From 22ccf4fe5cf1b64582f6fee6c339c18ded00bd43 Mon Sep 17 00:00:00 2001 From: Harrm Date: Wed, 1 Oct 2025 12:35:16 +0300 Subject: [PATCH 01/12] Expose rocksdb raw iterator --- kvdb-rocksdb/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index 71146848..fdbf1af8 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -17,7 +17,7 @@ use std::{ }; use rocksdb::{ - BlockBasedOptions, ColumnFamily, ColumnFamilyDescriptor, Options, ReadOptions, WriteBatch, WriteOptions, DB, + BlockBasedOptions, ColumnFamily, ColumnFamilyDescriptor, DBRawIterator, Options, ReadOptions, WriteBatch, WriteOptions, DB }; use kvdb::{DBKeyValue, DBOp, DBTransaction, DBValue, KeyValueDB}; @@ -579,6 +579,10 @@ impl Database { pub fn try_catch_up_with_primary(&self) -> io::Result<()> { self.inner.db.try_catch_up_with_primary().map_err(other_io_err) } + + pub fn raw_iter(&self, col: u32) -> io::Result> { + Ok(self.inner.db.raw_iterator_cf(self.inner.cf(col as usize)?)) + } } // duplicate declaration of methods here to avoid trait import in certain existing cases From ec191b2a5573d71737e61b2bd2cbea680669ecd3 Mon Sep 17 00:00:00 2001 From: Harrm Date: Thu, 2 Oct 2025 16:06:50 +0300 Subject: [PATCH 02/12] Publicly export DBRawIterator --- kvdb-rocksdb/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index fdbf1af8..0e92386b 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -17,9 +17,11 @@ use std::{ }; use rocksdb::{ - BlockBasedOptions, ColumnFamily, ColumnFamilyDescriptor, DBRawIterator, Options, ReadOptions, WriteBatch, WriteOptions, DB + BlockBasedOptions, ColumnFamily, ColumnFamilyDescriptor, Options, ReadOptions, WriteBatch, WriteOptions, DB, }; +pub use rocksdb::DBRawIterator; + use kvdb::{DBKeyValue, DBOp, DBTransaction, DBValue, KeyValueDB}; #[cfg(target_os = "linux")] From 682a483a6a7b2ecaa66ca16dd0cd4fe24e9cd5c2 Mon Sep 17 00:00:00 2001 From: Harrm Date: Wed, 29 Oct 2025 14:37:05 +0300 Subject: [PATCH 03/12] Expose key comparator --- kvdb-rocksdb/src/lib.rs | 58 +++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index 0e92386b..79af5808 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -145,17 +145,39 @@ impl CompactionProfile { } } +trait Comparator<'a>: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering { + fn clone_self(&self) -> Box + 'a>; +} + +impl<'a, T: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering + Clone + 'a> Comparator<'a> for T { + fn clone_self(&self) -> Box + 'a> { + Box::new(self.clone()) + } +} + +impl<'a> Clone for Box + 'a> { + fn clone(&self) -> Box + 'a> { + self.clone_self() + } +} + +#[derive(Clone, Default)] +pub struct ColumnConfig { + /// Memory budget (in MiB) used for setting block cache size and + /// write buffer size for each column including the default one. + /// If the memory budget of a column is not specified, + /// `DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB` is used for that column. + pub memory_budget: Option, + + pub comparator: Option>>, +} + /// Database configuration #[derive(Clone)] #[non_exhaustive] pub struct DatabaseConfig { /// Max number of open files. pub max_open_files: i32, - /// Memory budget (in MiB) used for setting block cache size and - /// write buffer size for each column including the default one. - /// If the memory budget of a column is not specified, - /// `DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB` is used for that column. - pub memory_budget: HashMap, /// Compaction profile. pub compaction: CompactionProfile, /// Set number of columns. @@ -163,7 +185,7 @@ pub struct DatabaseConfig { /// # Safety /// /// The number of columns must not be zero. - pub columns: u32, + pub columns: Vec, /// Specify the maximum number of info/debug log files to be kept. pub keep_log_file_num: i32, /// Enable native RocksDB statistics. @@ -198,22 +220,22 @@ impl DatabaseConfig { /// # Safety /// /// The number of `columns` must not be zero. - pub fn with_columns(columns: u32) -> Self { - assert!(columns > 0, "the number of columns must not be zero"); + pub fn with_columns(columns: Vec) -> Self { + assert!(columns.len() > 0, "the number of columns must not be zero"); Self { columns, ..Default::default() } } /// Returns the total memory budget in bytes. pub fn memory_budget(&self) -> MiB { - (0..self.columns) - .map(|i| self.memory_budget.get(&i).unwrap_or(&DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB) + self.columns.iter() + .map(|i| i.memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB) .sum() } /// Returns the memory budget of the specified column in bytes. fn memory_budget_for_col(&self, col: u32) -> MiB { - self.memory_budget.get(&col).unwrap_or(&DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB + self.columns[col as usize].memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB } // Get column family configuration with the given block based options. @@ -226,6 +248,9 @@ impl DatabaseConfig { opts.optimize_level_style_compaction(column_mem_budget); opts.set_target_file_size_base(self.compaction.initial_file_size); opts.set_compression_per_level(&[]); + if let Some(comparator) = &self.columns[col as usize].comparator { + opts.set_comparator(&format!("column_{col}_comparator"), comparator.clone()); + } opts } @@ -235,9 +260,8 @@ impl Default for DatabaseConfig { fn default() -> DatabaseConfig { DatabaseConfig { max_open_files: 512, - memory_budget: HashMap::new(), compaction: CompactionProfile::default(), - columns: 1, + columns: vec![ColumnConfig::default()], keep_log_file_num: 1, enable_statistics: false, secondary: None, @@ -336,12 +360,12 @@ impl Database { /// /// The number of `config.columns` must not be zero. pub fn open>(config: &DatabaseConfig, path: P) -> io::Result { - assert!(config.columns > 0, "the number of columns must not be zero"); + assert!(config.columns.len() > 0, "the number of columns must not be zero"); let opts = generate_options(config); let block_opts = generate_block_based_options(config)?; - let column_names: Vec<_> = (0..config.columns).map(|c| format!("col{}", c)).collect(); + let column_names: Vec<_> = (0..config.columns.len()).map(|c| format!("col{}", c)).collect(); let write_opts = WriteOptions::default(); let read_opts = generate_read_options(); @@ -371,8 +395,8 @@ impl Database { column_names: &[&str], block_opts: &BlockBasedOptions, ) -> io::Result { - let cf_descriptors: Vec<_> = (0..config.columns) - .map(|i| ColumnFamilyDescriptor::new(column_names[i as usize], config.column_config(&block_opts, i))) + let cf_descriptors: Vec<_> = (0..config.columns.len()) + .map(|i| ColumnFamilyDescriptor::new(column_names[i as usize], config.column_config(&block_opts, i as u32))) .collect(); let db = match DB::open_cf_descriptors(&opts, path.as_ref(), cf_descriptors) { From ace6d0d5e214cc19af3428dcc7f307f47ccee1ec Mon Sep 17 00:00:00 2001 From: Harrm Date: Wed, 29 Oct 2025 17:31:00 +0300 Subject: [PATCH 04/12] Make Comparator public --- kvdb-rocksdb/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index 79af5808..b1b3a6c0 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -145,7 +145,7 @@ impl CompactionProfile { } } -trait Comparator<'a>: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering { +pub trait Comparator<'a>: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering { fn clone_self(&self) -> Box + 'a>; } From 6bee2886805602ecb2853a0b333af95187f0d797 Mon Sep 17 00:00:00 2001 From: Harrm Date: Wed, 12 Nov 2025 12:33:40 +0300 Subject: [PATCH 05/12] Fix comparator clone --- kvdb-rocksdb/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index b1b3a6c0..4bb07c81 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -151,7 +151,7 @@ pub trait Comparator<'a>: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering { impl<'a, T: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering + Clone + 'a> Comparator<'a> for T { fn clone_self(&self) -> Box + 'a> { - Box::new(self.clone()) + Box::new(T::clone(self)) } } From 3150b697a022059283243bb384aa58c5ceb93cd3 Mon Sep 17 00:00:00 2001 From: Harrm Date: Wed, 12 Nov 2025 14:44:29 +0300 Subject: [PATCH 06/12] Fix comparator clone --- kvdb-rocksdb/src/lib.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index 4bb07c81..7b58287e 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -145,19 +145,17 @@ impl CompactionProfile { } } -pub trait Comparator<'a>: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering { - fn clone_self(&self) -> Box + 'a>; +pub trait Comparator<'a>: Send + Sync { + fn get_fn(&self) -> Box cmp::Ordering + 'a>; } -impl<'a, T: Send + Sync + Fn(&[u8], &[u8]) -> cmp::Ordering + Clone + 'a> Comparator<'a> for T { - fn clone_self(&self) -> Box + 'a> { - Box::new(T::clone(self)) - } +pub struct ComparatorWrapper { + cmp: T, } -impl<'a> Clone for Box + 'a> { - fn clone(&self) -> Box + 'a> { - self.clone_self() +impl cmp::Ordering> Comparator<'static> for ComparatorWrapper { + fn get_fn(&self) -> Box cmp::Ordering + 'static> { + Box::new(self.cmp.clone()) } } @@ -169,7 +167,7 @@ pub struct ColumnConfig { /// `DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB` is used for that column. pub memory_budget: Option, - pub comparator: Option>>, + pub comparator: Option>>, } /// Database configuration @@ -249,7 +247,7 @@ impl DatabaseConfig { opts.set_target_file_size_base(self.compaction.initial_file_size); opts.set_compression_per_level(&[]); if let Some(comparator) = &self.columns[col as usize].comparator { - opts.set_comparator(&format!("column_{col}_comparator"), comparator.clone()); + opts.set_comparator(&format!("column_{col}_comparator"), comparator.get_fn()); } opts From 813dfa7626aff42f7349c7d7e7671230fc896e23 Mon Sep 17 00:00:00 2001 From: Harrm Date: Wed, 12 Nov 2025 14:50:10 +0300 Subject: [PATCH 07/12] Fix comparator clone --- kvdb-rocksdb/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index 7b58287e..cef89b0e 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -153,6 +153,12 @@ pub struct ComparatorWrapper { cmp: T, } +impl ComparatorWrapper { + pub fn new(cmp: T) -> Self { + Self { cmp } + } +} + impl cmp::Ordering> Comparator<'static> for ComparatorWrapper { fn get_fn(&self) -> Box cmp::Ordering + 'static> { Box::new(self.cmp.clone()) From e078caea091b2a0e0c182754d9d3232ee1ca0e7b Mon Sep 17 00:00:00 2001 From: Harrm Date: Thu, 20 Nov 2025 15:07:24 +0300 Subject: [PATCH 08/12] Update lib.rs --- kvdb-rocksdb/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index cef89b0e..4b2479c0 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -145,10 +145,13 @@ impl CompactionProfile { } } +/// Custom comparison function for row ordering pub trait Comparator<'a>: Send + Sync { fn get_fn(&self) -> Box cmp::Ordering + 'a>; } +/// A wrapper to allow the comparator to be both cloneable and convertible into Box, +/// which is required by RocksDb pub struct ComparatorWrapper { cmp: T, } @@ -173,6 +176,7 @@ pub struct ColumnConfig { /// `DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB` is used for that column. pub memory_budget: Option, + /// Custom comparison function for row ordering pub comparator: Option>>, } @@ -184,7 +188,7 @@ pub struct DatabaseConfig { pub max_open_files: i32, /// Compaction profile. pub compaction: CompactionProfile, - /// Set number of columns. + /// Configuration for column spaces. /// /// # Safety /// @@ -610,6 +614,8 @@ impl Database { self.inner.db.try_catch_up_with_primary().map_err(other_io_err) } + /// Raw RocksDb iterator, which exposes seek operations, unavailable + /// in Iterator trait pub fn raw_iter(&self, col: u32) -> io::Result> { Ok(self.inner.db.raw_iterator_cf(self.inner.cf(col as usize)?)) } From b788ce4f4ba0933a912d074b1e90dc3dea4b33b1 Mon Sep 17 00:00:00 2001 From: Harrm Date: Mon, 8 Dec 2025 23:08:11 +0300 Subject: [PATCH 09/12] Review and test fixes --- kvdb-rocksdb/examples/memtest.rs | 2 +- kvdb-rocksdb/src/lib.rs | 69 +++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/kvdb-rocksdb/examples/memtest.rs b/kvdb-rocksdb/examples/memtest.rs index f60ea50a..6963203a 100644 --- a/kvdb-rocksdb/examples/memtest.rs +++ b/kvdb-rocksdb/examples/memtest.rs @@ -101,7 +101,7 @@ fn main() { let mut config = DatabaseConfig::with_columns(COLUMN_COUNT); for c in 0..=COLUMN_COUNT { - config.memory_budget.insert(c, mb_per_col); + config.columns[c as usize].memory_budget = Some(mb_per_col); } let dir = tempfile::Builder::new().prefix("rocksdb-example").tempdir().unwrap(); diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index e970b512..4a596433 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -163,7 +163,9 @@ impl ComparatorWrapper { } } -impl cmp::Ordering> Comparator<'static> for ComparatorWrapper { +impl cmp::Ordering> Comparator<'static> + for ComparatorWrapper +{ fn get_fn(&self) -> Box cmp::Ordering + 'static> { Box::new(self.cmp.clone()) } @@ -177,7 +179,12 @@ pub struct ColumnConfig { /// `DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB` is used for that column. pub memory_budget: Option, - /// Custom comparison function for row ordering + /// Custom comparison function for row ordering. + /// Pass `None` to use the default lexicographic ordering. + /// + /// The client must ensure that the comparator supplied here has the same + /// name and orders keys *exactly* the same as the comparator provided to + /// previous open calls on the same DB. pub comparator: Option>>, } @@ -223,13 +230,25 @@ pub struct DatabaseConfig { } impl DatabaseConfig { + /// Create new `DatabaseConfig` with default parameters and specified number of columns with default configuration. + /// Note that cache sizes must be explicitly set. + /// + /// # Safety + /// + /// The number of `columns` must not be zero. + pub fn with_columns(columns: u32) -> Self { + assert!(columns > 0, "the number of columns must not be zero"); + + Self { columns: (0..columns).map(|_| ColumnConfig::default()).collect(), ..Default::default() } + } + /// Create new `DatabaseConfig` with default parameters and specified set of columns. /// Note that cache sizes must be explicitly set. /// /// # Safety /// /// The number of `columns` must not be zero. - pub fn with_columns(columns: Vec) -> Self { + pub fn with_configured_columns(columns: Vec) -> Self { assert!(columns.len() > 0, "the number of columns must not be zero"); Self { columns, ..Default::default() } @@ -237,14 +256,20 @@ impl DatabaseConfig { /// Returns the total memory budget in bytes. pub fn memory_budget(&self) -> MiB { - self.columns.iter() - .map(|i| i.memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB) + self.columns + .iter() + .map(|cfg| cfg.memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB) .sum() } /// Returns the memory budget of the specified column in bytes. fn memory_budget_for_col(&self, col: u32) -> MiB { - self.columns[col as usize].memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) * MB + let budget_mb = if let Some(cfg) = self.columns.get(col as usize) { + cfg.memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) + } else { + DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB + }; + budget_mb * MB } // Get column family configuration with the given block based options. @@ -572,10 +597,11 @@ impl Database { } /// Add a new column family to the DB. - pub fn add_column(&mut self) -> io::Result<()> { + pub fn add_column(&mut self, cfg: ColumnConfig) -> io::Result<()> { let DBAndColumns { ref mut db, ref mut column_names } = self.inner; let col = column_names.len() as u32; let name = format!("col{}", col); + self.config.columns.push(cfg); let col_config = self.config.column_config(&self.block_opts, col as u32); let _ = db.create_cf(&name, &col_config).map_err(other_io_err)?; column_names.push(name); @@ -618,7 +644,7 @@ impl Database { pub fn raw_iter(&self, col: u32) -> io::Result> { Ok(self.inner.db.raw_iterator_cf(self.inner.cf(col as usize)?)) } - + /// Force compact a single column. /// /// After compaction of the column, this may lead to better read performance. @@ -816,7 +842,7 @@ mod tests { #[test] #[should_panic] fn open_db_with_zero_columns() { - let cfg = DatabaseConfig { columns: 0, ..Default::default() }; + let cfg = DatabaseConfig { columns: vec![], ..Default::default() }; let _db = Database::open(&cfg, ""); } @@ -833,7 +859,7 @@ mod tests { assert_eq!(db.num_columns(), 1); for i in 2..=5 { - db.add_column().unwrap(); + db.add_column(Default::default()).unwrap(); assert_eq!(db.num_columns(), i); } } @@ -887,7 +913,7 @@ mod tests { #[test] fn default_memory_budget() { let c = DatabaseConfig::default(); - assert_eq!(c.columns, 1); + assert_eq!(c.columns.len(), 1); assert_eq!(c.memory_budget(), DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB * MB, "total memory budget is default"); assert_eq!( c.memory_budget_for_col(0), @@ -903,8 +929,13 @@ mod tests { #[test] fn memory_budget() { - let mut c = DatabaseConfig::with_columns(3); - c.memory_budget = [(0, 10), (1, 15), (2, 20)].iter().cloned().collect(); + let c = DatabaseConfig::with_configured_columns( + [10, 15, 20] + .iter() + .cloned() + .map(|n| ColumnConfig { memory_budget: Some(n), ..Default::default() }) + .collect(), + ); assert_eq!(c.memory_budget(), 45 * MB, "total budget is the sum of the column budget"); } @@ -928,11 +959,19 @@ rocksdb.db.get.micros P50 : 2.000000 P95 : 3.000000 P99 : 4.000000 P100 : 5.0000 #[test] fn rocksdb_settings() { const NUM_COLS: usize = 2; - let mut cfg = DatabaseConfig { enable_statistics: true, ..DatabaseConfig::with_columns(NUM_COLS as u32) }; + let mut cfg = DatabaseConfig { + enable_statistics: true, + ..DatabaseConfig::with_configured_columns( + [30, 300] + .iter() + .cloned() + .map(|n| ColumnConfig { memory_budget: Some(n), ..Default::default() }) + .collect(), + ) + }; cfg.max_open_files = 123; // is capped by the OS fd limit (typically 1024) cfg.compaction.block_size = 323232; cfg.compaction.initial_file_size = 102030; - cfg.memory_budget = [(0, 30), (1, 300)].iter().cloned().collect(); let db_path = TempfileBuilder::new() .prefix("config_test") From 30f2db6534a424c638995e7f5a4f76ad5f020fcc Mon Sep 17 00:00:00 2001 From: Harrm Date: Tue, 9 Dec 2025 01:22:26 +0300 Subject: [PATCH 10/12] Leave get_column untouched, add a separate method to add a column with config instead --- kvdb-rocksdb/src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index 4a596433..cd6f780f 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -596,8 +596,13 @@ impl Database { Ok(()) } + /// Add a new column family with default config to the DB. + pub fn add_column(&mut self) -> io::Result<()> { + self.add_column_with_config(Default::default()) + } + /// Add a new column family to the DB. - pub fn add_column(&mut self, cfg: ColumnConfig) -> io::Result<()> { + pub fn add_column_with_config(&mut self, cfg: ColumnConfig) -> io::Result<()> { let DBAndColumns { ref mut db, ref mut column_names } = self.inner; let col = column_names.len() as u32; let name = format!("col{}", col); @@ -859,7 +864,7 @@ mod tests { assert_eq!(db.num_columns(), 1); for i in 2..=5 { - db.add_column(Default::default()).unwrap(); + db.add_column().unwrap(); assert_eq!(db.num_columns(), i); } } From dcde8f93cf136b00a8fe8e6f1b9d87b53fe7a2d1 Mon Sep 17 00:00:00 2001 From: Harrm Date: Tue, 9 Dec 2025 15:34:59 +0300 Subject: [PATCH 11/12] Review fixes --- kvdb-rocksdb/src/lib.rs | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index cd6f780f..c68c8b99 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -146,31 +146,6 @@ impl CompactionProfile { } } -/// Custom comparison function for row ordering -pub trait Comparator<'a>: Send + Sync { - fn get_fn(&self) -> Box cmp::Ordering + 'a>; -} - -/// A wrapper to allow the comparator to be both cloneable and convertible into Box, -/// which is required by RocksDb -pub struct ComparatorWrapper { - cmp: T, -} - -impl ComparatorWrapper { - pub fn new(cmp: T) -> Self { - Self { cmp } - } -} - -impl cmp::Ordering> Comparator<'static> - for ComparatorWrapper -{ - fn get_fn(&self) -> Box cmp::Ordering + 'static> { - Box::new(self.cmp.clone()) - } -} - #[derive(Clone, Default)] pub struct ColumnConfig { /// Memory budget (in MiB) used for setting block cache size and @@ -185,7 +160,7 @@ pub struct ColumnConfig { /// The client must ensure that the comparator supplied here has the same /// name and orders keys *exactly* the same as the comparator provided to /// previous open calls on the same DB. - pub comparator: Option>>, + pub comparator: Option cmp::Ordering>, } /// Database configuration @@ -282,8 +257,8 @@ impl DatabaseConfig { opts.optimize_level_style_compaction(column_mem_budget); opts.set_target_file_size_base(self.compaction.initial_file_size); opts.set_compression_per_level(&[]); - if let Some(comparator) = &self.columns[col as usize].comparator { - opts.set_comparator(&format!("column_{col}_comparator"), comparator.get_fn()); + if let Some(comparator) = self.columns[col as usize].comparator { + opts.set_comparator(&format!("column_{col}_comparator"), Box::new(comparator)); } opts From 4b87b8617e01f5c1ee9d76eff2a2a8eb41e8b8fc Mon Sep 17 00:00:00 2001 From: Harrm Date: Tue, 9 Dec 2025 21:36:19 +0300 Subject: [PATCH 12/12] Review fixes --- kvdb-rocksdb/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/kvdb-rocksdb/src/lib.rs b/kvdb-rocksdb/src/lib.rs index c68c8b99..e296d477 100644 --- a/kvdb-rocksdb/src/lib.rs +++ b/kvdb-rocksdb/src/lib.rs @@ -157,8 +157,8 @@ pub struct ColumnConfig { /// Custom comparison function for row ordering. /// Pass `None` to use the default lexicographic ordering. /// - /// The client must ensure that the comparator supplied here has the same - /// name and orders keys *exactly* the same as the comparator provided to + /// The client must ensure that the comparator supplied here + /// orders keys *exactly* the same as the comparator provided to /// previous open calls on the same DB. pub comparator: Option cmp::Ordering>, } @@ -239,11 +239,11 @@ impl DatabaseConfig { /// Returns the memory budget of the specified column in bytes. fn memory_budget_for_col(&self, col: u32) -> MiB { - let budget_mb = if let Some(cfg) = self.columns.get(col as usize) { - cfg.memory_budget.unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB) - } else { - DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB - }; + let budget_mb = self + .columns + .get(col as usize) + .and_then(|cfg| cfg.memory_budget) + .unwrap_or(DB_DEFAULT_COLUMN_MEMORY_BUDGET_MB); budget_mb * MB }