rust-rocksdb

This library has been tested against RocksDB 3.13.1 on linux and OSX. The 0.3.5 crate should work with the Rust 1.5 stable and nightly releases as of 5/1/16.

Fork features

This fork adds the following features: - Build RocksDB from source. Note that the library is only build if not detected in the system. - Prefix seek.

status

Feedback and pull requests welcome! If a particular feature of RocksDB is important to you, please let me know by opening an issue, and I'll prioritize it.

Prerequisite: Snappy

Use your system's package manager to install snappy. This is optional, but lets rocksdb take advantage of better compression, and some code may require it.

Running

Cargo.toml

rust [dependencies] rocksdb = { git = "https://github.com/arkpar/rust-rocksdb.git" }

Code

```rust extern crate rocksdb; use rocksdb::{DB, Writable};

fn main() { let mut db = DB::opendefault("/path/for/rocksdb/storage").unwrap(); db.put(b"my key", b"my value"); match db.get(b"my key") { Ok(Some(value)) => println!("retrieved value {}", value.toutf8().unwrap()), Ok(None) => println!("value not found"), Err(e) => println!("operational problem encountered: {}", e), }

db.delete(b"my key");

} ```

Doing an atomic commit of several writes

```rust extern crate rocksdb; use rocksdb::{DB, WriteBatch, Writable};

fn main() { // NB: db is automatically freed at end of lifetime let mut db = DB::open_default("/path/for/rocksdb/storage").unwrap(); { let mut batch = WriteBatch::new(); // WriteBatch and db both have trait Writable batch.put(b"my key", b"my value"); batch.put(b"key2", b"value2"); batch.put(b"key3", b"value3"); db.write(batch); // Atomically commits the batch } } ```

Getting an Iterator

```rust extern crate rocksdb; use rocksdb::{DB, Direction, IteratorMode};

fn main() { // NB: db is automatically freed at end of lifetime let mut db = DB::open_default("/path/for/rocksdb/storage").unwrap(); let mut iter = db.iterator(IteratorMode::Start); // Always iterates forward for (key, value) in iter { println!("Saw {} {}", key, value); //actually, need to convert [u8] keys into Strings } iter = db.iterator(IteratorMode::End); // Always iterates backward for (key, value) in iter { println!("Saw {} {}", key, value); } iter = db.iterator(IteratorMode::From(b"my key", Direction::forward)); // From a key in Direction::{forward,reverse} for (key, value) in iter { println!("Saw {} {}", key, value); }

// You can seek with an existing Iterator instance, too
iter.set_mode(IteratorMode::From(b"another key", Direction::reverse));
for (key, value) in iter {
    println!("Saw {} {}", key, value);
}

} ```

Getting an Iterator from a Snapshot

```rust extern crate rocksdb; use rocksdb::{DB, Direction};

fn main() { // NB: db is automatically freed at end of lifetime let mut db = DB::open_default("/path/for/rocksdb/storage").unwrap(); let snapshot = db.snapshot(); // Creates a longer-term snapshot of the DB, but freed when goes out of scope let mut iter = snapshot.iterator(IteratorMode::Start); // Make as many iterators as you'd like from one snapshot } ```

Rustic Merge Operator

```rust extern crate rocksdb; use rocksdb::{Options, DB, MergeOperands, Writable};

fn concatmerge(newkey: &[u8], existingval: Option<&[u8]>, operands: &mut MergeOperands) -> Vec { let mut result: Vec = Vec::withcapacity(operands.sizehint().0); existingval.map(|v| { for e in v { result.push(e) } }); for op in operands { for e in op { result.push(e) } } result }

fn main() { let path = "/path/to/rocksdb"; let mut opts = Options::new(); opts.createifmissing(true); opts.addmergeoperator("test operator", concatmerge); let mut db = DB::open(&opts, path).unwrap(); let p = db.put(b"k1", b"a"); db.merge(b"k1", b"b"); db.merge(b"k1", b"c"); db.merge(b"k1", b"d"); db.merge(b"k1", b"efg"); let r = db.get(b"k1"); assert!(r.unwrap().unwrap().toutf8().unwrap() == "abcdefg"); } ```

Apply Some Tunings

Please read the official tuning guide, and most importantly, measure performance under realistic workloads with realistic hardware. ```rust use rocksdb::{Options, DB}; use rocksdb::DBCompactionStyle::DBUniversalCompaction;

fn badlytunedforsomebodyelsesdisk() -> DB { let path = "rustrocksdboptimizetest"; let mut opts = Options::new(); opts.createifmissing(true); opts.setmaxopenfiles(10000); opts.setusefsync(false); opts.setbytespersync(8388608); opts.setblockcachesizemb(1024); opts.settablecachenumshardbits(6); opts.setmaxwritebuffernumber(32); opts.setwritebuffersize(536870912); opts.settargetfilesizebase(1073741824); opts.setminwritebuffernumbertomerge(4); opts.setlevelzerostopwritestrigger(2000); opts.setlevelzeroslowdownwritestrigger(0); opts.setcompactionstyle(DBUniversalCompaction); opts.setmaxbackgroundcompactions(4); opts.setmaxbackgroundflushes(4); opts.setfilterdeletes(false); opts.setdisableauto_compactions(true);

DB::open(&opts, path).unwrap()

} ```