diff options
author | Stanislav Tkach <stanislav.tkach@gmail.com> | 2020-12-20 17:55:35 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-20 16:55:35 +0200 |
commit | ed690840413dafbb92b4d9403f994911b8a9a4b5 (patch) | |
tree | 72bc84a543f35ac7315bdbf5a6629e24305f1b65 /src | |
parent | 154c23bc9920e4b2ddafadc2c06e80a77af4cd64 (diff) |
Add multi_get functions family (#487)
Diffstat (limited to 'src')
-rw-r--r-- | src/db.rs | 110 |
1 files changed, 110 insertions, 0 deletions
@@ -564,6 +564,102 @@ impl DB { self.get_pinned_cf_opt(cf, key, &ReadOptions::default()) } + /// Return the values associated with the given keys. + pub fn multi_get<K, I>(&self, keys: I) -> Result<Vec<Vec<u8>>, Error> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = K>, + { + self.multi_get_opt(keys, &ReadOptions::default()) + } + + /// Return the values associated with the given keys using read options. + pub fn multi_get_opt<K, I>( + &self, + keys: I, + readopts: &ReadOptions, + ) -> Result<Vec<Vec<u8>>, Error> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = K>, + { + let (keys, keys_sizes): (Vec<Box<[u8]>>, Vec<_>) = keys + .into_iter() + .map(|k| (Box::from(k.as_ref()), k.as_ref().len())) + .unzip(); + let ptr_keys: Vec<_> = keys.iter().map(|k| k.as_ptr() as *const c_char).collect(); + + let mut values = vec![ptr::null_mut(); keys.len()]; + let mut values_sizes = vec![0_usize; keys.len()]; + unsafe { + ffi_try!(ffi::rocksdb_multi_get( + self.inner, + readopts.inner, + ptr_keys.len(), + ptr_keys.as_ptr(), + keys_sizes.as_ptr(), + values.as_mut_ptr(), + values_sizes.as_mut_ptr(), + )); + } + + Ok(convert_values(values, values_sizes)) + } + + /// Return the values associated with the given keys and column families. + pub fn multi_get_cf<'c, K, I>(&self, keys: I) -> Result<Vec<Vec<u8>>, Error> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = (&'c ColumnFamily, K)>, + { + self.multi_get_cf_opt(keys, &ReadOptions::default()) + } + + /// Return the values associated with the given keys and column families using read options. + pub fn multi_get_cf_opt<'c, K, I>( + &self, + keys: I, + readopts: &ReadOptions, + ) -> Result<Vec<Vec<u8>>, Error> + where + K: AsRef<[u8]>, + I: IntoIterator<Item = (&'c ColumnFamily, K)>, + { + let mut boxed_keys: Vec<Box<[u8]>> = Vec::new(); + let mut keys_sizes = Vec::new(); + let mut column_families = Vec::new(); + for (cf, key) in keys { + boxed_keys.push(Box::from(key.as_ref())); + keys_sizes.push(key.as_ref().len()); + column_families.push(cf); + } + let ptr_keys: Vec<_> = boxed_keys + .iter() + .map(|k| k.as_ptr() as *const c_char) + .collect(); + let ptr_cfs: Vec<_> = column_families + .iter() + .map(|c| c.inner as *const _) + .collect(); + + let mut values = vec![ptr::null_mut(); boxed_keys.len()]; + let mut values_sizes = vec![0_usize; boxed_keys.len()]; + unsafe { + ffi_try!(ffi::rocksdb_multi_get_cf( + self.inner, + readopts.inner, + ptr_cfs.as_ptr(), + ptr_keys.len(), + ptr_keys.as_ptr(), + keys_sizes.as_ptr(), + values.as_mut_ptr(), + values_sizes.as_mut_ptr(), + )); + } + + Ok(convert_values(values, values_sizes)) + } + pub fn create_cf<N: AsRef<str>>(&mut self, name: N, opts: &Options) -> Result<(), Error> { let cf_name = if let Ok(c) = CString::new(name.as_ref().as_bytes()) { c @@ -1428,3 +1524,17 @@ fn convert_options(opts: &[(&str, &str)]) -> Result<Vec<(CString, CString)>, Err }) .collect() } + +fn convert_values(values: Vec<*mut c_char>, values_sizes: Vec<usize>) -> Vec<Vec<u8>> { + values + .into_iter() + .zip(values_sizes.into_iter()) + .map(|(v, s)| { + let value = unsafe { slice::from_raw_parts(v as *const u8, s) }.into(); + unsafe { + ffi::rocksdb_free(v as *mut c_void); + } + value + }) + .collect() +} |