1use crate::{
16 AsColumnFamilyRef, DB, DBIteratorWithThreadMode, DBPinnableSlice, DBRawIteratorWithThreadMode,
17 Error, IteratorMode, ReadOptions, db::DBAccess, ffi,
18};
19
20pub type Snapshot<'a> = SnapshotWithThreadMode<'a, DB>;
22
23pub struct SnapshotWithThreadMode<'a, D: DBAccess> {
54 db: &'a D,
55 pub(crate) inner: *const ffi::rocksdb_snapshot_t,
56}
57
58impl<'a, D: DBAccess> SnapshotWithThreadMode<'a, D> {
59 pub fn new(db: &'a D) -> Self {
61 let snapshot = unsafe { db.create_snapshot() };
62 Self {
63 db,
64 inner: snapshot,
65 }
66 }
67
68 pub fn sequence_number(&self) -> u64 {
70 unsafe { ffi::rocksdb_snapshot_get_sequence_number(self.inner) }
71 }
72
73 pub fn iterator(&self, mode: IteratorMode) -> DBIteratorWithThreadMode<'a, D> {
75 let readopts = ReadOptions::default();
76 self.iterator_opt(mode, readopts)
77 }
78
79 pub fn iterator_cf(
82 &'_ self,
83 cf_handle: &impl AsColumnFamilyRef,
84 mode: IteratorMode,
85 ) -> DBIteratorWithThreadMode<'_, D> {
86 let readopts = ReadOptions::default();
87 self.iterator_cf_opt(cf_handle, readopts, mode)
88 }
89
90 pub fn iterator_opt(
92 &self,
93 mode: IteratorMode,
94 mut readopts: ReadOptions,
95 ) -> DBIteratorWithThreadMode<'a, D> {
96 readopts.set_snapshot(self);
97 DBIteratorWithThreadMode::<D>::new(self.db, readopts, mode)
98 }
99
100 pub fn iterator_cf_opt(
103 &'_ self,
104 cf_handle: &impl AsColumnFamilyRef,
105 mut readopts: ReadOptions,
106 mode: IteratorMode,
107 ) -> DBIteratorWithThreadMode<'_, D> {
108 readopts.set_snapshot(self);
109 DBIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts, mode)
110 }
111
112 pub fn raw_iterator(&'_ self) -> DBRawIteratorWithThreadMode<'_, D> {
114 let readopts = ReadOptions::default();
115 self.raw_iterator_opt(readopts)
116 }
117
118 pub fn raw_iterator_cf(
121 &'_ self,
122 cf_handle: &impl AsColumnFamilyRef,
123 ) -> DBRawIteratorWithThreadMode<'_, D> {
124 let readopts = ReadOptions::default();
125 self.raw_iterator_cf_opt(cf_handle, readopts)
126 }
127
128 pub fn raw_iterator_opt(
130 &'_ self,
131 mut readopts: ReadOptions,
132 ) -> DBRawIteratorWithThreadMode<'_, D> {
133 readopts.set_snapshot(self);
134 DBRawIteratorWithThreadMode::new(self.db, readopts)
135 }
136
137 pub fn raw_iterator_cf_opt(
140 &'_ self,
141 cf_handle: &impl AsColumnFamilyRef,
142 mut readopts: ReadOptions,
143 ) -> DBRawIteratorWithThreadMode<'_, D> {
144 readopts.set_snapshot(self);
145 DBRawIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts)
146 }
147
148 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
150 let readopts = ReadOptions::default();
151 self.get_opt(key, readopts)
152 }
153
154 pub fn get_cf<K: AsRef<[u8]>>(
157 &self,
158 cf: &impl AsColumnFamilyRef,
159 key: K,
160 ) -> Result<Option<Vec<u8>>, Error> {
161 let readopts = ReadOptions::default();
162 self.get_cf_opt(cf, key.as_ref(), readopts)
163 }
164
165 pub fn get_opt<K: AsRef<[u8]>>(
167 &self,
168 key: K,
169 mut readopts: ReadOptions,
170 ) -> Result<Option<Vec<u8>>, Error> {
171 readopts.set_snapshot(self);
172 self.db.get_opt(key.as_ref(), &readopts)
173 }
174
175 pub fn get_cf_opt<K: AsRef<[u8]>>(
177 &self,
178 cf: &impl AsColumnFamilyRef,
179 key: K,
180 mut readopts: ReadOptions,
181 ) -> Result<Option<Vec<u8>>, Error> {
182 readopts.set_snapshot(self);
183 self.db.get_cf_opt(cf, key.as_ref(), &readopts)
184 }
185
186 pub fn get_pinned<K: AsRef<[u8]>>(
190 &'_ self,
191 key: K,
192 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
193 let readopts = ReadOptions::default();
194 self.get_pinned_opt(key, readopts)
195 }
196
197 pub fn get_pinned_cf<K: AsRef<[u8]>>(
201 &'_ self,
202 cf: &impl AsColumnFamilyRef,
203 key: K,
204 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
205 let readopts = ReadOptions::default();
206 self.get_pinned_cf_opt(cf, key.as_ref(), readopts)
207 }
208
209 pub fn get_pinned_opt<K: AsRef<[u8]>>(
212 &'_ self,
213 key: K,
214 mut readopts: ReadOptions,
215 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
216 readopts.set_snapshot(self);
217 self.db.get_pinned_opt(key.as_ref(), &readopts)
218 }
219
220 pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
224 &'_ self,
225 cf: &impl AsColumnFamilyRef,
226 key: K,
227 mut readopts: ReadOptions,
228 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
229 readopts.set_snapshot(self);
230 self.db.get_pinned_cf_opt(cf, key.as_ref(), &readopts)
231 }
232
233 pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
235 where
236 I: IntoIterator<Item = K>,
237 {
238 let readopts = ReadOptions::default();
239 self.multi_get_opt(keys, readopts)
240 }
241
242 pub fn multi_get_cf<'b, K, I, W>(&self, keys_cf: I) -> Vec<Result<Option<Vec<u8>>, Error>>
244 where
245 K: AsRef<[u8]>,
246 I: IntoIterator<Item = (&'b W, K)>,
247 W: AsColumnFamilyRef + 'b,
248 {
249 let readopts = ReadOptions::default();
250 self.multi_get_cf_opt(keys_cf, readopts)
251 }
252
253 pub fn multi_get_opt<K, I>(
255 &self,
256 keys: I,
257 mut readopts: ReadOptions,
258 ) -> Vec<Result<Option<Vec<u8>>, Error>>
259 where
260 K: AsRef<[u8]>,
261 I: IntoIterator<Item = K>,
262 {
263 readopts.set_snapshot(self);
264 self.db.multi_get_opt(keys, &readopts)
265 }
266
267 pub fn multi_get_cf_opt<'b, K, I, W>(
269 &self,
270 keys_cf: I,
271 mut readopts: ReadOptions,
272 ) -> Vec<Result<Option<Vec<u8>>, Error>>
273 where
274 K: AsRef<[u8]>,
275 I: IntoIterator<Item = (&'b W, K)>,
276 W: AsColumnFamilyRef + 'b,
277 {
278 readopts.set_snapshot(self);
279 self.db.multi_get_cf_opt(keys_cf, &readopts)
280 }
281}
282
283impl<D: DBAccess> Drop for SnapshotWithThreadMode<'_, D> {
284 fn drop(&mut self) {
285 unsafe {
286 self.db.release_snapshot(self.inner);
287 }
288 }
289}
290
291unsafe impl<D: DBAccess> Send for SnapshotWithThreadMode<'_, D> {}
294unsafe impl<D: DBAccess> Sync for SnapshotWithThreadMode<'_, D> {}