rusty_leveldb_arc/
options.rs

1use crate::block::Block;
2use crate::cache::Cache;
3use crate::cmp::{Cmp, DefaultCmp};
4use crate::compressor::{self, Compressor, CompressorId};
5use crate::env::Env;
6use crate::infolog::{self, Logger};
7use crate::mem_env::MemEnv;
8use crate::types::{share, Shared};
9use crate::{disk_env, Result};
10use crate::{filter, Status, StatusCode};
11
12use std::default::Default;
13use std::sync::Arc;
14
15const KB: usize = 1 << 10;
16const MB: usize = KB * KB;
17
18const BLOCK_MAX_SIZE: usize = 4 * KB;
19const BLOCK_CACHE_CAPACITY: usize = 8 * MB;
20const WRITE_BUFFER_SIZE: usize = 4 * MB;
21const DEFAULT_BITS_PER_KEY: u32 = 10; // NOTE: This may need to be optimized.
22
23/// Options contains general parameters for a LevelDB instance. Most of the names are
24/// self-explanatory; the defaults are defined in the `Default` implementation.
25#[derive(Clone)]
26pub struct Options {
27    pub cmp: Arc<Box<dyn Cmp>>,
28    pub env: Arc<Box<dyn Env>>,
29    pub log: Option<Shared<Logger>>,
30    pub create_if_missing: bool,
31    pub error_if_exists: bool,
32    pub paranoid_checks: bool,
33    pub write_buffer_size: usize,
34    pub max_open_files: usize,
35    pub max_file_size: usize,
36    pub block_cache: Shared<Cache<Block>>,
37    pub block_size: usize,
38    pub block_restart_interval: usize,
39    /// Compressor id in compressor list
40    ///
41    /// Note: you have to open a database with the same compression type as it was written to, in
42    /// order to not lose data! (this is a bug and will be fixed)
43    pub compressor: u8,
44
45    pub compressor_list: Arc<CompressorList>,
46    pub reuse_logs: bool,
47    pub reuse_manifest: bool,
48    pub filter_policy: filter::BoxedFilterPolicy,
49}
50
51impl Default for Options {
52    fn default() -> Options {
53        Options {
54            cmp: Arc::new(Box::new(DefaultCmp)),
55            env: Arc::new(Box::new(disk_env::PosixDiskEnv::new())),
56            log: None,
57            create_if_missing: true,
58            error_if_exists: false,
59            paranoid_checks: false,
60            write_buffer_size: WRITE_BUFFER_SIZE,
61            max_open_files: 1 << 10,
62            max_file_size: 2 << 20,
63            // 2000 elements by default
64            block_cache: share(Cache::new(BLOCK_CACHE_CAPACITY / BLOCK_MAX_SIZE)),
65            block_size: BLOCK_MAX_SIZE,
66            block_restart_interval: 16,
67            reuse_logs: true,
68            reuse_manifest: true,
69            compressor: 0,
70            compressor_list: Arc::new(CompressorList::default()),
71            filter_policy: Arc::new(Box::new(filter::BloomPolicy::new(DEFAULT_BITS_PER_KEY))),
72        }
73    }
74}
75
76/// Customize compressor method for leveldb
77///
78/// `Default` value is like the code below
79/// ```
80/// # use rusty_leveldb_arc::{compressor, CompressorList};
81/// let mut list = CompressorList::new();
82/// list.set(compressor::NoneCompressor);
83/// list.set(compressor::SnappyCompressor);
84/// ```
85pub struct CompressorList([Option<Box<dyn Compressor>>; 256]);
86
87impl CompressorList {
88    /// Create a **Empty** compressor list
89    pub fn new() -> Self {
90        const INIT: Option<Box<dyn Compressor>> = None;
91        Self([INIT; 256])
92    }
93
94    /// Set compressor with the id in `CompressorId` trait
95    pub fn set<T>(&mut self, compressor: T)
96    where
97        T: Compressor + CompressorId + 'static,
98    {
99        self.set_with_id(T::ID, compressor)
100    }
101
102    /// Set compressor with id
103    pub fn set_with_id(&mut self, id: u8, compressor: impl Compressor + 'static) {
104        self.0[id as usize] = Some(Box::new(compressor));
105    }
106
107    pub fn is_set(&self, id: u8) -> bool {
108        self.0[id as usize].is_some()
109    }
110
111    pub fn get(&self, id: u8) -> Result<&Box<dyn Compressor + 'static>> {
112        self.0[id as usize].as_ref().ok_or_else(|| Status {
113            code: StatusCode::NotSupported,
114            err: format!("invalid compression id `{}`", id),
115        })
116    }
117}
118
119impl Default for CompressorList {
120    fn default() -> Self {
121        let mut list = Self::new();
122        list.set(compressor::NoneCompressor);
123        list.set(compressor::SnappyCompressor);
124        list
125    }
126}
127
128/// Returns Options that will cause a database to exist purely in-memory instead of being stored on
129/// disk. This is useful for testing or ephemeral databases.
130pub fn in_memory() -> Options {
131    let mut opt = Options::default();
132    opt.env = Arc::new(Box::new(MemEnv::new()));
133    opt
134}
135
136pub fn for_test() -> Options {
137    let mut o = Options::default();
138    o.env = Arc::new(Box::new(MemEnv::new()));
139    o.log = Some(share(infolog::stderr()));
140    o
141}