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