Add Snapshot PinnableSlice based API (#606)

master
Andrey Zheleznov 3 years ago committed by GitHub
parent 180e65e1b0
commit 16e4eaf1c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      src/db.rs
  2. 48
      src/snapshot.rs
  3. 23
      tests/test_pinnable_slice.rs

@ -146,6 +146,19 @@ pub trait DBAccess {
readopts: &ReadOptions, readopts: &ReadOptions,
) -> Result<Option<Vec<u8>>, Error>; ) -> Result<Option<Vec<u8>>, Error>;
fn get_pinned_opt<K: AsRef<[u8]>>(
&self,
key: K,
readopts: &ReadOptions,
) -> Result<Option<DBPinnableSlice>, Error>;
fn get_pinned_cf_opt<K: AsRef<[u8]>>(
&self,
cf: &impl AsColumnFamilyRef,
key: K,
readopts: &ReadOptions,
) -> Result<Option<DBPinnableSlice>, Error>;
fn multi_get_opt<K, I>( fn multi_get_opt<K, I>(
&self, &self,
keys: I, keys: I,
@ -188,6 +201,23 @@ impl<T: ThreadMode> DBAccess for DBWithThreadMode<T> {
self.get_cf_opt(cf, key, readopts) self.get_cf_opt(cf, key, readopts)
} }
fn get_pinned_opt<K: AsRef<[u8]>>(
&self,
key: K,
readopts: &ReadOptions,
) -> Result<Option<DBPinnableSlice>, Error> {
self.get_pinned_opt(key, readopts)
}
fn get_pinned_cf_opt<K: AsRef<[u8]>>(
&self,
cf: &impl AsColumnFamilyRef,
key: K,
readopts: &ReadOptions,
) -> Result<Option<DBPinnableSlice>, Error> {
self.get_pinned_cf_opt(cf, key, readopts)
}
fn multi_get_opt<K, I>( fn multi_get_opt<K, I>(
&self, &self,
keys: I, keys: I,

@ -13,8 +13,8 @@
// limitations under the License. // limitations under the License.
use crate::{ use crate::{
db::DBAccess, ffi, AsColumnFamilyRef, DBIteratorWithThreadMode, DBRawIteratorWithThreadMode, db::DBAccess, ffi, AsColumnFamilyRef, DBIteratorWithThreadMode, DBPinnableSlice,
Error, IteratorMode, ReadOptions, DB, DBRawIteratorWithThreadMode, Error, IteratorMode, ReadOptions, DB,
}; };
/// A type alias to keep compatibility. See [`SnapshotWithThreadMode`] for details /// A type alias to keep compatibility. See [`SnapshotWithThreadMode`] for details
@ -161,6 +161,50 @@ impl<'a, D: DBAccess> SnapshotWithThreadMode<'a, D> {
self.db.get_cf_opt(cf, key.as_ref(), &readopts) self.db.get_cf_opt(cf, key.as_ref(), &readopts)
} }
/// Return the value associated with a key using RocksDB's PinnableSlice
/// so as to avoid unnecessary memory copy. Similar to get_pinned_opt but
/// leverages default options.
pub fn get_pinned<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<DBPinnableSlice>, Error> {
let readopts = ReadOptions::default();
self.get_pinned_opt(key, readopts)
}
/// Return the value associated with a key using RocksDB's PinnableSlice
/// so as to avoid unnecessary memory copy. Similar to get_pinned_cf_opt but
/// leverages default options.
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)
}
/// Return the value associated with a key using RocksDB's PinnableSlice
/// so as to avoid unnecessary memory copy.
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)
}
/// Return the value associated with a key using RocksDB's PinnableSlice
/// so as to avoid unnecessary memory copy. Similar to get_pinned_opt but
/// allows specifying ColumnFamily.
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)
}
/// Returns the bytes associated with the given key values and default read options. /// Returns the bytes associated with the given key values and default read options.
pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>> pub fn multi_get<K: AsRef<[u8]>, I>(&self, keys: I) -> Vec<Result<Option<Vec<u8>>, Error>>
where where

@ -39,3 +39,26 @@ fn test_pinnable_slice() {
assert_eq!(b"12345", &pinnable_slice[5..10]); assert_eq!(b"12345", &pinnable_slice[5..10]);
} }
#[test]
fn test_snapshot_pinnable_slice() {
let path = DBPath::new("_rust_rocksdb_snapshot_pinnable_slice_test");
let mut opts = Options::default();
opts.create_if_missing(true);
let db = DB::open(&opts, &path).unwrap();
db.put(b"k1", b"value12345").unwrap();
let snap = db.snapshot();
assert!(db.put(b"k1", b"value23456").is_ok());
let result = snap.get_pinned(b"k1");
assert!(result.is_ok());
let value = result.unwrap();
assert!(value.is_some());
let pinnable_slice = value.unwrap();
assert_eq!(b"12345", &pinnable_slice[5..10]);
}

Loading…
Cancel
Save