use crate::binding::*;
use crate::database::cache::Cache;
#[cfg(feature = "experimental-extension")]
use crate::database::cache::FlatT3CacheConfig;
use crate::database::comparator::{Comparator, RawComparator};
use crate::database::filter_policy::{
BloomFilterPolicy, CustomFilterPolicy, FilterPolicy, LevelDBFilterPolicy,
};
use crate::database::snapshots::Snapshot;
use libc::{c_int, size_t};
#[cfg(feature = "experimental-extension")]
use crate::extension::logger::{LogHandler, Logger, OpaqueLogger};
#[repr(C)]
#[derive(Copy, Clone)]
pub enum Compression {
No = 0,
Snappy = 1,
Zstd = 2,
}
pub struct Options {
pub create_if_missing: bool,
pub error_if_exists: bool,
pub paranoid_checks: bool,
pub write_buffer_size: Option<size_t>,
pub max_open_files: Option<i32>,
pub block_size: Option<size_t>,
pub block_restart_interval: Option<i32>,
pub max_file_size: Option<size_t>,
pub compression: Compression,
pub cache: Option<Cache>,
pub comparator: Option<RawComparator>,
pub filter_policy: Option<Box<dyn LevelDBFilterPolicy>>,
#[cfg(feature = "experimental-extension")]
pub logger: Option<OpaqueLogger>,
}
impl Default for Options {
fn default() -> Self {
Self::new()
}
}
impl Options {
pub fn new() -> Options {
Options {
create_if_missing: false,
error_if_exists: false,
paranoid_checks: false,
write_buffer_size: None,
max_open_files: None,
block_size: None,
block_restart_interval: None,
max_file_size: None,
compression: Compression::No,
cache: None,
comparator: None,
filter_policy: None,
#[cfg(feature = "experimental-extension")]
logger: None,
}
}
pub fn set_comparator<C: Comparator>(&mut self, comparator: C) {
self.comparator = Some(RawComparator::new(comparator));
}
pub fn set_bloom_filter(&mut self, bits_per_key: i32) {
let filter_ptr = BloomFilterPolicy::new(bits_per_key);
self.filter_policy = Some(Box::new(filter_ptr));
}
pub fn set_filter_policy<T: FilterPolicy + 'static>(&mut self, policy: T) {
let custom_policy = CustomFilterPolicy::new(policy);
self.filter_policy = Some(Box::new(custom_policy));
}
#[cfg(feature = "experimental-extension")]
#[deprecated(since = "2.2.0", note = "Use set_log_handler instead")]
pub fn set_logger<H: LogHandler + Send + Sync + 'static>(&mut self, logger: Logger<H>) {
let mut opaque_logger = logger.into_opaque();
opaque_logger.initialize();
self.logger = Some(opaque_logger);
}
#[cfg(feature = "experimental-extension")]
pub fn set_log_handler<H: LogHandler + Send + Sync + 'static>(&mut self, handler: H) {
let logger = Logger::new(handler);
let mut opaque_logger = logger.into_opaque();
opaque_logger.initialize();
self.logger = Some(opaque_logger);
}
#[allow(deprecated)]
pub fn set_builtin_lru_cache(&mut self, capacity: size_t) {
self.cache = Some(Cache::new(capacity));
}
#[cfg(feature = "experimental-extension")]
#[allow(deprecated)]
pub fn set_flat_t3_cache(&mut self, config: FlatT3CacheConfig) {
self.cache = Some(Cache::new_flat_t3_cache(config));
}
}
#[derive(Copy, Clone)]
pub struct WriteOptions {
pub sync: bool,
}
impl Default for WriteOptions {
fn default() -> Self {
Self::new()
}
}
impl WriteOptions {
pub fn new() -> WriteOptions {
WriteOptions { sync: false }
}
}
#[allow(missing_copy_implementations)]
pub struct ReadOptions<'a> {
pub verify_checksums: bool,
pub fill_cache: bool,
pub snapshot: Option<&'a Snapshot<'a>>,
}
impl<'a> Default for ReadOptions<'a> {
fn default() -> Self {
Self::new()
}
}
impl<'a> ReadOptions<'a> {
pub fn new() -> ReadOptions<'a> {
ReadOptions {
verify_checksums: false,
fill_cache: true,
snapshot: None,
}
}
}
pub(crate) unsafe fn c_options(options: &Options) -> *mut leveldb_options_t {
unsafe {
let c_options = leveldb_options_create();
leveldb_options_set_create_if_missing(c_options, options.create_if_missing as u8);
leveldb_options_set_error_if_exists(c_options, options.error_if_exists as u8);
leveldb_options_set_paranoid_checks(c_options, options.paranoid_checks as u8);
if let Some(wbs) = options.write_buffer_size {
leveldb_options_set_write_buffer_size(c_options, wbs);
}
if let Some(mf) = options.max_open_files {
leveldb_options_set_max_open_files(c_options, mf);
}
if let Some(bs) = options.block_size {
leveldb_options_set_block_size(c_options, bs);
}
if let Some(bi) = options.block_restart_interval {
leveldb_options_set_block_restart_interval(c_options, bi);
}
if let Some(mfs) = options.max_file_size {
leveldb_options_set_max_file_size(c_options, mfs);
}
leveldb_options_set_compression(c_options, options.compression as c_int);
if let Some(ref c) = options.comparator {
leveldb_options_set_comparator(c_options, c.raw_ptr());
}
if let Some(ref cache) = options.cache {
leveldb_options_set_cache(c_options, cache.raw_ptr());
}
if let Some(ref fp) = options.filter_policy {
leveldb_options_set_filter_policy(c_options, fp.raw_ptr());
}
#[cfg(feature = "experimental-extension")]
if let Some(ref logger) = options.logger {
leveldb_options_set_info_log(c_options, logger.raw_ptr());
}
c_options
}
}
pub(crate) unsafe fn c_writeoptions(options: WriteOptions) -> *mut leveldb_writeoptions_t {
unsafe {
let c_writeoptions = leveldb_writeoptions_create();
leveldb_writeoptions_set_sync(c_writeoptions, options.sync as u8);
c_writeoptions
}
}
pub(crate) unsafe fn c_readoptions<'a>(options: &ReadOptions<'a>) -> *mut leveldb_readoptions_t {
unsafe {
let c_readoptions = leveldb_readoptions_create();
leveldb_readoptions_set_verify_checksums(c_readoptions, options.verify_checksums as u8);
leveldb_readoptions_set_fill_cache(c_readoptions, options.fill_cache as u8);
if let Some(snapshot) = options.snapshot {
leveldb_readoptions_set_snapshot(c_readoptions, snapshot.raw_ptr());
}
c_readoptions
}
}