diff --git a/src/db.rs b/src/db.rs index 1ecb6c4..dd2a061 100644 --- a/src/db.rs +++ b/src/db.rs @@ -677,28 +677,37 @@ impl DB { /// Open the database with the specified options. pub fn open>(opts: &Options, path: P) -> Result { - DB::open_cf(opts, path, &[]) + DB::open_cf(opts, path, None::<&str>) } /// Open a database with the given database options and column family names. /// /// Column families opened using this function will be created with default `Options`. - pub fn open_cf>(opts: &Options, path: P, cfs: &[&str]) -> Result { - let cfs_v = cfs - .to_vec() - .iter() - .map(|name| ColumnFamilyDescriptor::new(*name, Options::default())) - .collect(); + pub fn open_cf(opts: &Options, path: P, cfs: I) -> Result + where P: AsRef, + I: IntoIterator, + N: AsRef { + + let cfs = cfs + .into_iter() + .map(|name| ColumnFamilyDescriptor::new(name.as_ref(), Options::default())); - DB::open_cf_descriptors(opts, path, cfs_v) + DB::open_cf_descriptors(opts, path, cfs) } - /// Open a database with the given database options and column family names/options. - pub fn open_cf_descriptors>( + /// Open a database with the given database options and column family descriptors. + pub fn open_cf_descriptors( opts: &Options, path: P, - cfs: Vec, - ) -> Result { + cfs: I, + ) -> Result + where P: AsRef, + I: IntoIterator { + + let cfs: Vec<_> = cfs + .into_iter() + .collect(); + let path = path.as_ref(); let cpath = match CString::new(path.to_string_lossy().as_bytes()) { Ok(c) => c, diff --git a/src/db_options.rs b/src/db_options.rs index 925eb5a..0454d41 100644 --- a/src/db_options.rs +++ b/src/db_options.rs @@ -27,7 +27,7 @@ use merge_operator::{ use slice_transform::SliceTransform; use { BlockBasedIndexType, BlockBasedOptions, DBCompactionStyle, DBCompressionType, DBRecoveryMode, - MemtableFactory, Options, WriteOptions, + MemtableFactory, Options, PlainTableFactoryOptions, WriteOptions, }; pub fn new_cache(capacity: size_t) -> *mut ffi::rocksdb_cache_t { @@ -982,6 +982,33 @@ impl Options { } } + /// See https://github.com/facebook/rocksdb/wiki/PlainTable-Format. + /// + /// ``` + /// use rocksdb::{Options, PlainTableFactoryOptions}; + /// + /// let mut opts = Options::default(); + /// let factory_opts = PlainTableFactoryOptions { + /// user_key_length: 0, + /// bloom_bits_per_key: 20, + /// hash_table_ratio: 0.75, + /// index_sparseness: 16, + /// }; + /// + /// opts.set_plain_table_factory(&factory_opts); + /// ``` + pub fn set_plain_table_factory(&mut self, options: &PlainTableFactoryOptions) { + unsafe { + ffi::rocksdb_options_set_plain_table_factory( + self.inner, + options.user_key_length, + options.bloom_bits_per_key, + options.hash_table_ratio, + options.index_sparseness, + ); + } + } + /// Measure IO stats in compactions and flushes, if `true`. /// /// Default: `false` diff --git a/src/lib.rs b/src/lib.rs index 10390b4..fe94c43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -176,6 +176,21 @@ pub enum MemtableFactory { }, } +/// Used with DBOptions::set_plain_table_factory. +/// See https://github.com/facebook/rocksdb/wiki/PlainTable-Format. +/// +/// Defaults: +/// user_key_length: 0 (variable length) +/// bloom_bits_per_key: 10 +/// hash_table_ratio: 0.75 +/// index_sparseness: 16 +pub struct PlainTableFactoryOptions { + pub user_key_length: u32, + pub bloom_bits_per_key: i32, + pub hash_table_ratio: f64, + pub index_sparseness: usize, +} + /// Database-wide options around performance and behavior. /// /// Please read [the official tuning guide](https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide), and most importantly, measure performance under realistic workloads with realistic hardware. diff --git a/tests/test_column_family.rs b/tests/test_column_family.rs index bdd4eec..c9c44f2 100644 --- a/tests/test_column_family.rs +++ b/tests/test_column_family.rs @@ -19,7 +19,7 @@ use rocksdb::{ColumnFamilyDescriptor, MergeOperands, Options, DB}; use util::DBPath; #[test] -pub fn test_column_family() { +fn test_column_family() { let n = DBPath::new("_rust_rocksdb_cftest"); // should be able to create column families @@ -88,6 +88,30 @@ pub fn test_column_family() { } } +#[test] +fn test_can_open_db_with_results_of_list_cf() { + // Test scenario derived from GitHub issue #175 and 177 + + let n = DBPath::new("_rust_rocksdb_cftest_with_list_cf"); + + { + let mut opts = Options::default(); + opts.create_if_missing(true); + let db = DB::open(&opts, &n).unwrap(); + let opts = Options::default(); + + assert!(db.create_cf("cf1", &opts).is_ok()); + } + + { + let options = Options::default(); + let cfs = DB::list_cf(&options, &n).unwrap(); + let db = DB::open_cf(&options, &n, &cfs).unwrap(); + + assert!(db.cf_handle("cf1").is_some()); + } +} + #[test] fn test_create_missing_column_family() { let n = DBPath::new("_rust_rocksdb_missing_cftest"); @@ -172,7 +196,7 @@ fn test_provided_merge( } #[test] -pub fn test_column_family_with_options() { +fn test_column_family_with_options() { let n = DBPath::new("_rust_rocksdb_cf_with_optionstest"); { let mut cfopts = Options::default();