From 22b34a40cb9ca18c0f97b7a567621c53c669318d Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 27 Jan 2019 22:18:01 +0000 Subject: [PATCH 1/7] Add property_value functions --- src/db.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/db.rs b/src/db.rs index c51f9b0..6ec9f0c 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1152,6 +1152,27 @@ impl DB { )) }) } + + pub fn property_value(&self, name: &str) -> Option { + let prop_name = CString::new(name).unwrap(); + unsafe { + let value = ffi::rocksdb_property_value(self.inner, prop_name.as_ptr()); + if value.is_null() { + return None; + } + + let s = CStr::from_ptr(value).to_str().unwrap().to_owned(); + libc::free(value as *mut c_void); + Some(s) + } + } + + pub fn property_int_value(&self, name: &str) -> Option { + match self.property_value(name) { + Some(value) => value.parse::().ok(), + None => None, + } + } } impl WriteBatch { From 312ad80f98e63aa77450264c2bf4d5cb4fb0316b Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Mon, 23 Apr 2018 15:08:54 +0200 Subject: [PATCH 2/7] Add cf getters for properties --- src/db.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/db.rs b/src/db.rs index 6ec9f0c..b40140d 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1167,12 +1167,38 @@ impl DB { } } + pub fn property_value_cf(&self, column_family: ColumnFamily, name: &str) -> Option { + let prop_name = CString::new(name).unwrap(); + unsafe { + let value = ffi::rocksdb_property_value_cf( + self.inner, + column_family.inner, + prop_name.as_ptr() + ); + + if value.is_null() { + return None; + } + + let s = CStr::from_ptr(value).to_str().unwrap().to_owned(); + libc::free(value as *mut c_void); + Some(s) + } + } + pub fn property_int_value(&self, name: &str) -> Option { match self.property_value(name) { Some(value) => value.parse::().ok(), None => None, } } + + pub fn property_int_value_cf(&self, column_family: ColumnFamily, name: &str) -> Option { + match self.property_value_cf(column_family, name) { + Some(value) => value.parse::().ok(), + None => None, + } + } } impl WriteBatch { From 369d2ab8a6c047974a025d5d1baf88e8bb5d4af6 Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 27 Jan 2019 22:19:50 +0000 Subject: [PATCH 3/7] column_family -> cf for consistency --- src/db.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/db.rs b/src/db.rs index b40140d..adf0b15 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1167,12 +1167,12 @@ impl DB { } } - pub fn property_value_cf(&self, column_family: ColumnFamily, name: &str) -> Option { + pub fn property_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { let prop_name = CString::new(name).unwrap(); unsafe { let value = ffi::rocksdb_property_value_cf( self.inner, - column_family.inner, + cf.inner, prop_name.as_ptr() ); @@ -1193,8 +1193,8 @@ impl DB { } } - pub fn property_int_value_cf(&self, column_family: ColumnFamily, name: &str) -> Option { - match self.property_value_cf(column_family, name) { + pub fn property_int_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { + match self.property_value_cf(cf, name) { Some(value) => value.parse::().ok(), None => None, } From 33d30d4ca1bb908b9dfb8278de2e58f6fce0f921 Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 27 Jan 2019 22:44:37 +0000 Subject: [PATCH 4/7] Add tests --- src/db.rs | 7 +------ tests/test_property.rs | 47 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 tests/test_property.rs diff --git a/src/db.rs b/src/db.rs index adf0b15..b2a5912 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1170,12 +1170,7 @@ impl DB { pub fn property_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { let prop_name = CString::new(name).unwrap(); unsafe { - let value = ffi::rocksdb_property_value_cf( - self.inner, - cf.inner, - prop_name.as_ptr() - ); - + let value = ffi::rocksdb_property_value_cf(self.inner, cf.inner, prop_name.as_ptr()); if value.is_null() { return None; } diff --git a/tests/test_property.rs b/tests/test_property.rs new file mode 100644 index 0000000..222755b --- /dev/null +++ b/tests/test_property.rs @@ -0,0 +1,47 @@ +// Copyright 2019 Tyler Neely +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +extern crate rocksdb; +mod util; + +use rocksdb::{Options, DB}; +use util::DBPath; + +#[test] +fn property_test() { + let n = DBPath::new("_rust_rocksdb_property_test"); + { + let db = DB::open_default(&n).unwrap(); + let value = db + .property_int_value("rocksdb.estimate-live-data-size") + .unwrap(); + + assert!(value == 0); + } +} + +#[test] +fn property_cf_test() { + let n = DBPath::new("_rust_rocksdb_property_cf_test"); + { + let opts = Options::default(); + let db = DB::open_default(&n).unwrap(); + let cf = db.create_cf("cf1", &opts).unwrap(); + let total_keys = db + .property_int_value_cf(cf, "rocksdb.estimate-num-keys") + .unwrap() as usize; + + assert!(total_keys == 0); + } +} From 3a069ff4dc5ded1c96d724c71ea75cbf9cdc6322 Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 10 Feb 2019 17:29:41 +0000 Subject: [PATCH 5/7] Return a Result from property getters --- src/db.rs | 80 +++++++++++++++++++++++++++++++++--------- tests/test_property.rs | 6 ++-- 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/db.rs b/src/db.rs index b2a5912..09edb42 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1153,45 +1153,93 @@ impl DB { }) } - pub fn property_value(&self, name: &str) -> Option { - let prop_name = CString::new(name).unwrap(); + /// Retrieves a RocksDB property by name. + /// + /// For a full list of properties, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L428-L634 + pub fn property_value(&self, name: &str) -> Result, Error> { + let prop_name = match CString::new(name) { + Ok(c) => c, + Err(e) => { + return Err(Error::new(format!("Failed to convert property name to CString: {}", e))) + } + }; + unsafe { let value = ffi::rocksdb_property_value(self.inner, prop_name.as_ptr()); if value.is_null() { - return None; + return Ok(None); } - let s = CStr::from_ptr(value).to_str().unwrap().to_owned(); + let str_value = match CStr::from_ptr(value).to_str() { + Ok(s) => s.to_owned(), + Err(e) => { + return Err(Error::new(format!("Failed to convert property value to string: {}", e))) + } + }; + libc::free(value as *mut c_void); - Some(s) + Ok(Some(str_value)) } } - pub fn property_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { - let prop_name = CString::new(name).unwrap(); + /// Retrieves a RocksDB property by name, for a specific column family. + /// + /// For a full list of properties, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L428-L634 + pub fn property_value_cf(&self, cf: ColumnFamily, name: &str) -> Result, Error> { + let prop_name = match CString::new(name) { + Ok(c) => c, + Err(e) => { + return Err(Error::new(format!("Failed to convert property name to CString: {}", e))) + } + }; + unsafe { let value = ffi::rocksdb_property_value_cf(self.inner, cf.inner, prop_name.as_ptr()); if value.is_null() { - return None; + return Ok(None); } - let s = CStr::from_ptr(value).to_str().unwrap().to_owned(); + let str_value = match CStr::from_ptr(value).to_str() { + Ok(s) => s.to_owned(), + Err(e) => { + return Err(Error::new(format!("Failed to convert property value to string: {}", e))) + } + }; + libc::free(value as *mut c_void); - Some(s) + Ok(Some(str_value)) } } - pub fn property_int_value(&self, name: &str) -> Option { + /// Retrieves a RocksDB property and casts it to an integer. + /// + /// For a full list of properties that return int values, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L654-L689 + pub fn property_int_value(&self, name: &str) -> Result, Error> { match self.property_value(name) { - Some(value) => value.parse::().ok(), - None => None, + Ok(Some(value)) => match value.parse::() { + Ok(int_value) => Ok(Some(int_value)), + Err(e) => Err(Error::new(format!("Failed to convert property value to int: {}", e))), + } + Ok(None) => Ok(None), + Err(e) => Err(e), } } - pub fn property_int_value_cf(&self, cf: ColumnFamily, name: &str) -> Option { + /// Retrieves a RocksDB property for a specific column family and casts it to an integer. + /// + /// For a full list of properties that return int values, see + /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L654-L689 + pub fn property_int_value_cf(&self, cf: ColumnFamily, name: &str) -> Result, Error> { match self.property_value_cf(cf, name) { - Some(value) => value.parse::().ok(), - None => None, + Ok(Some(value)) => match value.parse::() { + Ok(int_value) => Ok(Some(int_value)), + Err(e) => Err(Error::new(format!("Failed to convert property value to int: {}", e))), + } + Ok(None) => Ok(None), + Err(e) => Err(e), } } } diff --git a/tests/test_property.rs b/tests/test_property.rs index 222755b..c2be439 100644 --- a/tests/test_property.rs +++ b/tests/test_property.rs @@ -27,7 +27,7 @@ fn property_test() { .property_int_value("rocksdb.estimate-live-data-size") .unwrap(); - assert!(value == 0); + assert!(value == Some(0)); } } @@ -40,8 +40,8 @@ fn property_cf_test() { let cf = db.create_cf("cf1", &opts).unwrap(); let total_keys = db .property_int_value_cf(cf, "rocksdb.estimate-num-keys") - .unwrap() as usize; + .unwrap(); - assert!(total_keys == 0); + assert!(total_keys == Some(0)); } } From 7b38b29d8cca393616fc5ba71a075c7e76969c66 Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 10 Feb 2019 17:33:44 +0000 Subject: [PATCH 6/7] Add more tests --- tests/test_property.rs | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/tests/test_property.rs b/tests/test_property.rs index c2be439..11e1f21 100644 --- a/tests/test_property.rs +++ b/tests/test_property.rs @@ -24,16 +24,46 @@ fn property_test() { { let db = DB::open_default(&n).unwrap(); let value = db - .property_int_value("rocksdb.estimate-live-data-size") + .property_value("rocksdb.stats") + .unwrap() .unwrap(); - assert!(value == Some(0)); + assert!(value.contains("Stats")); } } #[test] fn property_cf_test() { let n = DBPath::new("_rust_rocksdb_property_cf_test"); + { + let opts = Options::default(); + let db = DB::open_default(&n).unwrap(); + let cf = db.create_cf("cf1", &opts).unwrap(); + let value = db + .property_value_cf(cf, "rocksdb.stats") + .unwrap() + .unwrap(); + + assert!(value.contains("Stats")); + } +} + +#[test] +fn property_int_test() { + let n = DBPath::new("_rust_rocksdb_property_int_test"); + { + let db = DB::open_default(&n).unwrap(); + let value = db + .property_int_value("rocksdb.estimate-live-data-size") + .unwrap(); + + assert!(value == Some(0)); + } +} + +#[test] +fn property_int_cf_test() { + let n = DBPath::new("_rust_rocksdb_property_int_cf_test"); { let opts = Options::default(); let db = DB::open_default(&n).unwrap(); From 54cf68d3d07ae2b3e42c1a7785ad87d076737dcd Mon Sep 17 00:00:00 2001 From: Martin Ek Date: Sun, 10 Feb 2019 17:35:27 +0000 Subject: [PATCH 7/7] rustfmt --- src/db.rs | 40 +++++++++++++++++++++++++++++++--------- tests/test_property.rs | 10 ++-------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/db.rs b/src/db.rs index 09edb42..bbccf8f 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1161,7 +1161,10 @@ impl DB { let prop_name = match CString::new(name) { Ok(c) => c, Err(e) => { - return Err(Error::new(format!("Failed to convert property name to CString: {}", e))) + return Err(Error::new(format!( + "Failed to convert property name to CString: {}", + e + ))); } }; @@ -1174,7 +1177,10 @@ impl DB { let str_value = match CStr::from_ptr(value).to_str() { Ok(s) => s.to_owned(), Err(e) => { - return Err(Error::new(format!("Failed to convert property value to string: {}", e))) + return Err(Error::new(format!( + "Failed to convert property value to string: {}", + e + ))); } }; @@ -1191,7 +1197,10 @@ impl DB { let prop_name = match CString::new(name) { Ok(c) => c, Err(e) => { - return Err(Error::new(format!("Failed to convert property name to CString: {}", e))) + return Err(Error::new(format!( + "Failed to convert property name to CString: {}", + e + ))); } }; @@ -1204,7 +1213,10 @@ impl DB { let str_value = match CStr::from_ptr(value).to_str() { Ok(s) => s.to_owned(), Err(e) => { - return Err(Error::new(format!("Failed to convert property value to string: {}", e))) + return Err(Error::new(format!( + "Failed to convert property value to string: {}", + e + ))); } }; @@ -1221,8 +1233,11 @@ impl DB { match self.property_value(name) { Ok(Some(value)) => match value.parse::() { Ok(int_value) => Ok(Some(int_value)), - Err(e) => Err(Error::new(format!("Failed to convert property value to int: {}", e))), - } + Err(e) => Err(Error::new(format!( + "Failed to convert property value to int: {}", + e + ))), + }, Ok(None) => Ok(None), Err(e) => Err(e), } @@ -1232,12 +1247,19 @@ impl DB { /// /// For a full list of properties that return int values, see /// https://github.com/facebook/rocksdb/blob/08809f5e6cd9cc4bc3958dd4d59457ae78c76660/include/rocksdb/db.h#L654-L689 - pub fn property_int_value_cf(&self, cf: ColumnFamily, name: &str) -> Result, Error> { + pub fn property_int_value_cf( + &self, + cf: ColumnFamily, + name: &str, + ) -> Result, Error> { match self.property_value_cf(cf, name) { Ok(Some(value)) => match value.parse::() { Ok(int_value) => Ok(Some(int_value)), - Err(e) => Err(Error::new(format!("Failed to convert property value to int: {}", e))), - } + Err(e) => Err(Error::new(format!( + "Failed to convert property value to int: {}", + e + ))), + }, Ok(None) => Ok(None), Err(e) => Err(e), } diff --git a/tests/test_property.rs b/tests/test_property.rs index 11e1f21..6b30e59 100644 --- a/tests/test_property.rs +++ b/tests/test_property.rs @@ -23,10 +23,7 @@ fn property_test() { let n = DBPath::new("_rust_rocksdb_property_test"); { let db = DB::open_default(&n).unwrap(); - let value = db - .property_value("rocksdb.stats") - .unwrap() - .unwrap(); + let value = db.property_value("rocksdb.stats").unwrap().unwrap(); assert!(value.contains("Stats")); } @@ -39,10 +36,7 @@ fn property_cf_test() { let opts = Options::default(); let db = DB::open_default(&n).unwrap(); let cf = db.create_cf("cf1", &opts).unwrap(); - let value = db - .property_value_cf(cf, "rocksdb.stats") - .unwrap() - .unwrap(); + let value = db.property_value_cf(cf, "rocksdb.stats").unwrap().unwrap(); assert!(value.contains("Stats")); }