diff options
author | Oleg Nosov <olegnosov1@gmail.com> | 2022-01-14 13:55:55 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-14 12:55:55 +0200 |
commit | 8bf9faddb3b51bd1f1267efbc2037b323b4ba0a4 (patch) | |
tree | af0ee4f27b52d42e7ab529dfab5674698c2bc21d | |
parent | 522b4967389881749405b5872f46d0b8d0625b81 (diff) |
Support `multi_get_*` methods (#572)
-rw-r--r-- | src/db.rs | 44 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/snapshot.rs | 49 | ||||
-rw-r--r-- | tests/test_db.rs | 49 |
4 files changed, 138 insertions, 6 deletions
@@ -145,6 +145,25 @@ pub trait DBAccess { key: K, readopts: &ReadOptions, ) -> Result<Option<Vec<u8>>, Error>; + + fn multi_get_opt<K, I>( + &self, + keys: I, + readopts: &ReadOptions, + ) -> Vec<Result<Option<Vec<u8>>, Error>> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = K>; + + fn multi_get_cf_opt<'b, K, I, W>( + &self, + keys_cf: I, + readopts: &ReadOptions, + ) -> Vec<Result<Option<Vec<u8>>, Error>> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = (&'b W, K)>, + W: AsColumnFamilyRef + 'b; } impl<T: ThreadMode> DBAccess for DBWithThreadMode<T> { @@ -168,6 +187,31 @@ impl<T: ThreadMode> DBAccess for DBWithThreadMode<T> { ) -> Result<Option<Vec<u8>>, Error> { self.get_cf_opt(cf, key, readopts) } + + fn multi_get_opt<K, I>( + &self, + keys: I, + readopts: &ReadOptions, + ) -> Vec<Result<Option<Vec<u8>>, Error>> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = K>, + { + self.multi_get_opt(keys, readopts) + } + + fn multi_get_cf_opt<'b, K, I, W>( + &self, + keys_cf: I, + readopts: &ReadOptions, + ) -> Vec<Result<Option<Vec<u8>>, Error>> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = (&'b W, K)>, + W: AsColumnFamilyRef + 'b, + { + self.multi_get_cf_opt(keys_cf, readopts) + } } /// A type alias to DB instance type with the single-threaded column family @@ -98,7 +98,7 @@ pub use crate::{ ColumnFamilyRef, DEFAULT_COLUMN_FAMILY_NAME, }, compaction_filter::Decision as CompactionDecision, - db::{DBWithThreadMode, LiveFile, MultiThreaded, SingleThreaded, ThreadMode, DB}, + db::{DBAccess, DBWithThreadMode, LiveFile, MultiThreaded, SingleThreaded, ThreadMode, DB}, db_iterator::{ DBIterator, DBIteratorWithThreadMode, DBRawIterator, DBRawIteratorWithThreadMode, DBWALIterator, Direction, IteratorMode, diff --git a/src/snapshot.rs b/src/snapshot.rs index a4356ca..0a0ea06 100644 --- a/src/snapshot.rs +++ b/src/snapshot.rs @@ -160,6 +160,55 @@ impl<'a, D: DBAccess> SnapshotWithThreadMode<'a, D> { readopts.set_snapshot(self); self.db.get_cf_opt(cf, key.as_ref(), &readopts) } + + /// 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>> + where + I: IntoIterator<Item = K>, + { + let readopts = ReadOptions::default(); + self.multi_get_opt(keys, readopts) + } + + /// Returns the bytes associated with the given key values and default read options. + 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) + } + + /// Returns the bytes associated with the given key values and given read options. + 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) + } + + /// Returns the bytes associated with the given key values, given column family and read options. + 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> { diff --git a/tests/test_db.rs b/tests/test_db.rs index 394d05e..a362d46 100644 --- a/tests/test_db.rs +++ b/tests/test_db.rs @@ -20,7 +20,7 @@ use pretty_assertions::assert_eq; use rocksdb::{ perf::get_memory_usage_stats, BlockBasedOptions, BottommostLevelCompaction, Cache, - CompactOptions, CuckooTableOptions, DBCompactionStyle, DBWithThreadMode, Env, Error, + CompactOptions, CuckooTableOptions, DBAccess, DBCompactionStyle, DBWithThreadMode, Env, Error, FifoCompactOptions, IteratorMode, MultiThreaded, Options, PerfContext, PerfMetric, ReadOptions, SingleThreaded, SliceTransform, Snapshot, UniversalCompactOptions, UniversalCompactionStopStyle, WriteBatch, DB, @@ -926,20 +926,59 @@ fn multi_get() { { let db = DB::open_default(&path).unwrap(); + let initial_snap = db.snapshot(); db.put(b"k1", b"v1").unwrap(); + let k1_snap = db.snapshot(); db.put(b"k2", b"v2").unwrap(); let _ = db.multi_get(&[b"k0"; 40]); + let assert_values = |values: Vec<_>| { + assert_eq!(3, values.len()); + assert_eq!(values[0], None); + assert_eq!(values[1], Some(b"v1".to_vec())); + assert_eq!(values[2], Some(b"v2".to_vec())); + }; + let values = db .multi_get(&[b"k0", b"k1", b"k2"]) .into_iter() .map(Result::unwrap) .collect::<Vec<_>>(); - assert_eq!(3, values.len()); - assert_eq!(values[0], None); - assert_eq!(values[1], Some(b"v1".to_vec())); - assert_eq!(values[2], Some(b"v2".to_vec())); + + assert_values(values); + + let values = DBAccess::multi_get_opt(&db, &[b"k0", b"k1", b"k2"], &Default::default()) + .into_iter() + .map(Result::unwrap) + .collect::<Vec<_>>(); + + assert_values(values); + + let values = db + .snapshot() + .multi_get(&[b"k0", b"k1", b"k2"]) + .into_iter() + .map(Result::unwrap) + .collect::<Vec<_>>(); + + assert_values(values); + + let none_values = initial_snap + .multi_get(&[b"k0", b"k1", b"k2"]) + .into_iter() + .map(Result::unwrap) + .collect::<Vec<_>>(); + + assert_eq!(none_values, vec![None; 3]); + + let k1_only = k1_snap + .multi_get(&[b"k0", b"k1", b"k2"]) + .into_iter() + .map(Result::unwrap) + .collect::<Vec<_>>(); + + assert_eq!(k1_only, vec![None, Some(b"v1".to_vec()), None]); } } |