From c0cb8a77c2f73a757ab74ce658c93d75f6b74f2d Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Sat, 1 May 2021 11:39:35 +0300 Subject: [PATCH] Add 'key_may_exist' functions family (#518) --- src/db.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_db.rs | 33 ++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/db.rs b/src/db.rs index ae7f595..a785de3 100644 --- a/src/db.rs +++ b/src/db.rs @@ -844,6 +844,62 @@ impl DBWithThreadMode { Ok(convert_values(values, values_sizes)) } + /// Returns `false` if the given key definitely doesn't exist in the database, otherwise returns + /// `false`. This function uses default `ReadOptions`. + pub fn key_may_exist>(&self, key: K) -> bool { + self.key_may_exist_opt(key, &ReadOptions::default()) + } + + /// Returns `false` if the given key definitely doesn't exist in the database, otherwise returns + /// `false`. + pub fn key_may_exist_opt>(&self, key: K, readopts: &ReadOptions) -> bool { + let key = key.as_ref(); + unsafe { + 0 != ffi::rocksdb_key_may_exist( + self.inner, + readopts.inner, + key.as_ptr() as *const c_char, + key.len() as size_t, + ptr::null_mut(), /*value*/ + ptr::null_mut(), /*val_len*/ + ptr::null(), /*timestamp*/ + 0, /*timestamp_len*/ + ptr::null_mut(), /*value_found*/ + ) + } + } + + /// Returns `false` if the given key definitely doesn't exist in the specified column family, + /// otherwise returns `false`. This function uses default `ReadOptions`. + pub fn key_may_exist_cf>(&self, cf: impl AsColumnFamilyRef, key: K) -> bool { + self.key_may_exist_cf_opt(cf, key, &ReadOptions::default()) + } + + /// Returns `false` if the given key definitely doesn't exist in the specified column family, + /// otherwise returns `false`. + pub fn key_may_exist_cf_opt>( + &self, + cf: impl AsColumnFamilyRef, + key: K, + readopts: &ReadOptions, + ) -> bool { + let key = key.as_ref(); + 0 != unsafe { + ffi::rocksdb_key_may_exist_cf( + self.inner, + readopts.inner, + cf.inner(), + key.as_ptr() as *const c_char, + key.len() as size_t, + ptr::null_mut(), /*value*/ + ptr::null_mut(), /*val_len*/ + ptr::null(), /*timestamp*/ + 0, /*timestamp_len*/ + ptr::null_mut(), /*value_found*/ + ) + } + } + fn create_inner_cf_handle( &self, name: &str, diff --git a/tests/test_db.rs b/tests/test_db.rs index 1447ed0..8aa682f 100644 --- a/tests/test_db.rs +++ b/tests/test_db.rs @@ -966,6 +966,39 @@ fn multi_get_cf() { } } +#[test] +fn key_may_exist() { + let path = DBPath::new("_rust_rocksdb_multi_get"); + + { + let db = DB::open_default(&path).unwrap(); + assert_eq!(false, db.key_may_exist("nonexistent")); + assert_eq!( + false, + db.key_may_exist_opt("nonexistent", &ReadOptions::default()) + ); + } +} + +#[test] +fn key_may_exist_cf() { + let path = DBPath::new("_rust_rocksdb_multi_get_cf"); + + { + let mut opts = Options::default(); + opts.create_if_missing(true); + opts.create_missing_column_families(true); + let db = DB::open_cf(&opts, &path, &["cf"]).unwrap(); + let cf = db.cf_handle("cf").unwrap(); + + assert_eq!(false, db.key_may_exist_cf(cf, "nonexistent")); + assert_eq!( + false, + db.key_may_exist_cf_opt(cf, "nonexistent", &ReadOptions::default()) + ); + } +} + #[test] fn test_snapshot_outlive_db() { let t = trybuild::TestCases::new();