1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//! All the option types needed for interfacing with leveldb.
//!
//! Those are:
//! * `Options`: used when opening a database
//! * `ReadOptions`: used when reading from leveldb
//! * `WriteOptions`: used when writng to leveldb
use leveldb_sys::*;

use libc::size_t;
use database::snapshots::Snapshot;
use database::cache::Cache;

/// Options to consider when opening a new or pre-existing database.
///
/// Note that in contrast to the leveldb C API, the Comparator is not
/// passed using this structure.
///
/// For more detailed explanations, consider the
/// [leveldb documentation](https://github.com/google/leveldb/tree/master/doc)
pub struct Options {
    /// create the database if missing
    ///
    /// default: false
    pub create_if_missing: bool,
    /// report an error if the DB already exists instead of opening.
    ///
    /// default: false
    pub error_if_exists: bool,
    /// paranoid checks make the database report an error as soon as
    /// corruption is detected.
    ///
    /// default: false
    pub paranoid_checks: bool,
    /// Override the size of the write buffer to use.
    ///
    /// default: None
    pub write_buffer_size: Option<size_t>,
    /// Override the max number of open files.
    ///
    /// default: None
    pub max_open_files: Option<i32>,
    /// Override the size of the blocks leveldb uses for writing and caching.
    ///
    /// default: None
    pub block_size: Option<size_t>,
    /// Override the interval between restart points.
    ///
    /// default: None
    pub block_restart_interval: Option<i32>,
    /// Define whether leveldb should write compressed or not.
    ///
    /// default: Compression::No
    pub compression: Compression,
    /// A cache to use during read operations.
    ///
    /// default: None
    pub cache: Option<Cache>,
}

impl Options {
    /// Create a new `Options` struct with default settings.
    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,
            compression: Compression::No,
            cache: None,
        }
    }
}

impl Default for Options {
    fn default() -> Options {
        Options::new()
    }
}

/// The write options to use for a write operation.
#[derive(Copy, Clone)]
pub struct WriteOptions {
    /// `fsync` before acknowledging a write operation.
    ///
    /// default: false
    pub sync: bool,
}

impl WriteOptions {
    /// Return a new `WriteOptions` struct with default settings.
    pub fn new() -> WriteOptions {
        WriteOptions { sync: false }
    }
}

impl Default for WriteOptions {
    fn default() -> WriteOptions {
        WriteOptions::new()
    }
}

/// The read options to use for any read operation.
#[allow(missing_copy_implementations)]
pub struct ReadOptions<'a> {
    /// Whether to verify the saved checksums on read.
    ///
    /// default: false
    pub verify_checksums: bool,
    /// Whether to fill the internal cache with the
    /// results of the read.
    ///
    /// default: true
    pub fill_cache: bool,
    /// An optional snapshot to base this operation on.
    ///
    /// Consider using the `Snapshot` trait instead of setting
    /// this yourself.
    ///
    /// default: None
    pub snapshot: Option<&'a Snapshot<'a>>,
}

impl<'a> ReadOptions<'a> {
    /// Return a `ReadOptions` struct with the default values.
    pub fn new() -> ReadOptions<'a> {
        ReadOptions {
            verify_checksums: false,
            fill_cache: true,
            snapshot: None,
        }
    }
}

#[allow(missing_docs)]
pub unsafe fn c_options(options: &Options,
                        comparator: Option<*mut leveldb_comparator_t>)
                        -> *mut leveldb_options_t {
    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);
    }
    leveldb_options_set_compression(c_options, options.compression);
    if let Some(c) = comparator {
        leveldb_options_set_comparator(c_options, c);
    }
    if let Some(ref cache) = options.cache {
        leveldb_options_set_cache(c_options, cache.raw_ptr());
    }
    c_options
}

#[allow(missing_docs)]
pub unsafe fn c_writeoptions(options: WriteOptions) -> *mut leveldb_writeoptions_t {
    let c_writeoptions = leveldb_writeoptions_create();
    leveldb_writeoptions_set_sync(c_writeoptions, options.sync as u8);
    c_writeoptions
}

#[allow(missing_docs)]
pub unsafe fn c_readoptions(options: &ReadOptions) -> *mut leveldb_readoptions_t {
    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
}