use crate::{
Error,
handle::{ConstHandle, Handle},
};
use std::ffi::{CStr, CString};
use std::path::Path;
use std::sync::Arc;
use libc::{self, c_char, c_double, c_int, c_uchar, c_uint, c_void, size_t};
use crate::compaction_filter::{self, CompactionFilterCallback, CompactionFilterFn};
use crate::compaction_filter_factory::{self, CompactionFilterFactory};
use crate::comparator::{self, ComparatorCallback, CompareFn};
use crate::ffi;
use crate::merge_operator::{
self, MergeFn, MergeOperatorCallback, full_merge_callback, partial_merge_callback,
};
use crate::slice_transform::SliceTransform;
use std::ptr::NonNull;
pub(crate) struct CacheWrapper {
pub(crate) inner: NonNull<ffi::rocksdb_cache_t>,
}
impl Drop for CacheWrapper {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_cache_destroy(self.inner.as_ptr());
}
}
}
#[derive(Clone)]
pub struct Cache(pub(crate) Arc<CacheWrapper>);
impl Cache {
pub fn new_lru_cache(capacity: size_t) -> Cache {
let inner = NonNull::new(unsafe { ffi::rocksdb_cache_create_lru(capacity) }).unwrap();
Cache(Arc::new(CacheWrapper { inner }))
}
pub fn new_hyper_clock_cache(capacity: size_t, estimated_entry_charge: size_t) -> Cache {
Cache(Arc::new(CacheWrapper {
inner: NonNull::new(unsafe {
ffi::rocksdb_cache_create_hyper_clock(capacity, estimated_entry_charge)
})
.unwrap(),
}))
}
pub fn get_usage(&self) -> usize {
unsafe { ffi::rocksdb_cache_get_usage(self.0.inner.as_ptr()) }
}
pub fn get_pinned_usage(&self) -> usize {
unsafe { ffi::rocksdb_cache_get_pinned_usage(self.0.inner.as_ptr()) }
}
pub fn set_capacity(&mut self, capacity: size_t) {
unsafe {
ffi::rocksdb_cache_set_capacity(self.0.inner.as_ptr(), capacity);
}
}
}
#[derive(Clone)]
pub struct Env(Arc<EnvWrapper>);
pub(crate) struct EnvWrapper {
inner: *mut ffi::rocksdb_env_t,
}
impl Drop for EnvWrapper {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_env_destroy(self.inner);
}
}
}
impl Env {
pub fn default_env() -> Result<Self, Error> {
let env = unsafe { ffi::rocksdb_create_default_env() };
if env.is_null() {
Err(Error::new("Could not create mem env".to_owned()))
} else {
Ok(Self(Arc::new(EnvWrapper { inner: env })))
}
}
pub fn mem_env() -> Result<Self, Error> {
let env = unsafe { ffi::rocksdb_create_mem_env() };
if env.is_null() {
Err(Error::new("Could not create mem env".to_owned()))
} else {
Ok(Self(Arc::new(EnvWrapper { inner: env })))
}
}
pub fn set_background_threads(&mut self, num_threads: c_int) {
unsafe {
ffi::rocksdb_env_set_background_threads(self.0.inner, num_threads);
}
}
pub fn set_high_priority_background_threads(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_env_set_high_priority_background_threads(self.0.inner, n);
}
}
pub fn set_low_priority_background_threads(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_env_set_low_priority_background_threads(self.0.inner, n);
}
}
pub fn set_bottom_priority_background_threads(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_env_set_bottom_priority_background_threads(self.0.inner, n);
}
}
pub fn join_all_threads(&mut self) {
unsafe {
ffi::rocksdb_env_join_all_threads(self.0.inner);
}
}
pub fn lower_thread_pool_io_priority(&mut self) {
unsafe {
ffi::rocksdb_env_lower_thread_pool_io_priority(self.0.inner);
}
}
pub fn lower_high_priority_thread_pool_io_priority(&mut self) {
unsafe {
ffi::rocksdb_env_lower_high_priority_thread_pool_io_priority(self.0.inner);
}
}
pub fn lower_thread_pool_cpu_priority(&mut self) {
unsafe {
ffi::rocksdb_env_lower_thread_pool_cpu_priority(self.0.inner);
}
}
pub fn lower_high_priority_thread_pool_cpu_priority(&mut self) {
unsafe {
ffi::rocksdb_env_lower_high_priority_thread_pool_cpu_priority(self.0.inner);
}
}
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
#[derive(Default)]
pub struct OptionsMustOutliveDB {
pub(crate) env: Option<Env>,
pub(crate) row_cache: Option<Cache>,
pub(crate) block_based: Option<BlockBasedOptionsMustOutliveDB>,
}
impl OptionsMustOutliveDB {
pub(crate) fn clone(&self) -> Self {
Self {
env: self.env.as_ref().map(Env::clone),
row_cache: self.row_cache.clone(),
block_based: self
.block_based
.as_ref()
.map(BlockBasedOptionsMustOutliveDB::clone),
}
}
}
#[derive(Default)]
pub(crate) struct BlockBasedOptionsMustOutliveDB {
block_cache: Option<Cache>,
}
impl BlockBasedOptionsMustOutliveDB {
fn clone(&self) -> Self {
Self {
block_cache: self.block_cache.clone(),
}
}
}
pub struct Options {
pub(crate) inner: *mut ffi::rocksdb_options_t,
pub(crate) outlive: OptionsMustOutliveDB,
}
pub struct WriteOptions {
option_set_sync: Option<bool>,
option_disable_wal: Option<bool>,
inner: *mut ffi::rocksdb_writeoptions_t,
}
pub struct FlushOptions {
pub(crate) inner: *mut ffi::rocksdb_flushoptions_t,
}
pub struct BlockBasedOptions {
pub(crate) inner: *mut ffi::rocksdb_block_based_table_options_t,
outlive: BlockBasedOptionsMustOutliveDB,
}
pub struct ReadOptions {
option_fill_cache: Option<bool>,
option_set_iterate_upper_bound: Option<Vec<u8>>,
option_set_iterate_lower_bound: Option<Vec<u8>>,
option_set_prefix_same_as_start: Option<bool>,
option_set_total_order_seek: Option<bool>,
option_set_readahead_size: Option<usize>,
inner: *mut ffi::rocksdb_readoptions_t,
}
pub struct CuckooTableOptions {
pub(crate) inner: *mut ffi::rocksdb_cuckoo_table_options_t,
}
pub struct IngestExternalFileOptions {
pub(crate) inner: *mut ffi::rocksdb_ingestexternalfileoptions_t,
}
unsafe impl Send for Options {}
unsafe impl Send for WriteOptions {}
unsafe impl Send for BlockBasedOptions {}
unsafe impl Send for CuckooTableOptions {}
unsafe impl Send for ReadOptions {}
unsafe impl Send for IngestExternalFileOptions {}
unsafe impl Send for CacheWrapper {}
unsafe impl Send for EnvWrapper {}
unsafe impl Sync for Options {}
unsafe impl Sync for WriteOptions {}
unsafe impl Sync for BlockBasedOptions {}
unsafe impl Sync for CuckooTableOptions {}
unsafe impl Sync for ReadOptions {}
unsafe impl Sync for IngestExternalFileOptions {}
unsafe impl Sync for CacheWrapper {}
unsafe impl Sync for EnvWrapper {}
impl Drop for Options {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_options_destroy(self.inner);
}
}
}
impl Clone for Options {
fn clone(&self) -> Self {
let inner = unsafe { ffi::rocksdb_options_create_copy(self.inner) };
assert!(!inner.is_null(), "Could not copy RocksDB options");
Self {
inner,
outlive: self.outlive.clone(),
}
}
}
impl Drop for BlockBasedOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_block_based_options_destroy(self.inner);
}
}
}
impl Drop for CuckooTableOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_cuckoo_options_destroy(self.inner);
}
}
}
impl Drop for FlushOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_flushoptions_destroy(self.inner);
}
}
}
impl Drop for WriteOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_writeoptions_destroy(self.inner);
}
}
}
impl Drop for ReadOptions {
fn drop(&mut self) {
unsafe { ffi::rocksdb_readoptions_destroy(self.inner) }
}
}
impl Drop for IngestExternalFileOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_ingestexternalfileoptions_destroy(self.inner);
}
}
}
impl BlockBasedOptions {
pub fn set_block_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_block_based_options_set_block_size(self.inner, size);
}
}
pub fn set_metadata_block_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_block_based_options_set_metadata_block_size(self.inner, size as u64);
}
}
pub fn set_partition_filters(&mut self, size: bool) {
unsafe {
ffi::rocksdb_block_based_options_set_partition_filters(self.inner, size as c_uchar);
}
}
pub fn set_block_cache(&mut self, cache: &Cache) {
unsafe {
ffi::rocksdb_block_based_options_set_block_cache(self.inner, cache.0.inner.as_ptr());
}
self.outlive.block_cache = Some(cache.clone());
}
pub fn disable_cache(&mut self) {
unsafe {
ffi::rocksdb_block_based_options_set_no_block_cache(self.inner, true as c_uchar);
}
}
pub fn set_bloom_filter(&mut self, bits_per_key: c_double, block_based: bool) {
unsafe {
let bloom = if block_based {
ffi::rocksdb_filterpolicy_create_bloom(bits_per_key)
} else {
ffi::rocksdb_filterpolicy_create_bloom_full(bits_per_key)
};
ffi::rocksdb_block_based_options_set_filter_policy(self.inner, bloom);
}
}
pub fn set_ribbon_filter(&mut self, bloom_equivalent_bits_per_key: c_double) {
unsafe {
let ribbon = ffi::rocksdb_filterpolicy_create_ribbon(bloom_equivalent_bits_per_key);
ffi::rocksdb_block_based_options_set_filter_policy(self.inner, ribbon);
}
}
pub fn set_hybrid_ribbon_filter(
&mut self,
bloom_equivalent_bits_per_key: c_double,
bloom_before_level: c_int,
) {
unsafe {
let ribbon = ffi::rocksdb_filterpolicy_create_ribbon_hybrid(
bloom_equivalent_bits_per_key,
bloom_before_level,
);
ffi::rocksdb_block_based_options_set_filter_policy(self.inner, ribbon);
}
}
pub fn set_cache_index_and_filter_blocks(&mut self, v: bool) {
unsafe {
ffi::rocksdb_block_based_options_set_cache_index_and_filter_blocks(self.inner, v as u8);
}
}
pub fn set_index_type(&mut self, index_type: BlockBasedIndexType) {
let index = index_type as i32;
unsafe {
ffi::rocksdb_block_based_options_set_index_type(self.inner, index);
}
}
pub fn set_pin_l0_filter_and_index_blocks_in_cache(&mut self, v: bool) {
unsafe {
ffi::rocksdb_block_based_options_set_pin_l0_filter_and_index_blocks_in_cache(
self.inner,
v as c_uchar,
);
}
}
pub fn set_pin_top_level_index_and_filter(&mut self, v: bool) {
unsafe {
ffi::rocksdb_block_based_options_set_pin_top_level_index_and_filter(
self.inner,
v as c_uchar,
);
}
}
pub fn set_format_version(&mut self, version: i32) {
unsafe {
ffi::rocksdb_block_based_options_set_format_version(self.inner, version);
}
}
pub fn set_block_restart_interval(&mut self, interval: i32) {
unsafe {
ffi::rocksdb_block_based_options_set_block_restart_interval(self.inner, interval);
}
}
pub fn set_index_block_restart_interval(&mut self, interval: i32) {
unsafe {
ffi::rocksdb_block_based_options_set_index_block_restart_interval(self.inner, interval);
}
}
pub fn set_data_block_index_type(&mut self, index_type: DataBlockIndexType) {
let index_t = index_type as i32;
unsafe {
ffi::rocksdb_block_based_options_set_data_block_index_type(self.inner, index_t);
}
}
pub fn set_data_block_hash_ratio(&mut self, ratio: f64) {
unsafe {
ffi::rocksdb_block_based_options_set_data_block_hash_ratio(self.inner, ratio);
}
}
pub fn set_whole_key_filtering(&mut self, v: bool) {
unsafe {
ffi::rocksdb_block_based_options_set_whole_key_filtering(self.inner, v as u8);
}
}
}
impl Default for BlockBasedOptions {
fn default() -> Self {
let block_opts = unsafe { ffi::rocksdb_block_based_options_create() };
assert!(
!block_opts.is_null(),
"Could not create RocksDB block based options"
);
Self {
inner: block_opts,
outlive: BlockBasedOptionsMustOutliveDB::default(),
}
}
}
impl CuckooTableOptions {
pub fn set_hash_ratio(&mut self, ratio: f64) {
unsafe {
ffi::rocksdb_cuckoo_options_set_hash_ratio(self.inner, ratio);
}
}
pub fn set_max_search_depth(&mut self, depth: u32) {
unsafe {
ffi::rocksdb_cuckoo_options_set_max_search_depth(self.inner, depth);
}
}
pub fn set_cuckoo_block_size(&mut self, size: u32) {
unsafe {
ffi::rocksdb_cuckoo_options_set_cuckoo_block_size(self.inner, size);
}
}
pub fn set_identity_as_first_hash(&mut self, flag: bool) {
let v = flag as u8;
unsafe {
ffi::rocksdb_cuckoo_options_set_identity_as_first_hash(self.inner, v);
}
}
pub fn set_use_module_hash(&mut self, flag: bool) {
let v = flag as u8;
unsafe {
ffi::rocksdb_cuckoo_options_set_use_module_hash(self.inner, v);
}
}
}
impl Default for CuckooTableOptions {
fn default() -> Self {
let opts = unsafe { ffi::rocksdb_cuckoo_options_create() };
assert!(!opts.is_null(), "Could not create RocksDB cuckoo options");
Self { inner: opts }
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(i32)]
pub enum LogLevel {
Debug = 0,
Info,
Warn,
Error,
Fatal,
Header,
}
impl Options {
pub fn increase_parallelism(&mut self, parallelism: i32) {
unsafe {
ffi::rocksdb_options_increase_parallelism(self.inner, parallelism);
}
}
pub fn optimize_level_style_compaction(&mut self, memtable_memory_budget: usize) {
unsafe {
ffi::rocksdb_options_optimize_level_style_compaction(
self.inner,
memtable_memory_budget as u64,
);
}
}
pub fn optimize_universal_style_compaction(&mut self, memtable_memory_budget: usize) {
unsafe {
ffi::rocksdb_options_optimize_universal_style_compaction(
self.inner,
memtable_memory_budget as u64,
);
}
}
pub fn create_if_missing(&mut self, create_if_missing: bool) {
unsafe {
ffi::rocksdb_options_set_create_if_missing(self.inner, create_if_missing as c_uchar);
}
}
pub fn create_missing_column_families(&mut self, create_missing_cfs: bool) {
unsafe {
ffi::rocksdb_options_set_create_missing_column_families(
self.inner,
create_missing_cfs as c_uchar,
);
}
}
pub fn set_error_if_exists(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_error_if_exists(self.inner, enabled as c_uchar);
}
}
pub fn set_paranoid_checks(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_paranoid_checks(self.inner, enabled as c_uchar);
}
}
pub fn set_db_paths(&mut self, paths: &[DBPath]) {
let mut paths: Vec<_> = paths
.iter()
.map(|path| path.inner as *const ffi::rocksdb_dbpath_t)
.collect();
let num_paths = paths.len();
unsafe {
ffi::rocksdb_options_set_db_paths(self.inner, paths.as_mut_ptr(), num_paths);
}
}
pub fn set_env(&mut self, env: &Env) {
unsafe {
ffi::rocksdb_options_set_env(self.inner, env.0.inner);
}
self.outlive.env = Some(env.clone());
}
pub fn set_compression_type(&mut self, t: DBCompressionType) {
unsafe {
ffi::rocksdb_options_set_compression(self.inner, t as c_int);
}
}
pub fn set_bottommost_compression_type(&mut self, t: DBCompressionType) {
unsafe {
ffi::rocksdb_options_set_bottommost_compression(self.inner, t as c_int);
}
}
pub fn set_compression_per_level(&mut self, level_types: &[DBCompressionType]) {
unsafe {
let mut level_types: Vec<_> = level_types.iter().map(|&t| t as c_int).collect();
ffi::rocksdb_options_set_compression_per_level(
self.inner,
level_types.as_mut_ptr(),
level_types.len() as size_t,
);
}
}
pub fn set_compression_options(
&mut self,
w_bits: c_int,
level: c_int,
strategy: c_int,
max_dict_bytes: c_int,
) {
unsafe {
ffi::rocksdb_options_set_compression_options(
self.inner,
w_bits,
level,
strategy,
max_dict_bytes,
);
}
}
pub fn set_bottommost_compression_options(
&mut self,
w_bits: c_int,
level: c_int,
strategy: c_int,
max_dict_bytes: c_int,
enabled: bool,
) {
unsafe {
ffi::rocksdb_options_set_bottommost_compression_options(
self.inner,
w_bits,
level,
strategy,
max_dict_bytes,
enabled as c_uchar,
);
}
}
pub fn set_zstd_max_train_bytes(&mut self, value: c_int) {
unsafe {
ffi::rocksdb_options_set_compression_options_zstd_max_train_bytes(self.inner, value);
}
}
pub fn set_bottommost_zstd_max_train_bytes(&mut self, value: c_int, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_bottommost_compression_options_zstd_max_train_bytes(
self.inner,
value,
enabled as c_uchar,
);
}
}
pub fn set_compaction_readahead_size(&mut self, compaction_readahead_size: usize) {
unsafe {
ffi::rocksdb_options_compaction_readahead_size(self.inner, compaction_readahead_size);
}
}
pub fn set_level_compaction_dynamic_level_bytes(&mut self, v: bool) {
unsafe {
ffi::rocksdb_options_set_level_compaction_dynamic_level_bytes(self.inner, v as c_uchar);
}
}
pub fn set_merge_operator_associative<F: MergeFn + Clone>(
&mut self,
name: &str,
full_merge_fn: F,
) {
let cb = Box::new(MergeOperatorCallback {
name: CString::new(name.as_bytes()).unwrap(),
full_merge_fn: full_merge_fn.clone(),
partial_merge_fn: full_merge_fn,
});
unsafe {
let mo = ffi::rocksdb_mergeoperator_create(
Box::into_raw(cb).cast::<c_void>(),
Some(merge_operator::destructor_callback::<F, F>),
Some(full_merge_callback::<F, F>),
Some(partial_merge_callback::<F, F>),
Some(merge_operator::delete_callback),
Some(merge_operator::name_callback::<F, F>),
);
ffi::rocksdb_options_set_merge_operator(self.inner, mo);
}
}
pub fn set_merge_operator<F: MergeFn, PF: MergeFn>(
&mut self,
name: &str,
full_merge_fn: F,
partial_merge_fn: PF,
) {
let cb = Box::new(MergeOperatorCallback {
name: CString::new(name.as_bytes()).unwrap(),
full_merge_fn,
partial_merge_fn,
});
unsafe {
let mo = ffi::rocksdb_mergeoperator_create(
Box::into_raw(cb).cast::<c_void>(),
Some(merge_operator::destructor_callback::<F, PF>),
Some(full_merge_callback::<F, PF>),
Some(partial_merge_callback::<F, PF>),
Some(merge_operator::delete_callback),
Some(merge_operator::name_callback::<F, PF>),
);
ffi::rocksdb_options_set_merge_operator(self.inner, mo);
}
}
#[deprecated(
since = "0.5.0",
note = "add_merge_operator has been renamed to set_merge_operator"
)]
pub fn add_merge_operator<F: MergeFn + Clone>(&mut self, name: &str, merge_fn: F) {
self.set_merge_operator_associative(name, merge_fn);
}
pub fn set_compaction_filter<F>(&mut self, name: &str, filter_fn: F)
where
F: CompactionFilterFn + Send + 'static,
{
let cb = Box::new(CompactionFilterCallback {
name: CString::new(name.as_bytes()).unwrap(),
filter_fn,
});
unsafe {
let cf = ffi::rocksdb_compactionfilter_create(
Box::into_raw(cb).cast::<c_void>(),
Some(compaction_filter::destructor_callback::<CompactionFilterCallback<F>>),
Some(compaction_filter::filter_callback::<CompactionFilterCallback<F>>),
Some(compaction_filter::name_callback::<CompactionFilterCallback<F>>),
);
ffi::rocksdb_options_set_compaction_filter(self.inner, cf);
}
}
pub fn set_compaction_filter_factory<F>(&mut self, factory: F)
where
F: CompactionFilterFactory + 'static,
{
let factory = Box::new(factory);
unsafe {
let cff = ffi::rocksdb_compactionfilterfactory_create(
Box::into_raw(factory).cast::<c_void>(),
Some(compaction_filter_factory::destructor_callback::<F>),
Some(compaction_filter_factory::create_compaction_filter_callback::<F>),
Some(compaction_filter_factory::name_callback::<F>),
);
ffi::rocksdb_options_set_compaction_filter_factory(self.inner, cff);
}
}
pub fn set_comparator(&mut self, name: &str, compare_fn: CompareFn) {
let cb = Box::new(ComparatorCallback {
name: CString::new(name.as_bytes()).unwrap(),
f: compare_fn,
});
unsafe {
let cmp = ffi::rocksdb_comparator_create(
Box::into_raw(cb).cast::<c_void>(),
Some(comparator::destructor_callback),
Some(comparator::compare_callback),
Some(comparator::name_callback),
);
ffi::rocksdb_options_set_comparator(self.inner, cmp);
}
}
pub fn set_prefix_extractor(&mut self, prefix_extractor: SliceTransform) {
unsafe {
ffi::rocksdb_options_set_prefix_extractor(self.inner, prefix_extractor.inner);
}
}
#[deprecated(
since = "0.5.0",
note = "add_comparator has been renamed to set_comparator"
)]
pub fn add_comparator(&mut self, name: &str, compare_fn: CompareFn) {
self.set_comparator(name, compare_fn);
}
pub fn optimize_for_point_lookup(&mut self, cache_size: u64) {
unsafe {
ffi::rocksdb_options_optimize_for_point_lookup(self.inner, cache_size);
}
}
pub fn set_optimize_filters_for_hits(&mut self, optimize_for_hits: bool) {
unsafe {
ffi::rocksdb_options_set_optimize_filters_for_hits(
self.inner,
optimize_for_hits as c_int,
);
}
}
pub fn set_delete_obsolete_files_period_micros(&mut self, micros: u64) {
unsafe {
ffi::rocksdb_options_set_delete_obsolete_files_period_micros(self.inner, micros);
}
}
pub fn set_prepare_for_bulk_load(&mut self) {
unsafe {
ffi::rocksdb_options_prepare_for_bulk_load(self.inner);
}
}
pub fn set_max_open_files(&mut self, nfiles: c_int) {
unsafe {
ffi::rocksdb_options_set_max_open_files(self.inner, nfiles);
}
}
pub fn set_max_file_opening_threads(&mut self, nthreads: c_int) {
unsafe {
ffi::rocksdb_options_set_max_file_opening_threads(self.inner, nthreads);
}
}
pub fn set_use_fsync(&mut self, useit: bool) {
unsafe {
ffi::rocksdb_options_set_use_fsync(self.inner, useit as c_int);
}
}
pub fn set_db_log_dir<P: AsRef<Path>>(&mut self, path: P) {
let p = CString::new(path.as_ref().to_string_lossy().as_bytes()).unwrap();
unsafe {
ffi::rocksdb_options_set_db_log_dir(self.inner, p.as_ptr());
}
}
pub fn set_log_level(&mut self, level: LogLevel) {
unsafe {
ffi::rocksdb_options_set_info_log_level(self.inner, level as c_int);
}
}
pub fn set_bytes_per_sync(&mut self, nbytes: u64) {
unsafe {
ffi::rocksdb_options_set_bytes_per_sync(self.inner, nbytes);
}
}
pub fn set_wal_bytes_per_sync(&mut self, nbytes: u64) {
unsafe {
ffi::rocksdb_options_set_wal_bytes_per_sync(self.inner, nbytes);
}
}
pub fn set_writable_file_max_buffer_size(&mut self, nbytes: u64) {
unsafe {
ffi::rocksdb_options_set_writable_file_max_buffer_size(self.inner, nbytes);
}
}
pub fn set_allow_concurrent_memtable_write(&mut self, allow: bool) {
unsafe {
ffi::rocksdb_options_set_allow_concurrent_memtable_write(self.inner, allow as c_uchar);
}
}
pub fn set_enable_write_thread_adaptive_yield(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_enable_write_thread_adaptive_yield(
self.inner,
enabled as c_uchar,
);
}
}
pub fn set_max_sequential_skip_in_iterations(&mut self, num: u64) {
unsafe {
ffi::rocksdb_options_set_max_sequential_skip_in_iterations(self.inner, num);
}
}
pub fn set_use_direct_reads(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_use_direct_reads(self.inner, enabled as c_uchar);
}
}
pub fn set_use_direct_io_for_flush_and_compaction(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_use_direct_io_for_flush_and_compaction(
self.inner,
enabled as c_uchar,
);
}
}
pub fn set_is_fd_close_on_exec(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_is_fd_close_on_exec(self.inner, enabled as c_uchar);
}
}
#[deprecated(
since = "0.7.0",
note = "replaced with set_use_direct_reads/set_use_direct_io_for_flush_and_compaction methods"
)]
pub fn set_allow_os_buffer(&mut self, is_allow: bool) {
self.set_use_direct_reads(!is_allow);
self.set_use_direct_io_for_flush_and_compaction(!is_allow);
}
pub fn set_table_cache_num_shard_bits(&mut self, nbits: c_int) {
unsafe {
ffi::rocksdb_options_set_table_cache_numshardbits(self.inner, nbits);
}
}
pub fn set_target_file_size_multiplier(&mut self, multiplier: i32) {
unsafe {
ffi::rocksdb_options_set_target_file_size_multiplier(self.inner, multiplier as c_int);
}
}
pub fn set_min_write_buffer_number(&mut self, nbuf: c_int) {
unsafe {
ffi::rocksdb_options_set_min_write_buffer_number_to_merge(self.inner, nbuf);
}
}
pub fn set_max_write_buffer_number(&mut self, nbuf: c_int) {
unsafe {
ffi::rocksdb_options_set_max_write_buffer_number(self.inner, nbuf);
}
}
pub fn set_write_buffer_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_options_set_write_buffer_size(self.inner, size);
}
}
pub fn set_db_write_buffer_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_options_set_db_write_buffer_size(self.inner, size);
}
}
pub fn set_max_bytes_for_level_base(&mut self, size: u64) {
unsafe {
ffi::rocksdb_options_set_max_bytes_for_level_base(self.inner, size);
}
}
pub fn set_max_bytes_for_level_multiplier(&mut self, mul: f64) {
unsafe {
ffi::rocksdb_options_set_max_bytes_for_level_multiplier(self.inner, mul);
}
}
pub fn set_max_manifest_file_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_options_set_max_manifest_file_size(self.inner, size);
}
}
pub fn set_target_file_size_base(&mut self, size: u64) {
unsafe {
ffi::rocksdb_options_set_target_file_size_base(self.inner, size);
}
}
pub fn set_min_write_buffer_number_to_merge(&mut self, to_merge: c_int) {
unsafe {
ffi::rocksdb_options_set_min_write_buffer_number_to_merge(self.inner, to_merge);
}
}
pub fn set_level_zero_file_num_compaction_trigger(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_options_set_level0_file_num_compaction_trigger(self.inner, n);
}
}
pub fn set_level_zero_slowdown_writes_trigger(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_options_set_level0_slowdown_writes_trigger(self.inner, n);
}
}
pub fn set_level_zero_stop_writes_trigger(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_options_set_level0_stop_writes_trigger(self.inner, n);
}
}
pub fn set_compaction_style(&mut self, style: DBCompactionStyle) {
unsafe {
ffi::rocksdb_options_set_compaction_style(self.inner, style as c_int);
}
}
pub fn set_universal_compaction_options(&mut self, uco: &UniversalCompactOptions) {
unsafe {
ffi::rocksdb_options_set_universal_compaction_options(self.inner, uco.inner);
}
}
pub fn set_fifo_compaction_options(&mut self, fco: &FifoCompactOptions) {
unsafe {
ffi::rocksdb_options_set_fifo_compaction_options(self.inner, fco.inner);
}
}
pub fn set_unordered_write(&mut self, unordered: bool) {
unsafe {
ffi::rocksdb_options_set_unordered_write(self.inner, unordered as c_uchar);
}
}
pub fn set_max_subcompactions(&mut self, num: u32) {
unsafe {
ffi::rocksdb_options_set_max_subcompactions(self.inner, num);
}
}
pub fn set_max_background_jobs(&mut self, jobs: c_int) {
unsafe {
ffi::rocksdb_options_set_max_background_jobs(self.inner, jobs);
}
}
#[deprecated(
since = "0.17.0",
note = "RocksDB automatically decides this based on the value of max_background_jobs"
)]
pub fn set_max_background_compactions(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_options_set_max_background_compactions(self.inner, n);
}
}
#[deprecated(
since = "0.17.0",
note = "RocksDB automatically decides this based on the value of max_background_jobs"
)]
pub fn set_max_background_flushes(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_options_set_max_background_flushes(self.inner, n);
}
}
pub fn set_disable_auto_compactions(&mut self, disable: bool) {
unsafe {
ffi::rocksdb_options_set_disable_auto_compactions(self.inner, disable as c_int);
}
}
pub fn set_memtable_huge_page_size(&mut self, size: size_t) {
unsafe {
ffi::rocksdb_options_set_memtable_huge_page_size(self.inner, size);
}
}
pub fn set_max_successive_merges(&mut self, num: usize) {
unsafe {
ffi::rocksdb_options_set_max_successive_merges(self.inner, num);
}
}
pub fn set_bloom_locality(&mut self, v: u32) {
unsafe {
ffi::rocksdb_options_set_bloom_locality(self.inner, v);
}
}
pub fn set_inplace_update_support(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_inplace_update_support(self.inner, enabled as c_uchar);
}
}
pub fn set_inplace_update_locks(&mut self, num: usize) {
unsafe {
ffi::rocksdb_options_set_inplace_update_num_locks(self.inner, num);
}
}
pub fn set_max_bytes_for_level_multiplier_additional(&mut self, level_values: &[i32]) {
let count = level_values.len();
unsafe {
ffi::rocksdb_options_set_max_bytes_for_level_multiplier_additional(
self.inner,
level_values.as_ptr() as *mut c_int,
count,
);
}
}
pub fn set_skip_checking_sst_file_sizes_on_db_open(&mut self, value: bool) {
unsafe {
ffi::rocksdb_options_set_skip_checking_sst_file_sizes_on_db_open(
self.inner,
value as c_uchar,
);
}
}
pub fn set_max_write_buffer_size_to_maintain(&mut self, size: i64) {
unsafe {
ffi::rocksdb_options_set_max_write_buffer_size_to_maintain(self.inner, size);
}
}
pub fn set_enable_pipelined_write(&mut self, value: bool) {
unsafe {
ffi::rocksdb_options_set_enable_pipelined_write(self.inner, value as c_uchar);
}
}
pub fn set_memtable_factory(&mut self, factory: MemtableFactory) {
match factory {
MemtableFactory::Vector => unsafe {
ffi::rocksdb_options_set_memtable_vector_rep(self.inner);
},
MemtableFactory::HashSkipList {
bucket_count,
height,
branching_factor,
} => unsafe {
ffi::rocksdb_options_set_hash_skip_list_rep(
self.inner,
bucket_count,
height,
branching_factor,
);
},
MemtableFactory::HashLinkList { bucket_count } => unsafe {
ffi::rocksdb_options_set_hash_link_list_rep(self.inner, bucket_count);
},
};
}
pub fn set_block_based_table_factory(&mut self, factory: &BlockBasedOptions) {
unsafe {
ffi::rocksdb_options_set_block_based_table_factory(self.inner, factory.inner);
}
self.outlive.block_based = Some(factory.outlive.clone());
}
pub fn set_cuckoo_table_factory(&mut self, factory: &CuckooTableOptions) {
unsafe {
ffi::rocksdb_options_set_cuckoo_table_factory(self.inner, factory.inner);
}
}
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,
options.huge_page_tlb_size,
options.encoding_type as c_char,
c_uchar::from(options.full_scan_mode),
c_uchar::from(options.store_index_in_file),
);
}
}
pub fn set_min_level_to_compress(&mut self, lvl: c_int) {
unsafe {
ffi::rocksdb_options_set_min_level_to_compress(self.inner, lvl);
}
}
pub fn set_report_bg_io_stats(&mut self, enable: bool) {
unsafe {
ffi::rocksdb_options_set_report_bg_io_stats(self.inner, enable as c_int);
}
}
pub fn set_max_total_wal_size(&mut self, size: u64) {
unsafe {
ffi::rocksdb_options_set_max_total_wal_size(self.inner, size);
}
}
pub fn set_wal_recovery_mode(&mut self, mode: DBRecoveryMode) {
unsafe {
ffi::rocksdb_options_set_wal_recovery_mode(self.inner, mode as c_int);
}
}
pub fn enable_statistics(&mut self) {
unsafe {
ffi::rocksdb_options_enable_statistics(self.inner);
}
}
pub fn get_statistics(&self) -> Option<String> {
unsafe {
let value = ffi::rocksdb_options_statistics_get_string(self.inner);
if value.is_null() {
return None;
}
let s = CStr::from_ptr(value).to_str().unwrap().to_owned();
ffi::rocksdb_free(value as *mut c_void);
Some(s)
}
}
pub fn set_stats_dump_period_sec(&mut self, period: c_uint) {
unsafe {
ffi::rocksdb_options_set_stats_dump_period_sec(self.inner, period);
}
}
pub fn set_stats_persist_period_sec(&mut self, period: c_uint) {
unsafe {
ffi::rocksdb_options_set_stats_persist_period_sec(self.inner, period);
}
}
pub fn set_advise_random_on_open(&mut self, advise: bool) {
unsafe {
ffi::rocksdb_options_set_advise_random_on_open(self.inner, advise as c_uchar);
}
}
pub fn set_use_adaptive_mutex(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_use_adaptive_mutex(self.inner, enabled as c_uchar);
}
}
pub fn set_num_levels(&mut self, n: c_int) {
unsafe {
ffi::rocksdb_options_set_num_levels(self.inner, n);
}
}
pub fn set_memtable_prefix_bloom_ratio(&mut self, ratio: f64) {
unsafe {
ffi::rocksdb_options_set_memtable_prefix_bloom_size_ratio(self.inner, ratio);
}
}
pub fn set_max_compaction_bytes(&mut self, nbytes: u64) {
unsafe {
ffi::rocksdb_options_set_max_compaction_bytes(self.inner, nbytes);
}
}
pub fn set_wal_dir<P: AsRef<Path>>(&mut self, path: P) {
let p = CString::new(path.as_ref().to_string_lossy().as_bytes()).unwrap();
unsafe {
ffi::rocksdb_options_set_wal_dir(self.inner, p.as_ptr());
}
}
pub fn set_wal_ttl_seconds(&mut self, secs: u64) {
unsafe {
ffi::rocksdb_options_set_WAL_ttl_seconds(self.inner, secs);
}
}
pub fn set_wal_size_limit_mb(&mut self, size: u64) {
unsafe {
ffi::rocksdb_options_set_WAL_size_limit_MB(self.inner, size);
}
}
pub fn set_manifest_preallocation_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_options_set_manifest_preallocation_size(self.inner, size);
}
}
pub fn set_skip_stats_update_on_db_open(&mut self, skip: bool) {
unsafe {
ffi::rocksdb_options_set_skip_stats_update_on_db_open(self.inner, skip as c_uchar);
}
}
pub fn set_keep_log_file_num(&mut self, nfiles: usize) {
unsafe {
ffi::rocksdb_options_set_keep_log_file_num(self.inner, nfiles);
}
}
pub fn set_allow_mmap_writes(&mut self, is_enabled: bool) {
unsafe {
ffi::rocksdb_options_set_allow_mmap_writes(self.inner, is_enabled as c_uchar);
}
}
pub fn set_allow_mmap_reads(&mut self, is_enabled: bool) {
unsafe {
ffi::rocksdb_options_set_allow_mmap_reads(self.inner, is_enabled as c_uchar);
}
}
pub fn set_manual_wal_flush(&mut self, is_enabled: bool) {
unsafe {
ffi::rocksdb_options_set_manual_wal_flush(self.inner, is_enabled as c_uchar);
}
}
pub fn set_atomic_flush(&mut self, atomic_flush: bool) {
unsafe {
ffi::rocksdb_options_set_atomic_flush(self.inner, atomic_flush as c_uchar);
}
}
pub fn set_row_cache(&mut self, cache: &Cache) {
unsafe {
ffi::rocksdb_options_set_row_cache(self.inner, cache.0.inner.as_ptr());
}
self.outlive.row_cache = Some(cache.clone());
}
pub fn set_ratelimiter(
&mut self,
rate_bytes_per_sec: i64,
refill_period_us: i64,
fairness: i32,
) {
unsafe {
let ratelimiter =
ffi::rocksdb_ratelimiter_create(rate_bytes_per_sec, refill_period_us, fairness);
ffi::rocksdb_options_set_ratelimiter(self.inner, ratelimiter);
}
}
pub fn set_max_log_file_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_options_set_max_log_file_size(self.inner, size);
}
}
pub fn set_log_file_time_to_roll(&mut self, secs: usize) {
unsafe {
ffi::rocksdb_options_set_log_file_time_to_roll(self.inner, secs);
}
}
pub fn set_recycle_log_file_num(&mut self, num: usize) {
unsafe {
ffi::rocksdb_options_set_recycle_log_file_num(self.inner, num);
}
}
pub fn set_soft_pending_compaction_bytes_limit(&mut self, limit: usize) {
unsafe {
ffi::rocksdb_options_set_soft_pending_compaction_bytes_limit(self.inner, limit);
}
}
pub fn set_hard_pending_compaction_bytes_limit(&mut self, limit: usize) {
unsafe {
ffi::rocksdb_options_set_hard_pending_compaction_bytes_limit(self.inner, limit);
}
}
pub fn set_arena_block_size(&mut self, size: usize) {
unsafe {
ffi::rocksdb_options_set_arena_block_size(self.inner, size);
}
}
pub fn set_dump_malloc_stats(&mut self, enabled: bool) {
unsafe {
ffi::rocksdb_options_set_dump_malloc_stats(self.inner, enabled as c_uchar);
}
}
pub fn set_memtable_whole_key_filtering(&mut self, whole_key_filter: bool) {
unsafe {
ffi::rocksdb_options_set_memtable_whole_key_filtering(
self.inner,
whole_key_filter as c_uchar,
);
}
}
}
impl Default for Options {
fn default() -> Self {
unsafe {
let opts = ffi::rocksdb_options_create();
assert!(!opts.is_null(), "Could not create RocksDB options");
Self {
inner: opts,
outlive: OptionsMustOutliveDB::default(),
}
}
}
}
impl FlushOptions {
pub fn new() -> FlushOptions {
FlushOptions::default()
}
pub fn set_wait(&mut self, wait: bool) {
unsafe {
ffi::rocksdb_flushoptions_set_wait(self.inner, wait as c_uchar);
}
}
}
impl Default for FlushOptions {
fn default() -> FlushOptions {
let flush_opts = unsafe { ffi::rocksdb_flushoptions_create() };
if flush_opts.is_null() {
panic!("Could not create RocksDB flush options");
}
FlushOptions { inner: flush_opts }
}
}
impl WriteOptions {
pub fn new() -> WriteOptions {
WriteOptions::default()
}
pub fn set_sync(&mut self, sync: bool) {
unsafe {
ffi::rocksdb_writeoptions_set_sync(self.inner, sync as c_uchar);
};
self.option_set_sync = Some(sync);
}
pub fn disable_wal(&mut self, disable: bool) {
unsafe {
ffi::rocksdb_writeoptions_disable_WAL(self.inner, disable as c_int);
}
self.option_disable_wal = Some(disable);
}
pub(crate) fn input_or_default(
input: Option<&WriteOptions>,
default_writeopts: &mut Option<WriteOptions>,
) -> Result<*mut ffi::rocksdb_writeoptions_t, Error> {
if default_writeopts.is_none() {
default_writeopts.replace(WriteOptions::default());
}
let wo_handle = input
.or(default_writeopts.as_ref())
.ok_or_else(|| Error::new("Unable to extract write options.".to_string()))?
.handle();
Ok(wo_handle)
}
}
impl Default for WriteOptions {
fn default() -> WriteOptions {
let write_opts = unsafe { ffi::rocksdb_writeoptions_create() };
if write_opts.is_null() {
panic!("Could not create RocksDB write options");
}
WriteOptions {
option_set_sync: None,
option_disable_wal: None,
inner: write_opts,
}
}
}
impl Clone for WriteOptions {
fn clone(&self) -> WriteOptions {
let mut ops = WriteOptions::default();
if let Some(set_sync) = self.option_set_sync {
ops.set_sync(set_sync);
};
if let Some(disable_wal) = self.option_disable_wal {
ops.disable_wal(disable_wal);
};
ops
}
}
impl ReadOptions {
pub fn fill_cache(&mut self, v: bool) {
unsafe {
ffi::rocksdb_readoptions_set_fill_cache(self.inner, v as c_uchar);
}
self.option_fill_cache = Some(v);
}
pub fn set_snapshot<T>(&mut self, snapshot: &T)
where
T: ConstHandle<ffi::rocksdb_snapshot_t>,
{
unsafe {
ffi::rocksdb_readoptions_set_snapshot(self.inner, snapshot.const_handle());
}
}
pub fn set_iterate_upper_bound<K: AsRef<[u8]>>(&mut self, key: K) {
self.option_set_iterate_upper_bound = Some(key.as_ref().to_vec());
let key = self.option_set_iterate_upper_bound.as_ref().unwrap();
unsafe {
ffi::rocksdb_readoptions_set_iterate_upper_bound(
self.inner,
key.as_ptr() as *const c_char,
key.len() as size_t,
);
}
}
pub fn set_iterate_lower_bound<K: AsRef<[u8]>>(&mut self, key: K) {
self.option_set_iterate_lower_bound = Some(key.as_ref().to_vec());
let key = self.option_set_iterate_lower_bound.as_ref().unwrap();
unsafe {
ffi::rocksdb_readoptions_set_iterate_upper_bound(
self.inner,
key.as_ptr() as *const c_char,
key.len() as size_t,
);
}
}
pub fn set_prefix_same_as_start(&mut self, v: bool) {
unsafe { ffi::rocksdb_readoptions_set_prefix_same_as_start(self.inner, v as c_uchar) }
self.option_set_prefix_same_as_start = Some(v);
}
pub fn set_total_order_seek(&mut self, v: bool) {
unsafe { ffi::rocksdb_readoptions_set_total_order_seek(self.inner, v as c_uchar) }
self.option_set_total_order_seek = Some(v);
}
pub fn set_readahead_size(&mut self, v: usize) {
unsafe {
ffi::rocksdb_readoptions_set_readahead_size(self.inner, v as size_t);
}
self.option_set_readahead_size = Some(v);
}
pub fn set_async_io(&mut self, v: bool) {
unsafe {
ffi::rocksdb_readoptions_set_async_io(self.inner, c_uchar::from(v));
}
}
pub fn input_or_default(
input: Option<&ReadOptions>,
default_readopts: &mut Option<ReadOptions>,
) -> Result<*mut ffi::rocksdb_readoptions_t, Error> {
if input.is_none() && default_readopts.is_none() {
default_readopts.replace(ReadOptions::default());
}
let ro_handle = input
.or(default_readopts.as_ref())
.ok_or_else(|| Error::new("Unable to extract read options.".to_string()))?
.handle();
if ro_handle.is_null() {
return Err(Error::new(
"Unable to create RocksDB read options. \
This is a fairly trivial call, and its \
failure may be indicative of a \
mis-compiled or mis-loaded RocksDB \
library."
.to_string(),
));
}
Ok(ro_handle)
}
}
impl Default for ReadOptions {
fn default() -> ReadOptions {
unsafe {
ReadOptions {
option_fill_cache: None,
option_set_iterate_upper_bound: None,
option_set_iterate_lower_bound: None,
option_set_prefix_same_as_start: None,
option_set_total_order_seek: None,
option_set_readahead_size: None,
inner: ffi::rocksdb_readoptions_create(),
}
}
}
}
impl Clone for ReadOptions {
fn clone(&self) -> ReadOptions {
let mut ops = ReadOptions::default();
if let Some(fill_cache) = self.option_fill_cache {
ops.fill_cache(fill_cache);
};
if let Some(set_iterate_upper_bound) = &self.option_set_iterate_upper_bound {
ops.set_iterate_upper_bound(set_iterate_upper_bound);
};
if let Some(set_iterate_lower_bound) = &self.option_set_iterate_lower_bound {
ops.set_iterate_lower_bound(set_iterate_lower_bound);
};
if let Some(set_prefix_same_as_start) = self.option_set_prefix_same_as_start {
ops.set_prefix_same_as_start(set_prefix_same_as_start);
};
if let Some(set_total_order_seek) = self.option_set_total_order_seek {
ops.set_total_order_seek(set_total_order_seek);
};
if let Some(set_readahead_size) = self.option_set_readahead_size {
ops.set_readahead_size(set_readahead_size)
};
ops
}
}
impl IngestExternalFileOptions {
pub fn set_move_files(&mut self, v: bool) {
unsafe {
ffi::rocksdb_ingestexternalfileoptions_set_move_files(self.inner, v as c_uchar);
}
}
pub fn set_snapshot_consistency(&mut self, v: bool) {
unsafe {
ffi::rocksdb_ingestexternalfileoptions_set_snapshot_consistency(
self.inner,
v as c_uchar,
);
}
}
pub fn set_allow_global_seqno(&mut self, v: bool) {
unsafe {
ffi::rocksdb_ingestexternalfileoptions_set_allow_global_seqno(self.inner, v as c_uchar);
}
}
pub fn set_allow_blocking_flush(&mut self, v: bool) {
unsafe {
ffi::rocksdb_ingestexternalfileoptions_set_allow_blocking_flush(
self.inner,
v as c_uchar,
);
}
}
pub fn set_ingest_behind(&mut self, v: bool) {
unsafe {
ffi::rocksdb_ingestexternalfileoptions_set_ingest_behind(self.inner, v as c_uchar);
}
}
pub fn input_or_default(
input: Option<&IngestExternalFileOptions>,
default_opts: &mut Option<IngestExternalFileOptions>,
) -> Result<*mut ffi::rocksdb_ingestexternalfileoptions_t, Error> {
if input.is_none() && default_opts.is_none() {
default_opts.replace(IngestExternalFileOptions::default());
}
let handle = input
.or(default_opts.as_ref())
.ok_or_else(|| {
Error::new("Unable to extract ingest external file options.".to_string())
})?
.handle();
if handle.is_null() {
return Err(Error::new(
"Unable to create RocksDB ingest external file options. \
This is a fairly trivial call, and its \
failure may be indicative of a \
mis-compiled or mis-loaded RocksDB \
library."
.to_string(),
));
}
Ok(handle)
}
}
impl Default for IngestExternalFileOptions {
fn default() -> Self {
unsafe {
Self {
inner: ffi::rocksdb_ingestexternalfileoptions_create(),
}
}
}
}
pub enum BlockBasedIndexType {
BinarySearch,
HashSearch,
TwoLevelIndexSearch,
}
#[repr(C)]
pub enum DataBlockIndexType {
BinarySearch = 0,
BinaryAndHash = 1,
}
pub enum MemtableFactory {
Vector,
HashSkipList {
bucket_count: usize,
height: i32,
branching_factor: i32,
},
HashLinkList {
bucket_count: usize,
},
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub enum KeyEncodingType {
#[default]
Plain = 0,
Prefix = 1,
}
pub struct PlainTableFactoryOptions {
pub user_key_length: u32,
pub bloom_bits_per_key: i32,
pub hash_table_ratio: f64,
pub index_sparseness: usize,
pub huge_page_tlb_size: usize,
pub encoding_type: KeyEncodingType,
pub full_scan_mode: bool,
pub store_index_in_file: bool,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DBCompressionType {
None = ffi::rocksdb_no_compression as isize,
Snappy = ffi::rocksdb_snappy_compression as isize,
Zlib = ffi::rocksdb_zlib_compression as isize,
Bz2 = ffi::rocksdb_bz2_compression as isize,
Lz4 = ffi::rocksdb_lz4_compression as isize,
Lz4hc = ffi::rocksdb_lz4hc_compression as isize,
Zstd = ffi::rocksdb_zstd_compression as isize,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DBCompactionStyle {
Level = ffi::rocksdb_level_compaction as isize,
Universal = ffi::rocksdb_universal_compaction as isize,
Fifo = ffi::rocksdb_fifo_compaction as isize,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DBRecoveryMode {
TolerateCorruptedTailRecords = ffi::rocksdb_tolerate_corrupted_tail_records_recovery as isize,
AbsoluteConsistency = ffi::rocksdb_absolute_consistency_recovery as isize,
PointInTime = ffi::rocksdb_point_in_time_recovery as isize,
SkipAnyCorruptedRecord = ffi::rocksdb_skip_any_corrupted_records_recovery as isize,
}
pub struct FifoCompactOptions {
pub(crate) inner: *mut ffi::rocksdb_fifo_compaction_options_t,
}
impl Default for FifoCompactOptions {
fn default() -> Self {
let opts = unsafe { ffi::rocksdb_fifo_compaction_options_create() };
assert!(
!opts.is_null(),
"Could not create RocksDB Fifo Compaction Options"
);
Self { inner: opts }
}
}
impl Drop for FifoCompactOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_fifo_compaction_options_destroy(self.inner);
}
}
}
impl FifoCompactOptions {
pub fn set_max_table_files_size(&mut self, nbytes: u64) {
unsafe {
ffi::rocksdb_fifo_compaction_options_set_max_table_files_size(self.inner, nbytes);
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
pub enum UniversalCompactionStopStyle {
Similar = ffi::rocksdb_similar_size_compaction_stop_style as isize,
Total = ffi::rocksdb_total_size_compaction_stop_style as isize,
}
pub struct UniversalCompactOptions {
pub(crate) inner: *mut ffi::rocksdb_universal_compaction_options_t,
}
impl Default for UniversalCompactOptions {
fn default() -> Self {
let opts = unsafe { ffi::rocksdb_universal_compaction_options_create() };
assert!(
!opts.is_null(),
"Could not create RocksDB Universal Compaction Options"
);
Self { inner: opts }
}
}
impl Drop for UniversalCompactOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_universal_compaction_options_destroy(self.inner);
}
}
}
impl UniversalCompactOptions {
pub fn set_size_ratio(&mut self, ratio: c_int) {
unsafe {
ffi::rocksdb_universal_compaction_options_set_size_ratio(self.inner, ratio);
}
}
pub fn set_min_merge_width(&mut self, num: c_int) {
unsafe {
ffi::rocksdb_universal_compaction_options_set_min_merge_width(self.inner, num);
}
}
pub fn set_max_merge_width(&mut self, num: c_int) {
unsafe {
ffi::rocksdb_universal_compaction_options_set_max_merge_width(self.inner, num);
}
}
pub fn set_max_size_amplification_percent(&mut self, v: c_int) {
unsafe {
ffi::rocksdb_universal_compaction_options_set_max_size_amplification_percent(
self.inner, v,
);
}
}
pub fn set_compression_size_percent(&mut self, v: c_int) {
unsafe {
ffi::rocksdb_universal_compaction_options_set_compression_size_percent(self.inner, v);
}
}
pub fn set_stop_style(&mut self, style: UniversalCompactionStopStyle) {
unsafe {
ffi::rocksdb_universal_compaction_options_set_stop_style(self.inner, style as c_int);
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
#[repr(u8)]
pub enum BottommostLevelCompaction {
Skip = 0,
IfHaveCompactionFilter,
Force,
ForceOptimized,
}
pub struct CompactOptions {
pub(crate) inner: *mut ffi::rocksdb_compactoptions_t,
}
impl Default for CompactOptions {
fn default() -> Self {
let opts = unsafe { ffi::rocksdb_compactoptions_create() };
assert!(!opts.is_null(), "Could not create RocksDB Compact Options");
Self { inner: opts }
}
}
impl Drop for CompactOptions {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_compactoptions_destroy(self.inner);
}
}
}
impl CompactOptions {
pub fn set_exclusive_manual_compaction(&mut self, v: bool) {
unsafe {
ffi::rocksdb_compactoptions_set_exclusive_manual_compaction(self.inner, v as c_uchar);
}
}
pub fn set_bottommost_level_compaction(&mut self, lvl: BottommostLevelCompaction) {
unsafe {
ffi::rocksdb_compactoptions_set_bottommost_level_compaction(self.inner, lvl as c_uchar);
}
}
pub fn set_change_level(&mut self, v: bool) {
unsafe {
ffi::rocksdb_compactoptions_set_change_level(self.inner, v as c_uchar);
}
}
pub fn set_target_level(&mut self, lvl: c_int) {
unsafe {
ffi::rocksdb_compactoptions_set_target_level(self.inner, lvl);
}
}
}
pub struct DBPath {
pub(crate) inner: *mut ffi::rocksdb_dbpath_t,
}
impl DBPath {
pub fn new<P: AsRef<Path>>(path: P, target_size: u64) -> Result<Self, Error> {
let p = CString::new(path.as_ref().to_string_lossy().as_bytes()).unwrap();
let dbpath = unsafe { ffi::rocksdb_dbpath_create(p.as_ptr(), target_size) };
if dbpath.is_null() {
Err(Error::new(format!(
"Could not create path for storing sst files at location: {}",
path.as_ref().to_string_lossy()
)))
} else {
Ok(DBPath { inner: dbpath })
}
}
}
impl Drop for DBPath {
fn drop(&mut self) {
unsafe {
ffi::rocksdb_dbpath_destroy(self.inner);
}
}
}
impl ConstHandle<ffi::rocksdb_options_t> for Options {
fn const_handle(&self) -> *const ffi::rocksdb_options_t {
self.inner
}
}
impl Handle<ffi::rocksdb_options_t> for Options {
fn handle(&self) -> *mut ffi::rocksdb_options_t {
self.inner
}
}
impl Handle<ffi::rocksdb_readoptions_t> for ReadOptions {
fn handle(&self) -> *mut ffi::rocksdb_readoptions_t {
self.inner
}
}
impl Handle<ffi::rocksdb_writeoptions_t> for WriteOptions {
fn handle(&self) -> *mut ffi::rocksdb_writeoptions_t {
self.inner
}
}
impl Handle<ffi::rocksdb_ingestexternalfileoptions_t> for IngestExternalFileOptions {
fn handle(&self) -> *mut ffi::rocksdb_ingestexternalfileoptions_t {
self.inner
}
}
#[cfg(test)]
mod tests {
use crate::{MemtableFactory, Options};
#[test]
fn test_enable_statistics() {
let mut opts = Options::default();
opts.enable_statistics();
opts.set_stats_dump_period_sec(60);
assert!(opts.get_statistics().is_some());
let opts = Options::default();
assert!(opts.get_statistics().is_none());
}
#[test]
fn test_set_memtable_factory() {
let mut opts = Options::default();
opts.set_memtable_factory(MemtableFactory::Vector);
opts.set_memtable_factory(MemtableFactory::HashLinkList { bucket_count: 100 });
opts.set_memtable_factory(MemtableFactory::HashSkipList {
bucket_count: 100,
height: 4,
branching_factor: 4,
});
}
#[test]
fn test_set_stats_persist_period_sec() {
let mut opts = Options::default();
opts.enable_statistics();
opts.set_stats_persist_period_sec(5);
assert!(opts.get_statistics().is_some());
let opts = Options::default();
assert!(opts.get_statistics().is_none());
}
}