rocksdb/
lib.rs

1// Copyright 2020 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#![warn(clippy::pedantic)]
58#![allow(
59    // Next `cast_*` lints don't give alternatives.
60    clippy::cast_possible_wrap, clippy::cast_possible_truncation, clippy::cast_sign_loss,
61    // Next lints produce too much noise/false positives.
62    clippy::module_name_repetitions, clippy::similar_names, clippy::must_use_candidate,
63    // '... may panic' lints.
64    // Too much work to fix.
65    clippy::missing_errors_doc,
66    // False positive: WebSocket
67    clippy::doc_markdown,
68    clippy::missing_safety_doc,
69    clippy::needless_pass_by_value,
70    clippy::ptr_as_ptr,
71    clippy::missing_panics_doc,
72    clippy::from_over_into,
73)]
74
75#[macro_use]
76mod ffi_util;
77
78pub mod backup;
79pub mod checkpoint;
80mod column_family;
81pub mod compaction_filter;
82pub mod compaction_filter_factory;
83mod comparator;
84mod db;
85mod db_iterator;
86mod db_options;
87mod db_pinnable_slice;
88mod env;
89mod iter_range;
90pub mod merge_operator;
91pub mod perf;
92mod prop_name;
93pub mod properties;
94mod slice_transform;
95mod snapshot;
96mod sst_file_writer;
97pub mod statistics;
98mod transactions;
99mod write_batch;
100
101pub use crate::{
102    column_family::{
103        AsColumnFamilyRef, BoundColumnFamily, ColumnFamily, ColumnFamilyDescriptor,
104        ColumnFamilyRef, DEFAULT_COLUMN_FAMILY_NAME,
105    },
106    compaction_filter::Decision as CompactionDecision,
107    db::{
108        DBAccess, DBCommon, DBWithThreadMode, LiveFile, MultiThreaded, SingleThreaded, ThreadMode,
109        DB,
110    },
111    db_iterator::{
112        DBIterator, DBIteratorWithThreadMode, DBRawIterator, DBRawIteratorWithThreadMode,
113        DBWALIterator, Direction, IteratorMode,
114    },
115    db_options::{
116        BlockBasedIndexType, BlockBasedOptions, BottommostLevelCompaction, Cache, ChecksumType,
117        CompactOptions, CuckooTableOptions, DBCompactionStyle, DBCompressionType, DBPath,
118        DBRecoveryMode, DataBlockIndexType, FifoCompactOptions, FlushOptions,
119        IngestExternalFileOptions, KeyEncodingType, LogLevel, MemtableFactory, Options,
120        PlainTableFactoryOptions, ReadOptions, ReadTier, UniversalCompactOptions,
121        UniversalCompactionStopStyle, WaitForCompactOptions, WriteBufferManager, WriteOptions,
122    },
123    db_pinnable_slice::DBPinnableSlice,
124    env::Env,
125    ffi_util::CStrLike,
126    iter_range::{IterateBounds, PrefixRange},
127    merge_operator::MergeOperands,
128    perf::{PerfContext, PerfMetric, PerfStatsLevel},
129    slice_transform::SliceTransform,
130    snapshot::{Snapshot, SnapshotWithThreadMode},
131    sst_file_writer::SstFileWriter,
132    transactions::{
133        OptimisticTransactionDB, OptimisticTransactionOptions, Transaction, TransactionDB,
134        TransactionDBOptions, TransactionOptions,
135    },
136    write_batch::{WriteBatch, WriteBatchIterator, WriteBatchWithTransaction},
137};
138
139use librocksdb_sys as ffi;
140
141use std::error;
142use std::fmt;
143
144/// RocksDB error kind.
145#[derive(Debug, Clone, PartialEq, Eq)]
146pub enum ErrorKind {
147    NotFound,
148    Corruption,
149    NotSupported,
150    InvalidArgument,
151    IOError,
152    MergeInProgress,
153    Incomplete,
154    ShutdownInProgress,
155    TimedOut,
156    Aborted,
157    Busy,
158    Expired,
159    TryAgain,
160    CompactionTooLarge,
161    ColumnFamilyDropped,
162    Unknown,
163}
164
165/// A simple wrapper round a string, used for errors reported from
166/// ffi calls.
167#[derive(Debug, Clone, PartialEq, Eq)]
168pub struct Error {
169    message: String,
170}
171
172impl Error {
173    fn new(message: String) -> Error {
174        Error { message }
175    }
176
177    pub fn into_string(self) -> String {
178        self.into()
179    }
180
181    /// Parse corresponding [`ErrorKind`] from error message.
182    pub fn kind(&self) -> ErrorKind {
183        match self.message.split(':').next().unwrap_or("") {
184            "NotFound" => ErrorKind::NotFound,
185            "Corruption" => ErrorKind::Corruption,
186            "Not implemented" => ErrorKind::NotSupported,
187            "Invalid argument" => ErrorKind::InvalidArgument,
188            "IO error" => ErrorKind::IOError,
189            "Merge in progress" => ErrorKind::MergeInProgress,
190            "Result incomplete" => ErrorKind::Incomplete,
191            "Shutdown in progress" => ErrorKind::ShutdownInProgress,
192            "Operation timed out" => ErrorKind::TimedOut,
193            "Operation aborted" => ErrorKind::Aborted,
194            "Resource busy" => ErrorKind::Busy,
195            "Operation expired" => ErrorKind::Expired,
196            "Operation failed. Try again." => ErrorKind::TryAgain,
197            "Compaction too large" => ErrorKind::CompactionTooLarge,
198            "Column family dropped" => ErrorKind::ColumnFamilyDropped,
199            _ => ErrorKind::Unknown,
200        }
201    }
202}
203
204impl AsRef<str> for Error {
205    fn as_ref(&self) -> &str {
206        &self.message
207    }
208}
209
210impl From<Error> for String {
211    fn from(e: Error) -> String {
212        e.message
213    }
214}
215
216impl error::Error for Error {
217    fn description(&self) -> &str {
218        &self.message
219    }
220}
221
222impl fmt::Display for Error {
223    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
224        self.message.fmt(formatter)
225    }
226}
227
228#[cfg(test)]
229mod test {
230    use crate::{
231        OptimisticTransactionDB, OptimisticTransactionOptions, Transaction, TransactionDB,
232        TransactionDBOptions, TransactionOptions,
233    };
234
235    use super::{
236        column_family::UnboundColumnFamily,
237        db_options::{CacheWrapper, WriteBufferManagerWrapper},
238        env::{Env, EnvWrapper},
239        BlockBasedOptions, BoundColumnFamily, Cache, ColumnFamily, ColumnFamilyDescriptor,
240        DBIterator, DBRawIterator, IngestExternalFileOptions, Options, PlainTableFactoryOptions,
241        ReadOptions, Snapshot, SstFileWriter, WriteBatch, WriteBufferManager, WriteOptions, DB,
242    };
243
244    #[test]
245    fn is_send() {
246        // test (at compile time) that certain types implement the auto-trait Send, either directly for
247        // pointer-wrapping types or transitively for types with all Send fields
248
249        fn is_send<T: Send>() {
250            // dummy function just used for its parameterized type bound
251        }
252
253        is_send::<DB>();
254        is_send::<DBIterator<'_>>();
255        is_send::<DBRawIterator<'_>>();
256        is_send::<Snapshot>();
257        is_send::<Options>();
258        is_send::<ReadOptions>();
259        is_send::<WriteOptions>();
260        is_send::<IngestExternalFileOptions>();
261        is_send::<BlockBasedOptions>();
262        is_send::<PlainTableFactoryOptions>();
263        is_send::<ColumnFamilyDescriptor>();
264        is_send::<ColumnFamily>();
265        is_send::<BoundColumnFamily<'_>>();
266        is_send::<UnboundColumnFamily>();
267        is_send::<SstFileWriter>();
268        is_send::<WriteBatch>();
269        is_send::<Cache>();
270        is_send::<CacheWrapper>();
271        is_send::<Env>();
272        is_send::<EnvWrapper>();
273        is_send::<TransactionDB>();
274        is_send::<OptimisticTransactionDB>();
275        is_send::<Transaction<'_, TransactionDB>>();
276        is_send::<TransactionDBOptions>();
277        is_send::<OptimisticTransactionOptions>();
278        is_send::<TransactionOptions>();
279        is_send::<WriteBufferManager>();
280        is_send::<WriteBufferManagerWrapper>();
281    }
282
283    #[test]
284    fn is_sync() {
285        // test (at compile time) that certain types implement the auto-trait Sync
286
287        fn is_sync<T: Sync>() {
288            // dummy function just used for its parameterized type bound
289        }
290
291        is_sync::<DB>();
292        is_sync::<Snapshot>();
293        is_sync::<Options>();
294        is_sync::<ReadOptions>();
295        is_sync::<WriteOptions>();
296        is_sync::<IngestExternalFileOptions>();
297        is_sync::<BlockBasedOptions>();
298        is_sync::<PlainTableFactoryOptions>();
299        is_sync::<UnboundColumnFamily>();
300        is_sync::<ColumnFamilyDescriptor>();
301        is_sync::<SstFileWriter>();
302        is_sync::<Cache>();
303        is_sync::<CacheWrapper>();
304        is_sync::<Env>();
305        is_sync::<EnvWrapper>();
306        is_sync::<TransactionDB>();
307        is_sync::<OptimisticTransactionDB>();
308        is_sync::<TransactionDBOptions>();
309        is_sync::<OptimisticTransactionOptions>();
310        is_sync::<TransactionOptions>();
311        is_sync::<WriteBufferManager>();
312        is_sync::<WriteBufferManagerWrapper>();
313    }
314}