use crate::{
db::DBAccess, ffi, AsColumnFamilyRef, DBIteratorWithThreadMode, DBPinnableSlice,
DBRawIteratorWithThreadMode, Error, IteratorMode, ReadOptions, DB,
};
pub type Snapshot<'a> = SnapshotWithThreadMode<'a, DB>;
pub struct SnapshotWithThreadMode<'a, D: DBAccess> {
db: &'a D,
pub(crate) inner: *const ffi::rocksdb_snapshot_t,
}
impl<'a, D: DBAccess> SnapshotWithThreadMode<'a, D> {
pub fn new(db: &'a D) -> Self {
let snapshot = unsafe { db.create_snapshot() };
Self {
db,
inner: snapshot,
}
}
pub fn iterator(&self, mode: IteratorMode) -> DBIteratorWithThreadMode<'a, D> {
let readopts = ReadOptions::default();
self.iterator_opt(mode, readopts)
}
pub fn iterator_cf(
&self,
cf_handle: &impl AsColumnFamilyRef,
mode: IteratorMode,
) -> DBIteratorWithThreadMode<D> {
let readopts = ReadOptions::default();
self.iterator_cf_opt(cf_handle, readopts, mode)
}
pub fn iterator_opt(
&self,
mode: IteratorMode,
mut readopts: ReadOptions,
) -> DBIteratorWithThreadMode<'a, D> {
readopts.set_snapshot(self);
DBIteratorWithThreadMode::<D>::new(self.db, readopts, mode)
}
pub fn iterator_cf_opt(
&self,
cf_handle: &impl AsColumnFamilyRef,
mut readopts: ReadOptions,
mode: IteratorMode,
) -> DBIteratorWithThreadMode<D> {
readopts.set_snapshot(self);
DBIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts, mode)
}
pub fn raw_iterator(&self) -> DBRawIteratorWithThreadMode<D> {
let readopts = ReadOptions::default();
self.raw_iterator_opt(readopts)
}
pub fn raw_iterator_cf(
&self,
cf_handle: &impl AsColumnFamilyRef,
) -> DBRawIteratorWithThreadMode<D> {
let readopts = ReadOptions::default();
self.raw_iterator_cf_opt(cf_handle, readopts)
}
pub fn raw_iterator_opt(&self, mut readopts: ReadOptions) -> DBRawIteratorWithThreadMode<D> {
readopts.set_snapshot(self);
DBRawIteratorWithThreadMode::new(self.db, readopts)
}
pub fn raw_iterator_cf_opt(
&self,
cf_handle: &impl AsColumnFamilyRef,
mut readopts: ReadOptions,
) -> DBRawIteratorWithThreadMode<D> {
readopts.set_snapshot(self);
DBRawIteratorWithThreadMode::new_cf(self.db, cf_handle.inner(), readopts)
}
pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<Vec<u8>>, Error> {
let readopts = ReadOptions::default();
self.get_opt(key, readopts)
}
pub fn get_cf<K: AsRef<[u8]>>(
&self,
cf: &impl AsColumnFamilyRef,
key: K,
) -> Result<Option<Vec<u8>>, Error> {
let readopts = ReadOptions::default();
self.get_cf_opt(cf, key.as_ref(), readopts)
}
pub fn get_opt<K: AsRef<[u8]>>(
&self,
key: K,
mut readopts: ReadOptions,
) -> Result<Option<Vec<u8>>, Error> {
readopts.set_snapshot(self);
self.db.get_opt(key.as_ref(), &readopts)
}
pub fn get_cf_opt<K: AsRef<[u8]>>(
&self,
cf: &impl AsColumnFamilyRef,
key: K,
mut readopts: ReadOptions,
) -> Result<Option<Vec<u8>>, Error> {
readopts.set_snapshot(self);
self.db.get_cf_opt(cf, key.as_ref(), &readopts)
}
pub fn get_pinned<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<DBPinnableSlice>, Error> {
let readopts = ReadOptions::default();
self.get_pinned_opt(key, readopts)
}
pub fn get_pinned_cf<K: AsRef<[u8]>>(
&self,
cf: &impl AsColumnFamilyRef,
key: K,
) -> Result<Option<DBPinnableSlice>, Error> {
let readopts = ReadOptions::default();
self.get_pinned_cf_opt(cf, key.as_ref(), readopts)
}
pub fn get_pinned_opt<K: AsRef<[u8]>>(
&self,
key: K,
mut readopts: ReadOptions,
) -> Result<Option<DBPinnableSlice>, Error> {
readopts.set_snapshot(self);
self.db.get_pinned_opt(key.as_ref(), &readopts)
}
pub fn get_pinned_cf_opt<K: AsRef<[u8]>>(
&self,
cf: &impl AsColumnFamilyRef,
key: K,
mut readopts: ReadOptions,
) -> Result<Option<DBPinnableSlice>, Error> {
readopts.set_snapshot(self);
self.db.get_pinned_cf_opt(cf, key.as_ref(), &readopts)
}
pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
where
I: IntoIterator<Item = K>,
{
let readopts = ReadOptions::default();
self.multi_get_opt(keys, readopts)
}
pub fn multi_get_cf<'b, K, I, W>(&self, keys_cf: I) -> Vec<Result<Option<Vec<u8>>, Error>>
where
K: AsRef<[u8]>,
I: IntoIterator<Item = (&'b W, K)>,
W: AsColumnFamilyRef + 'b,
{
let readopts = ReadOptions::default();
self.multi_get_cf_opt(keys_cf, readopts)
}
pub fn multi_get_opt<K, I>(
&self,
keys: I,
mut readopts: ReadOptions,
) -> Vec<Result<Option<Vec<u8>>, Error>>
where
K: AsRef<[u8]>,
I: IntoIterator<Item = K>,
{
readopts.set_snapshot(self);
self.db.multi_get_opt(keys, &readopts)
}
pub fn multi_get_cf_opt<'b, K, I, W>(
&self,
keys_cf: I,
mut readopts: ReadOptions,
) -> Vec<Result<Option<Vec<u8>>, Error>>
where
K: AsRef<[u8]>,
I: IntoIterator<Item = (&'b W, K)>,
W: AsColumnFamilyRef + 'b,
{
readopts.set_snapshot(self);
self.db.multi_get_cf_opt(keys_cf, &readopts)
}
}
impl<'a, D: DBAccess> Drop for SnapshotWithThreadMode<'a, D> {
fn drop(&mut self) {
unsafe {
self.db.release_snapshot(self.inner);
}
}
}
unsafe impl<'a, D: DBAccess> Send for SnapshotWithThreadMode<'a, D> {}
unsafe impl<'a, D: DBAccess> Sync for SnapshotWithThreadMode<'a, D> {}