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> {
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(
120 &'_ self,
121 mut readopts: ReadOptions,
122 ) -> DBRawIteratorWithThreadMode<'_, D> {
123 readopts.set_snapshot(self);
124 DBRawIteratorWithThreadMode::new(self.db, readopts)
125 }
126
127 pub fn raw_iterator_cf_opt(
130 &'_ self,
131 cf_handle: &impl AsColumnFamilyRef,
132 mut readopts: ReadOptions,
133 ) -> DBRawIteratorWithThreadMode<'_, D> {
134 readopts.set_snapshot(self);
135 DBRawIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts)
136 }
137
138 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
140 let readopts = ReadOptions::default();
141 self.get_opt(key, readopts)
142 }
143
144 pub fn get_cf<K: AsRef<[u8]>>(
147 &self,
148 cf: &impl AsColumnFamilyRef,
149 key: K,
150 ) -> Result<Option<Vec<u8>>, Error> {
151 let readopts = ReadOptions::default();
152 self.get_cf_opt(cf, key.as_ref(), readopts)
153 }
154
155 pub fn get_opt<K: AsRef<[u8]>>(
157 &self,
158 key: K,
159 mut readopts: ReadOptions,
160 ) -> Result<Option<Vec<u8>>, Error> {
161 readopts.set_snapshot(self);
162 self.db.get_opt(key.as_ref(), &readopts)
163 }
164
165 pub fn get_cf_opt<K: AsRef<[u8]>>(
167 &self,
168 cf: &impl AsColumnFamilyRef,
169 key: K,
170 mut readopts: ReadOptions,
171 ) -> Result<Option<Vec<u8>>, Error> {
172 readopts.set_snapshot(self);
173 self.db.get_cf_opt(cf, key.as_ref(), &readopts)
174 }
175
176 pub fn get_pinned<K: AsRef<[u8]>>(
180 &'_ self,
181 key: K,
182 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
183 let readopts = ReadOptions::default();
184 self.get_pinned_opt(key, readopts)
185 }
186
187 pub fn get_pinned_cf<K: AsRef<[u8]>>(
191 &'_ self,
192 cf: &impl AsColumnFamilyRef,
193 key: K,
194 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
195 let readopts = ReadOptions::default();
196 self.get_pinned_cf_opt(cf, key.as_ref(), readopts)
197 }
198
199 pub fn get_pinned_opt<K: AsRef<[u8]>>(
202 &'_ self,
203 key: K,
204 mut readopts: ReadOptions,
205 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
206 readopts.set_snapshot(self);
207 self.db.get_pinned_opt(key.as_ref(), &readopts)
208 }
209
210 pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
214 &'_ self,
215 cf: &impl AsColumnFamilyRef,
216 key: K,
217 mut readopts: ReadOptions,
218 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
219 readopts.set_snapshot(self);
220 self.db.get_pinned_cf_opt(cf, key.as_ref(), &readopts)
221 }
222
223 pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
225 where
226 I: IntoIterator<Item = K>,
227 {
228 let readopts = ReadOptions::default();
229 self.multi_get_opt(keys, readopts)
230 }
231
232 pub fn multi_get_cf<'b, K, I, W>(&self, keys_cf: I) -> Vec<Result<Option<Vec<u8>>, Error>>
234 where
235 K: AsRef<[u8]>,
236 I: IntoIterator<Item = (&'b W, K)>,
237 W: AsColumnFamilyRef + 'b,
238 {
239 let readopts = ReadOptions::default();
240 self.multi_get_cf_opt(keys_cf, readopts)
241 }
242
243 pub fn multi_get_opt<K, I>(
245 &self,
246 keys: I,
247 mut readopts: ReadOptions,
248 ) -> Vec<Result<Option<Vec<u8>>, Error>>
249 where
250 K: AsRef<[u8]>,
251 I: IntoIterator<Item = K>,
252 {
253 readopts.set_snapshot(self);
254 self.db.multi_get_opt(keys, &readopts)
255 }
256
257 pub fn multi_get_cf_opt<'b, K, I, W>(
259 &self,
260 keys_cf: I,
261 mut readopts: ReadOptions,
262 ) -> Vec<Result<Option<Vec<u8>>, Error>>
263 where
264 K: AsRef<[u8]>,
265 I: IntoIterator<Item = (&'b W, K)>,
266 W: AsColumnFamilyRef + 'b,
267 {
268 readopts.set_snapshot(self);
269 self.db.multi_get_cf_opt(keys_cf, &readopts)
270 }
271}
272
273impl<D: DBAccess> Drop for SnapshotWithThreadMode<'_, D> {
274 fn drop(&mut self) {
275 unsafe {
276 self.db.release_snapshot(self.inner);
277 }
278 }
279}
280
281unsafe impl<D: DBAccess> Send for SnapshotWithThreadMode<'_, D> {}
284unsafe impl<D: DBAccess> Sync for SnapshotWithThreadMode<'_, D> {}