use rocksdb::{
BlockBasedOptions,
Cache,
DBCompactionStyle, DBCompressionType, FifoCompactOptions,
Options,
UniversalCompactOptions, WriteBufferManager,
};
use std::collections::HashSet;
#[derive(Debug)]
pub struct Tunable<T> {
pub inner: T,
locked: HashSet<&'static str>,
}
impl<T> Tunable<T> {
pub fn new(inner: T) -> Self {
Tunable {
inner,
locked: HashSet::new(),
}
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn is_locked(&self, key: &'static str) -> bool {
self.locked.contains(key)
}
fn lock(&mut self, key: &'static str) {
self.locked.insert(key);
}
}
#[macro_export]
macro_rules! tunable_methods {
(
$ty:ty;
$(
$(#[$outer:meta])*
fn $set_fn:ident(&mut self, $($arg_name:ident: $arg_ty:ty),*) => $inner_fn:ident {
key: $key_str:expr
}
),* $(,)?
) => {
impl $crate::tuner::tunable::Tunable<$ty> {
$(
$(#[$outer])*
pub fn $set_fn(&mut self, $($arg_name: $arg_ty),*) -> &mut Self {
self.inner.$inner_fn($($arg_name),*);
self.lock($key_str);
self
}
$(#[$outer])*
paste::paste! {
pub fn [<tune_$set_fn>](&mut self, $($arg_name: $arg_ty),*) -> &mut Self {
if !self.is_locked($key_str) {
self.inner.$inner_fn($($arg_name),*);
}
self
}
}
)*
}
};
}
tunable_methods! {
Options;
fn set_create_if_missing(&mut self, val: bool) => create_if_missing {
key: "db_create_if_missing"
},
fn set_create_missing_column_families(&mut self, val: bool) => create_missing_column_families {
key: "db_create_missing_column_families"
},
fn set_increase_parallelism(&mut self, total_threads: i32) => increase_parallelism {
key: "db_increase_parallelism"
},
fn set_max_open_files(&mut self, nfiles: i32) => set_max_open_files {
key: "db_max_open_files"
},
fn set_max_background_jobs(&mut self, val: i32) => set_max_background_jobs {
key: "db_max_background_jobs"
},
fn set_stats_dump_period_sec(&mut self, period: u32) => set_stats_dump_period_sec {
key: "db_stats_dump_period_sec"
},
fn set_rate_limiter(&mut self, rate_bytes_per_sec: i64, refill_period_us: i64, fairness: i32) => set_ratelimiter {
key: "db_rate_limiter"
},
fn set_bytes_per_sync(&mut self, nbytes: u64) => set_bytes_per_sync {
key: "db_bytes_per_sync"
},
fn set_wal_bytes_per_sync(&mut self, nbytes: u64) => set_wal_bytes_per_sync {
key: "db_wal_bytes_per_sync"
},
fn set_allow_concurrent_memtable_write(&mut self, allow: bool) => set_allow_concurrent_memtable_write {
key: "db_allow_concurrent_memtable_write"
},
fn set_enable_write_thread_adaptive_yield(&mut self, enabled: bool) => set_enable_write_thread_adaptive_yield {
key: "db_enable_write_thread_adaptive_yield"
},
fn set_atomic_flush(&mut self, val: bool) => set_atomic_flush {
key: "db_atomic_flush"
},
fn set_write_buffer_size(&mut self, size: usize) => set_write_buffer_size {
key: "cf_write_buffer_size"
},
fn set_max_write_buffer_number(&mut self, num: i32) => set_max_write_buffer_number {
key: "cf_max_write_buffer_number"
},
fn set_num_levels(&mut self, nlevels: i32) => set_num_levels {
key: "cf_num_levels"
},
fn set_level0_file_num_compaction_trigger(&mut self, trigger: i32) => set_level_zero_file_num_compaction_trigger {
key: "cf_level0_file_num_compaction_trigger"
},
fn set_level0_slowdown_writes_trigger(&mut self, trigger: i32) => set_level_zero_slowdown_writes_trigger {
key: "cf_level0_slowdown_writes_trigger"
},
fn set_level0_stop_writes_trigger(&mut self, trigger: i32) => set_level_zero_stop_writes_trigger {
key: "cf_level0_stop_writes_trigger"
},
fn set_target_file_size_base(&mut self, size: u64) => set_target_file_size_base {
key: "cf_target_file_size_base"
},
fn set_max_bytes_for_level_base(&mut self, size: u64) => set_max_bytes_for_level_base {
key: "cf_max_bytes_for_level_base"
},
fn set_max_compaction_bytes(&mut self, bytes: u64) => set_max_compaction_bytes {
key: "cf_max_compaction_bytes"
},
fn set_memtable_whole_key_filtering(&mut self, enable: bool) => set_memtable_whole_key_filtering {
key: "cf_memtable_whole_key_filtering"
},
fn set_memtable_prefix_bloom_size_ratio(&mut self, ratio: f64) => set_memtable_prefix_bloom_ratio {
key: "cf_memtable_prefix_bloom_size_ratio"
},
fn set_optimize_level_style_compaction(&mut self, memtable_memory_budget: usize) => optimize_level_style_compaction {
key: "cf_optimize_level_style_compaction"
},
fn set_optimize_universal_style_compaction(&mut self, memtable_memory_budget: usize) => optimize_universal_style_compaction {
key: "cf_optimize_universal_style_compaction"
},
fn set_optimize_filters_for_hits(&mut self, val: bool) => set_optimize_filters_for_hits {
key: "cf_optimize_filters_for_hits"
},
}
impl Tunable<Options> {
pub fn set_row_cache(&mut self, cache: &Cache) -> &mut Self {
self.inner.set_row_cache(&cache);
self.lock("db_row_cache");
self
}
pub fn tune_set_row_cache(&mut self, cache: &Cache) -> &mut Self {
if !self.is_locked("db_row_cache") {
self.inner.set_row_cache(&cache);
}
self
}
pub fn set_write_buffer_manager(&mut self, manager: &WriteBufferManager) -> &mut Self {
self.inner.set_write_buffer_manager(manager);
self.lock("db_write_buffer_manager");
self
}
pub fn tune_set_write_buffer_manager(&mut self, manager: &WriteBufferManager) -> &mut Self {
if !self.is_locked("db_write_buffer_manager") {
self.inner.set_write_buffer_manager(manager);
}
self
}
pub fn set_block_based_table_factory(&mut self, factory_opts: &BlockBasedOptions) -> &mut Self {
self.inner.set_block_based_table_factory(factory_opts);
self.lock("cf_block_based_table_factory");
self
}
pub fn tune_set_block_based_table_factory(&mut self, factory_opts: &BlockBasedOptions) -> &mut Self {
if !self.is_locked("cf_block_based_table_factory") {
self.inner.set_block_based_table_factory(factory_opts);
}
self
}
pub fn set_compaction_style(&mut self, style: DBCompactionStyle) -> &mut Self {
self.inner.set_compaction_style(style);
self.lock("cf_compaction_style");
self
}
pub fn tune_set_compaction_style(&mut self, style: DBCompactionStyle) -> &mut Self {
if !self.is_locked("cf_compaction_style") {
self.inner.set_compaction_style(style);
}
self
}
pub fn set_compression_type(&mut self, ctype: DBCompressionType) -> &mut Self {
self.inner.set_compression_type(ctype);
self.lock("cf_compression_type");
self
}
pub fn tune_set_compression_type(&mut self, ctype: DBCompressionType) -> &mut Self {
if !self.is_locked("cf_compression_type") {
self.inner.set_compression_type(ctype);
}
self
}
pub fn set_bottommost_compression_type(&mut self, ctype: DBCompressionType) -> &mut Self {
self.inner.set_bottommost_compression_type(ctype);
self.lock("cf_bottommost_compression_type");
self
}
pub fn tune_set_bottommost_compression_type(&mut self, ctype: DBCompressionType) -> &mut Self {
if !self.is_locked("cf_bottommost_compression_type") {
self.inner.set_bottommost_compression_type(ctype);
}
self
}
pub fn set_compaction_options_fifo(&mut self, opts: &FifoCompactOptions) -> &mut Self {
self.inner.set_fifo_compaction_options(opts);
self.lock("cf_compaction_options_fifo");
self
}
pub fn tune_set_compaction_options_fifo(&mut self, opts: &FifoCompactOptions) -> &mut Self {
if !self.is_locked("cf_compaction_options_fifo") {
self.inner.set_fifo_compaction_options(opts);
}
self
}
pub fn set_universal_compaction_options(&mut self, opts: &UniversalCompactOptions) -> &mut Self {
self.inner.set_universal_compaction_options(opts);
self.lock("cf_universal_compaction_options");
self
}
pub fn tune_set_universal_compaction_options(&mut self, opts: &UniversalCompactOptions) -> &mut Self {
if !self.is_locked("cf_universal_compaction_options") {
self.inner.set_universal_compaction_options(opts);
}
self
}
}