mappum_rocksdb/lib.rs
1// Copyright 2014 Tyler Neely
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15
16//! Rust wrapper for RocksDB.
17//!
18//! # Examples
19//!
20//! ```
21//! use rocksdb::{DB, Options};
22//! // NB: db is automatically closed at end of lifetime
23//! let path = "_path_for_rocksdb_storage";
24//! {
25//! let db = DB::open_default(path).unwrap();
26//! db.put(b"my key", b"my value").unwrap();
27//! match db.get(b"my key") {
28//! Ok(Some(value)) => println!("retrieved value {}", String::from_utf8(value).unwrap()),
29//! Ok(None) => println!("value not found"),
30//! Err(e) => println!("operational problem encountered: {}", e),
31//! }
32//! db.delete(b"my key").unwrap();
33//! }
34//! let _ = DB::destroy(&Options::default(), path);
35//! ```
36//!
37//! Opening a database and a single column family with custom options:
38//!
39//! ```
40//! use rocksdb::{DB, ColumnFamilyDescriptor, Options};
41//!
42//! let path = "_path_for_rocksdb_storage_with_cfs";
43//! let mut cf_opts = Options::default();
44//! cf_opts.set_max_write_buffer_number(16);
45//! let cf = ColumnFamilyDescriptor::new("cf1", cf_opts);
46//!
47//! let mut db_opts = Options::default();
48//! db_opts.create_missing_column_families(true);
49//! db_opts.create_if_missing(true);
50//! {
51//! let db = DB::open_cf_descriptors(&db_opts, path, vec![cf]).unwrap();
52//! }
53//! let _ = DB::destroy(&db_opts, path);
54//! ```
55//!
56
57#[macro_use]
58mod ffi_util;
59
60pub mod backup;
61pub mod checkpoint;
62pub mod compaction_filter;
63mod comparator;
64mod db;
65mod db_options;
66pub mod merge_operator;
67mod slice_transform;
68
69pub use crate::{
70 compaction_filter::Decision as CompactionDecision,
71 db::{
72 DBCompactionStyle, DBCompressionType, DBIterator, DBPinnableSlice, DBRawIterator,
73 DBRecoveryMode, DBWALIterator, Direction, IteratorMode, ReadOptions, Snapshot, WriteBatch,
74 WriteBatchIterator,
75 },
76 merge_operator::MergeOperands,
77 slice_transform::SliceTransform,
78};
79
80use librocksdb_sys as ffi;
81
82use std::collections::BTreeMap;
83use std::error;
84use std::fmt;
85use std::path::PathBuf;
86
87/// A RocksDB database.
88///
89/// See crate level documentation for a simple usage example.
90pub struct DB {
91 inner: *mut ffi::rocksdb_t,
92 cfs: BTreeMap<String, ColumnFamily>,
93 path: PathBuf,
94}
95
96/// A descriptor for a RocksDB column family.
97///
98/// A description of the column family, containing the name and `Options`.
99pub struct ColumnFamilyDescriptor {
100 name: String,
101 options: Options,
102}
103
104/// A simple wrapper round a string, used for errors reported from
105/// ffi calls.
106#[derive(Debug, Clone, PartialEq)]
107pub struct Error {
108 message: String,
109}
110
111impl Error {
112 fn new(message: String) -> Error {
113 Error { message }
114 }
115
116 pub fn into_string(self) -> String {
117 self.into()
118 }
119}
120
121impl AsRef<str> for Error {
122 fn as_ref(&self) -> &str {
123 &self.message
124 }
125}
126
127impl From<Error> for String {
128 fn from(e: Error) -> String {
129 e.message
130 }
131}
132
133impl error::Error for Error {
134 fn description(&self) -> &str {
135 &self.message
136 }
137}
138
139impl fmt::Display for Error {
140 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
141 self.message.fmt(formatter)
142 }
143}
144
145/// For configuring block-based file storage.
146pub struct BlockBasedOptions {
147 inner: *mut ffi::rocksdb_block_based_table_options_t,
148}
149
150/// Used by BlockBasedOptions::set_index_type.
151pub enum BlockBasedIndexType {
152 /// A space efficient index block that is optimized for
153 /// binary-search-based index.
154 BinarySearch,
155
156 /// The hash index, if enabled, will perform a hash lookup if
157 /// a prefix extractor has been provided through Options::set_prefix_extractor.
158 HashSearch,
159
160 /// A two-level index implementation. Both levels are binary search indexes.
161 TwoLevelIndexSearch,
162}
163
164/// Defines the underlying memtable implementation.
165/// See https://github.com/facebook/rocksdb/wiki/MemTable for more information.
166pub enum MemtableFactory {
167 Vector,
168 HashSkipList {
169 bucket_count: usize,
170 height: i32,
171 branching_factor: i32,
172 },
173 HashLinkList {
174 bucket_count: usize,
175 },
176}
177
178/// Used with DBOptions::set_plain_table_factory.
179/// See https://github.com/facebook/rocksdb/wiki/PlainTable-Format.
180///
181/// Defaults:
182/// user_key_length: 0 (variable length)
183/// bloom_bits_per_key: 10
184/// hash_table_ratio: 0.75
185/// index_sparseness: 16
186pub struct PlainTableFactoryOptions {
187 pub user_key_length: u32,
188 pub bloom_bits_per_key: i32,
189 pub hash_table_ratio: f64,
190 pub index_sparseness: usize,
191}
192
193/// Database-wide options around performance and behavior.
194///
195/// Please read [the official tuning guide](https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide), and most importantly, measure performance under realistic workloads with realistic hardware.
196///
197/// # Examples
198///
199/// ```
200/// use rocksdb::{Options, DB};
201/// use rocksdb::DBCompactionStyle;
202///
203/// fn badly_tuned_for_somebody_elses_disk() -> DB {
204/// let path = "path/for/rocksdb/storageX";
205/// let mut opts = Options::default();
206/// opts.create_if_missing(true);
207/// opts.set_max_open_files(10000);
208/// opts.set_use_fsync(false);
209/// opts.set_bytes_per_sync(8388608);
210/// opts.optimize_for_point_lookup(1024);
211/// opts.set_table_cache_num_shard_bits(6);
212/// opts.set_max_write_buffer_number(32);
213/// opts.set_write_buffer_size(536870912);
214/// opts.set_target_file_size_base(1073741824);
215/// opts.set_min_write_buffer_number_to_merge(4);
216/// opts.set_level_zero_stop_writes_trigger(2000);
217/// opts.set_level_zero_slowdown_writes_trigger(0);
218/// opts.set_compaction_style(DBCompactionStyle::Universal);
219/// opts.set_max_background_compactions(4);
220/// opts.set_max_background_flushes(4);
221/// opts.set_disable_auto_compactions(true);
222///
223/// DB::open(&opts, path).unwrap()
224/// }
225/// ```
226pub struct Options {
227 inner: *mut ffi::rocksdb_options_t,
228}
229
230/// Optionally wait for the memtable flush to be performed.
231///
232/// # Examples
233///
234/// Manually flushing the memtable:
235///
236/// ```
237/// use rocksdb::{DB, Options, FlushOptions};
238///
239/// let path = "_path_for_rocksdb_storageY";
240/// {
241/// let db = DB::open_default(path).unwrap();
242///
243/// let mut flush_options = FlushOptions::default();
244/// flush_options.set_wait(true);
245///
246/// db.flush_opt(&flush_options);
247/// }
248/// let _ = DB::destroy(&Options::default(), path);
249/// ```
250pub struct FlushOptions {
251 inner: *mut ffi::rocksdb_flushoptions_t,
252}
253
254/// Optionally disable WAL or sync for this write.
255///
256/// # Examples
257///
258/// Making an unsafe write of a batch:
259///
260/// ```
261/// use rocksdb::{DB, Options, WriteBatch, WriteOptions};
262///
263/// let path = "_path_for_rocksdb_storageY";
264/// {
265/// let db = DB::open_default(path).unwrap();
266/// let mut batch = WriteBatch::default();
267/// batch.put(b"my key", b"my value");
268/// batch.put(b"key2", b"value2");
269/// batch.put(b"key3", b"value3");
270///
271/// let mut write_options = WriteOptions::default();
272/// write_options.set_sync(false);
273/// write_options.disable_wal(true);
274///
275/// db.write_opt(batch, &write_options);
276/// }
277/// let _ = DB::destroy(&Options::default(), path);
278/// ```
279pub struct WriteOptions {
280 inner: *mut ffi::rocksdb_writeoptions_t,
281}
282
283/// An opaque type used to represent a column family. Returned from some functions, and used
284/// in others
285pub struct ColumnFamily {
286 inner: *mut ffi::rocksdb_column_family_handle_t,
287}
288
289unsafe impl Send for ColumnFamily {}
290
291#[cfg(test)]
292mod test {
293 use super::*;
294
295 #[test]
296 fn is_send() {
297 // test (at compile time) that certain types implement the auto-trait Send, either directly for
298 // pointer-wrapping types or transitively for types with all Send fields
299
300 fn is_send<T: Send>() {
301 // dummy function just used for its parameterized type bound
302 }
303
304 is_send::<DB>();
305 is_send::<DBIterator<'_>>();
306 is_send::<DBRawIterator<'_>>();
307 is_send::<Snapshot>();
308 is_send::<Options>();
309 is_send::<ReadOptions>();
310 is_send::<WriteOptions>();
311 is_send::<BlockBasedOptions>();
312 is_send::<PlainTableFactoryOptions>();
313 is_send::<ColumnFamilyDescriptor>();
314 is_send::<ColumnFamily>();
315 }
316
317 #[test]
318 fn is_sync() {
319 // test (at compile time) that certain types implement the auto-trait Sync
320
321 fn is_sync<T: Sync>() {
322 // dummy function just used for its parameterized type bound
323 }
324
325 is_sync::<DB>();
326 is_sync::<Snapshot>();
327 is_sync::<Options>();
328 is_sync::<ReadOptions>();
329 is_sync::<WriteOptions>();
330 is_sync::<BlockBasedOptions>();
331 is_sync::<PlainTableFactoryOptions>();
332 is_sync::<ColumnFamilyDescriptor>();
333 }
334}