1use crate::{
16 db::DBAccess, ffi, AsColumnFamilyRef, DBIteratorWithThreadMode, DBPinnableSlice,
17 DBRawIteratorWithThreadMode, Error, IteratorMode, ReadOptions, DB,
18};
19
20pub type Snapshot<'a> = SnapshotWithThreadMode<'a, DB>;
22
23pub struct SnapshotWithThreadMode<'a, D: DBAccess> {
44 db: &'a D,
45 pub(crate) inner: *const ffi::rocksdb_snapshot_t,
46}
47
48impl<'a, D: DBAccess> SnapshotWithThreadMode<'a, D> {
49 pub fn new(db: &'a D) -> Self {
51 let snapshot = unsafe { db.create_snapshot() };
52 Self {
53 db,
54 inner: snapshot,
55 }
56 }
57
58 pub fn sequence_number(&self) -> u64 {
60 unsafe { ffi::rocksdb_snapshot_get_sequence_number(self.inner) }
61 }
62
63 pub fn iterator(&self, mode: IteratorMode) -> DBIteratorWithThreadMode<'a, D> {
65 let readopts = ReadOptions::default();
66 self.iterator_opt(mode, readopts)
67 }
68
69 pub fn iterator_cf(
72 &self,
73 cf_handle: &impl AsColumnFamilyRef,
74 mode: IteratorMode,
75 ) -> DBIteratorWithThreadMode<D> {
76 let readopts = ReadOptions::default();
77 self.iterator_cf_opt(cf_handle, readopts, mode)
78 }
79
80 pub fn iterator_opt(
82 &self,
83 mode: IteratorMode,
84 mut readopts: ReadOptions,
85 ) -> DBIteratorWithThreadMode<'a, D> {
86 readopts.set_snapshot(self);
87 DBIteratorWithThreadMode::<D>::new(self.db, readopts, mode)
88 }
89
90 pub fn iterator_cf_opt(
93 &self,
94 cf_handle: &impl AsColumnFamilyRef,
95 mut readopts: ReadOptions,
96 mode: IteratorMode,
97 ) -> DBIteratorWithThreadMode<D> {
98 readopts.set_snapshot(self);
99 DBIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts, mode)
100 }
101
102 pub fn raw_iterator(&self) -> DBRawIteratorWithThreadMode<D> {
104 let readopts = ReadOptions::default();
105 self.raw_iterator_opt(readopts)
106 }
107
108 pub fn raw_iterator_cf(
111 &self,
112 cf_handle: &impl AsColumnFamilyRef,
113 ) -> DBRawIteratorWithThreadMode<D> {
114 let readopts = ReadOptions::default();
115 self.raw_iterator_cf_opt(cf_handle, readopts)
116 }
117
118 pub fn raw_iterator_opt(&self, mut readopts: ReadOptions) -> DBRawIteratorWithThreadMode<D> {
120 readopts.set_snapshot(self);
121 DBRawIteratorWithThreadMode::new(self.db, readopts)
122 }
123
124 pub fn raw_iterator_cf_opt(
127 &self,
128 cf_handle: &impl AsColumnFamilyRef,
129 mut readopts: ReadOptions,
130 ) -> DBRawIteratorWithThreadMode<D> {
131 readopts.set_snapshot(self);
132 DBRawIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts)
133 }
134
135 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
137 let readopts = ReadOptions::default();
138 self.get_opt(key, readopts)
139 }
140
141 pub fn get_cf<K: AsRef<[u8]>>(
144 &self,
145 cf: &impl AsColumnFamilyRef,
146 key: K,
147 ) -> Result<Option<Vec<u8>>, Error> {
148 let readopts = ReadOptions::default();
149 self.get_cf_opt(cf, key.as_ref(), readopts)
150 }
151
152 pub fn get_opt<K: AsRef<[u8]>>(
154 &self,
155 key: K,
156 mut readopts: ReadOptions,
157 ) -> Result<Option<Vec<u8>>, Error> {
158 readopts.set_snapshot(self);
159 self.db.get_opt(key.as_ref(), &readopts)
160 }
161
162 pub fn get_cf_opt<K: AsRef<[u8]>>(
164 &self,
165 cf: &impl AsColumnFamilyRef,
166 key: K,
167 mut readopts: ReadOptions,
168 ) -> Result<Option<Vec<u8>>, Error> {
169 readopts.set_snapshot(self);
170 self.db.get_cf_opt(cf, key.as_ref(), &readopts)
171 }
172
173 pub fn get_pinned<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<DBPinnableSlice>, Error> {
177 let readopts = ReadOptions::default();
178 self.get_pinned_opt(key, readopts)
179 }
180
181 pub fn get_pinned_cf<K: AsRef<[u8]>>(
185 &self,
186 cf: &impl AsColumnFamilyRef,
187 key: K,
188 ) -> Result<Option<DBPinnableSlice>, Error> {
189 let readopts = ReadOptions::default();
190 self.get_pinned_cf_opt(cf, key.as_ref(), readopts)
191 }
192
193 pub fn get_pinned_opt<K: AsRef<[u8]>>(
196 &self,
197 key: K,
198 mut readopts: ReadOptions,
199 ) -> Result<Option<DBPinnableSlice>, Error> {
200 readopts.set_snapshot(self);
201 self.db.get_pinned_opt(key.as_ref(), &readopts)
202 }
203
204 pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
208 &self,
209 cf: &impl AsColumnFamilyRef,
210 key: K,
211 mut readopts: ReadOptions,
212 ) -> Result<Option<DBPinnableSlice>, Error> {
213 readopts.set_snapshot(self);
214 self.db.get_pinned_cf_opt(cf, key.as_ref(), &readopts)
215 }
216
217 pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
219 where
220 I: IntoIterator<Item = K>,
221 {
222 let readopts = ReadOptions::default();
223 self.multi_get_opt(keys, readopts)
224 }
225
226 pub fn multi_get_cf<'b, K, I, W>(&self, keys_cf: I) -> Vec<Result<Option<Vec<u8>>, Error>>
228 where
229 K: AsRef<[u8]>,
230 I: IntoIterator<Item = (&'b W, K)>,
231 W: AsColumnFamilyRef + 'b,
232 {
233 let readopts = ReadOptions::default();
234 self.multi_get_cf_opt(keys_cf, readopts)
235 }
236
237 pub fn multi_get_opt<K, I>(
239 &self,
240 keys: I,
241 mut readopts: ReadOptions,
242 ) -> Vec<Result<Option<Vec<u8>>, Error>>
243 where
244 K: AsRef<[u8]>,
245 I: IntoIterator<Item = K>,
246 {
247 readopts.set_snapshot(self);
248 self.db.multi_get_opt(keys, &readopts)
249 }
250
251 pub fn multi_get_cf_opt<'b, K, I, W>(
253 &self,
254 keys_cf: I,
255 mut readopts: ReadOptions,
256 ) -> Vec<Result<Option<Vec<u8>>, Error>>
257 where
258 K: AsRef<[u8]>,
259 I: IntoIterator<Item = (&'b W, K)>,
260 W: AsColumnFamilyRef + 'b,
261 {
262 readopts.set_snapshot(self);
263 self.db.multi_get_cf_opt(keys_cf, &readopts)
264 }
265}
266
267impl<D: DBAccess> Drop for SnapshotWithThreadMode<'_, D> {
268 fn drop(&mut self) {
269 unsafe {
270 self.db.release_snapshot(self.inner);
271 }
272 }
273}
274
275unsafe impl<D: DBAccess> Send for SnapshotWithThreadMode<'_, D> {}
278unsafe impl<D: DBAccess> Sync for SnapshotWithThreadMode<'_, D> {}