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 iterator(&self, mode: IteratorMode) -> DBIteratorWithThreadMode<'a, D> {
60 let readopts = ReadOptions::default();
61 self.iterator_opt(mode, readopts)
62 }
63
64 pub fn iterator_cf(
67 &'_ self,
68 cf_handle: &impl AsColumnFamilyRef,
69 mode: IteratorMode,
70 ) -> DBIteratorWithThreadMode<'_, D> {
71 let readopts = ReadOptions::default();
72 self.iterator_cf_opt(cf_handle, readopts, mode)
73 }
74
75 pub fn iterator_opt(
77 &self,
78 mode: IteratorMode,
79 mut readopts: ReadOptions,
80 ) -> DBIteratorWithThreadMode<'a, D> {
81 readopts.set_snapshot(self);
82 DBIteratorWithThreadMode::<D>::new(self.db, readopts, mode)
83 }
84
85 pub fn iterator_cf_opt(
88 &'_ self,
89 cf_handle: &impl AsColumnFamilyRef,
90 mut readopts: ReadOptions,
91 mode: IteratorMode,
92 ) -> DBIteratorWithThreadMode<'_, D> {
93 readopts.set_snapshot(self);
94 DBIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts, mode)
95 }
96
97 pub fn raw_iterator(&'_ self) -> DBRawIteratorWithThreadMode<'_, D> {
99 let readopts = ReadOptions::default();
100 self.raw_iterator_opt(readopts)
101 }
102
103 pub fn raw_iterator_cf(
106 &'_ self,
107 cf_handle: &impl AsColumnFamilyRef,
108 ) -> DBRawIteratorWithThreadMode<'_, D> {
109 let readopts = ReadOptions::default();
110 self.raw_iterator_cf_opt(cf_handle, readopts)
111 }
112
113 pub fn raw_iterator_opt(
115 &'_ self,
116 mut readopts: ReadOptions,
117 ) -> DBRawIteratorWithThreadMode<'_, D> {
118 readopts.set_snapshot(self);
119 DBRawIteratorWithThreadMode::new(self.db, readopts)
120 }
121
122 pub fn raw_iterator_cf_opt(
125 &'_ self,
126 cf_handle: &impl AsColumnFamilyRef,
127 mut readopts: ReadOptions,
128 ) -> DBRawIteratorWithThreadMode<'_, D> {
129 readopts.set_snapshot(self);
130 DBRawIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts)
131 }
132
133 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
135 let readopts = ReadOptions::default();
136 self.get_opt(key, readopts)
137 }
138
139 pub fn get_cf<K: AsRef<[u8]>>(
142 &self,
143 cf: &impl AsColumnFamilyRef,
144 key: K,
145 ) -> Result<Option<Vec<u8>>, Error> {
146 let readopts = ReadOptions::default();
147 self.get_cf_opt(cf, key.as_ref(), readopts)
148 }
149
150 pub fn get_opt<K: AsRef<[u8]>>(
152 &self,
153 key: K,
154 mut readopts: ReadOptions,
155 ) -> Result<Option<Vec<u8>>, Error> {
156 readopts.set_snapshot(self);
157 self.db.get_opt(key.as_ref(), &readopts)
158 }
159
160 pub fn get_cf_opt<K: AsRef<[u8]>>(
162 &self,
163 cf: &impl AsColumnFamilyRef,
164 key: K,
165 mut readopts: ReadOptions,
166 ) -> Result<Option<Vec<u8>>, Error> {
167 readopts.set_snapshot(self);
168 self.db.get_cf_opt(cf, key.as_ref(), &readopts)
169 }
170
171 pub fn get_pinned<K: AsRef<[u8]>>(
175 &'_ self,
176 key: K,
177 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
178 let readopts = ReadOptions::default();
179 self.get_pinned_opt(key, readopts)
180 }
181
182 pub fn get_pinned_cf<K: AsRef<[u8]>>(
186 &'_ self,
187 cf: &impl AsColumnFamilyRef,
188 key: K,
189 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
190 let readopts = ReadOptions::default();
191 self.get_pinned_cf_opt(cf, key.as_ref(), readopts)
192 }
193
194 pub fn get_pinned_opt<K: AsRef<[u8]>>(
197 &'_ self,
198 key: K,
199 mut readopts: ReadOptions,
200 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
201 readopts.set_snapshot(self);
202 self.db.get_pinned_opt(key.as_ref(), &readopts)
203 }
204
205 pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
209 &'_ self,
210 cf: &impl AsColumnFamilyRef,
211 key: K,
212 mut readopts: ReadOptions,
213 ) -> Result<Option<DBPinnableSlice<'_>>, Error> {
214 readopts.set_snapshot(self);
215 self.db.get_pinned_cf_opt(cf, key.as_ref(), &readopts)
216 }
217
218 pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
220 where
221 I: IntoIterator<Item = K>,
222 {
223 let readopts = ReadOptions::default();
224 self.multi_get_opt(keys, readopts)
225 }
226
227 pub fn multi_get_cf<'b, K, I, W>(&self, keys_cf: I) -> Vec<Result<Option<Vec<u8>>, Error>>
229 where
230 K: AsRef<[u8]>,
231 I: IntoIterator<Item = (&'b W, K)>,
232 W: AsColumnFamilyRef + 'b,
233 {
234 let readopts = ReadOptions::default();
235 self.multi_get_cf_opt(keys_cf, readopts)
236 }
237
238 pub fn multi_get_opt<K, I>(
240 &self,
241 keys: I,
242 mut readopts: ReadOptions,
243 ) -> Vec<Result<Option<Vec<u8>>, Error>>
244 where
245 K: AsRef<[u8]>,
246 I: IntoIterator<Item = K>,
247 {
248 readopts.set_snapshot(self);
249 self.db.multi_get_opt(keys, &readopts)
250 }
251
252 pub fn multi_get_cf_opt<'b, K, I, W>(
254 &self,
255 keys_cf: I,
256 mut readopts: ReadOptions,
257 ) -> Vec<Result<Option<Vec<u8>>, Error>>
258 where
259 K: AsRef<[u8]>,
260 I: IntoIterator<Item = (&'b W, K)>,
261 W: AsColumnFamilyRef + 'b,
262 {
263 readopts.set_snapshot(self);
264 self.db.multi_get_cf_opt(keys_cf, &readopts)
265 }
266}
267
268impl<D: DBAccess> Drop for SnapshotWithThreadMode<'_, D> {
269 fn drop(&mut self) {
270 unsafe {
271 self.db.release_snapshot(self.inner);
272 }
273 }
274}
275
276unsafe impl<D: DBAccess> Send for SnapshotWithThreadMode<'_, D> {}
279unsafe impl<D: DBAccess> Sync for SnapshotWithThreadMode<'_, D> {}