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> {
40 db: &'a D,
41 pub(crate) inner: *const ffi::rocksdb_snapshot_t,
42}
43
44impl<'a, D: DBAccess> SnapshotWithThreadMode<'a, D> {
45 pub fn new(db: &'a D) -> Self {
47 let snapshot = unsafe { db.create_snapshot() };
48 Self {
49 db,
50 inner: snapshot,
51 }
52 }
53
54 pub fn iterator(&self, mode: IteratorMode) -> DBIteratorWithThreadMode<'a, D> {
56 let readopts = ReadOptions::default();
57 self.iterator_opt(mode, readopts)
58 }
59
60 pub fn iterator_cf(
63 &self,
64 cf_handle: &impl AsColumnFamilyRef,
65 mode: IteratorMode,
66 ) -> DBIteratorWithThreadMode<D> {
67 let readopts = ReadOptions::default();
68 self.iterator_cf_opt(cf_handle, readopts, mode)
69 }
70
71 pub fn iterator_opt(
73 &self,
74 mode: IteratorMode,
75 mut readopts: ReadOptions,
76 ) -> DBIteratorWithThreadMode<'a, D> {
77 readopts.set_snapshot(self);
78 DBIteratorWithThreadMode::<D>::new(self.db, readopts, mode)
79 }
80
81 pub fn iterator_cf_opt(
84 &self,
85 cf_handle: &impl AsColumnFamilyRef,
86 mut readopts: ReadOptions,
87 mode: IteratorMode,
88 ) -> DBIteratorWithThreadMode<D> {
89 readopts.set_snapshot(self);
90 DBIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts, mode)
91 }
92
93 pub fn raw_iterator(&self) -> DBRawIteratorWithThreadMode<D> {
95 let readopts = ReadOptions::default();
96 self.raw_iterator_opt(readopts)
97 }
98
99 pub fn raw_iterator_cf(
102 &self,
103 cf_handle: &impl AsColumnFamilyRef,
104 ) -> DBRawIteratorWithThreadMode<D> {
105 let readopts = ReadOptions::default();
106 self.raw_iterator_cf_opt(cf_handle, readopts)
107 }
108
109 pub fn raw_iterator_opt(&self, mut readopts: ReadOptions) -> DBRawIteratorWithThreadMode<D> {
111 readopts.set_snapshot(self);
112 DBRawIteratorWithThreadMode::new(self.db, readopts)
113 }
114
115 pub fn raw_iterator_cf_opt(
118 &self,
119 cf_handle: &impl AsColumnFamilyRef,
120 mut readopts: ReadOptions,
121 ) -> DBRawIteratorWithThreadMode<D> {
122 readopts.set_snapshot(self);
123 DBRawIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts)
124 }
125
126 pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
128 let readopts = ReadOptions::default();
129 self.get_opt(key, readopts)
130 }
131
132 pub fn get_cf<K: AsRef<[u8]>>(
135 &self,
136 cf: &impl AsColumnFamilyRef,
137 key: K,
138 ) -> Result<Option<Vec<u8>>, Error> {
139 let readopts = ReadOptions::default();
140 self.get_cf_opt(cf, key.as_ref(), readopts)
141 }
142
143 pub fn get_opt<K: AsRef<[u8]>>(
145 &self,
146 key: K,
147 mut readopts: ReadOptions,
148 ) -> Result<Option<Vec<u8>>, Error> {
149 readopts.set_snapshot(self);
150 self.db.get_opt(key.as_ref(), &readopts)
151 }
152
153 pub fn get_cf_opt<K: AsRef<[u8]>>(
155 &self,
156 cf: &impl AsColumnFamilyRef,
157 key: K,
158 mut readopts: ReadOptions,
159 ) -> Result<Option<Vec<u8>>, Error> {
160 readopts.set_snapshot(self);
161 self.db.get_cf_opt(cf, key.as_ref(), &readopts)
162 }
163
164 pub fn get_pinned<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<DBPinnableSlice>, Error> {
168 let readopts = ReadOptions::default();
169 self.get_pinned_opt(key, readopts)
170 }
171
172 pub fn get_pinned_cf<K: AsRef<[u8]>>(
176 &self,
177 cf: &impl AsColumnFamilyRef,
178 key: K,
179 ) -> Result<Option<DBPinnableSlice>, Error> {
180 let readopts = ReadOptions::default();
181 self.get_pinned_cf_opt(cf, key.as_ref(), readopts)
182 }
183
184 pub fn get_pinned_opt<K: AsRef<[u8]>>(
187 &self,
188 key: K,
189 mut readopts: ReadOptions,
190 ) -> Result<Option<DBPinnableSlice>, Error> {
191 readopts.set_snapshot(self);
192 self.db.get_pinned_opt(key.as_ref(), &readopts)
193 }
194
195 pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
199 &self,
200 cf: &impl AsColumnFamilyRef,
201 key: K,
202 mut readopts: ReadOptions,
203 ) -> Result<Option<DBPinnableSlice>, Error> {
204 readopts.set_snapshot(self);
205 self.db.get_pinned_cf_opt(cf, key.as_ref(), &readopts)
206 }
207
208 pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
210 where
211 I: IntoIterator<Item = K>,
212 {
213 let readopts = ReadOptions::default();
214 self.multi_get_opt(keys, readopts)
215 }
216
217 pub fn multi_get_cf<'b, K, I, W>(&self, keys_cf: I) -> Vec<Result<Option<Vec<u8>>, Error>>
219 where
220 K: AsRef<[u8]>,
221 I: IntoIterator<Item = (&'b W, K)>,
222 W: AsColumnFamilyRef + 'b,
223 {
224 let readopts = ReadOptions::default();
225 self.multi_get_cf_opt(keys_cf, readopts)
226 }
227
228 pub fn multi_get_opt<K, I>(
230 &self,
231 keys: I,
232 mut readopts: ReadOptions,
233 ) -> Vec<Result<Option<Vec<u8>>, Error>>
234 where
235 K: AsRef<[u8]>,
236 I: IntoIterator<Item = K>,
237 {
238 readopts.set_snapshot(self);
239 self.db.multi_get_opt(keys, &readopts)
240 }
241
242 pub fn multi_get_cf_opt<'b, K, I, W>(
244 &self,
245 keys_cf: I,
246 mut readopts: ReadOptions,
247 ) -> Vec<Result<Option<Vec<u8>>, Error>>
248 where
249 K: AsRef<[u8]>,
250 I: IntoIterator<Item = (&'b W, K)>,
251 W: AsColumnFamilyRef + 'b,
252 {
253 readopts.set_snapshot(self);
254 self.db.multi_get_cf_opt(keys_cf, &readopts)
255 }
256}
257
258impl<'a, D: DBAccess> Drop for SnapshotWithThreadMode<'a, D> {
259 fn drop(&mut self) {
260 unsafe {
261 self.db.release_snapshot(self.inner);
262 }
263 }
264}
265
266unsafe impl<'a, D: DBAccess> Send for SnapshotWithThreadMode<'a, D> {}
269unsafe impl<'a, D: DBAccess> Sync for SnapshotWithThreadMode<'a, D> {}