diff --git a/README.md b/README.md index 539753f..5fe3252 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,42 @@ fn main() { } ``` +###### Rustic Merge Operator +```rust +extern crate rocksdb; +use rocksdb::{RocksDBOptions, RocksDB, MergeOperands}; + +fn concat_merge<'a>(new_key: &[u8], existing_val: Option<&[u8]>, + mut operands: &mut MergeOperands) -> Vec { + let mut result: Vec = Vec::with_capacity(operands.size_hint().val0()); + match existing_val { + Some(v) => result.push_all(v), + None => (), + } + for op in operands { + result.push_all(op); + } + result +} + +fn main() { + let path = "/path/to/rocksdb"; + let opts = RocksDBOptions::new(); + opts.create_if_missing(true); + opts.add_merge_operator("test operator", concat_merge); + let db = RocksDB::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().to_utf8().unwrap() == "abcdefg"); + db.close(); +} +``` + + ### status - [x] basic open/put/get/delete/close - [x] linux support diff --git a/src/lib.rs b/src/lib.rs index 7e150ff..8b39b0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,10 @@ pub use ffi as rocksdb_ffi; pub use rocksdb::{ RocksDB, + MergeOperands, RocksDBResult, + RocksDBOptions, + RocksDBVector, }; pub mod rocksdb; pub mod ffi; diff --git a/src/main.rs b/src/main.rs index 86d04dd..0c3acd2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,61 @@ extern crate rocksdb; extern crate test; -use rocksdb::RocksDB; +use rocksdb::{RocksDBOptions, RocksDB, MergeOperands}; use test::Bencher; #[allow(dead_code)] fn main() { - match RocksDB::open_default("/tmp/rust-rocksdb") { - Ok(db) => { - assert!(db.put(b"my key", b"my value").is_ok()); + let path = "/tmp/rust-rocksdb"; + let db = RocksDB::open_default(path).unwrap(); + assert!(db.put(b"my key", b"my value").is_ok()); + db.get(b"my key").map( |value| { + match value.to_utf8() { + Some(v) => + println!("retrieved utf8 value: {}", v), + None => + println!("did not read valid utf-8 out of the db"), + } + }) + .on_absent( || { println!("value not found") }) + .on_error( |e| { println!("error retrieving value: {}", e) }); - db.get(b"my key").map( |value| { - match value.to_utf8() { - Some(v) => - println!("retrieved utf8 value: {}", v), - None => - println!("did not read valid utf-8 out of the db"), - } - }) - .on_absent( || { println!("value not found") }) - .on_error( |e| { println!("error retrieving value: {}", e) }); + assert!(db.delete(b"my key").is_ok()); + db.close(); - assert!(db.delete(b"my key").is_ok()); + custom_merge(); +} - db.close(); - }, - Err(e) => panic!(e), +#[allow(dead_code)] +fn concat_merge(new_key: &[u8], existing_val: Option<&[u8]>, + mut operands: &mut MergeOperands) -> Vec { + let mut result: Vec = Vec::with_capacity(operands.size_hint().val0()); + match existing_val { + Some(v) => result.push_all(v), + None => (), + } + for op in operands { + result.push_all(op); } + result +} + +#[allow(dead_code)] +fn custom_merge() { + let path = "_rust_rocksdb_mergetest"; + let opts = RocksDBOptions::new(); + opts.create_if_missing(true); + opts.add_merge_operator("test operator", concat_merge); + let db = RocksDB::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 m = db.merge(b"k1", b"h"); + let r = db.get(b"k1"); + assert!(r.unwrap().to_utf8().unwrap() == "abcdefgh"); + db.close(); + RocksDB::destroy(opts, path).is_ok(); } #[allow(dead_code)] diff --git a/src/rocksdb.rs b/src/rocksdb.rs index b732955..606dcff 100644 --- a/src/rocksdb.rs +++ b/src/rocksdb.rs @@ -54,7 +54,7 @@ impl RocksDBOptions { } } - pub fn add_merge_operator<'a>(&self, name: &str, merge_fn: for <'a> fn (&[u8], Option<&[u8]>, &mut MergeOperands) -> Vec) { + pub fn add_merge_operator<'a>(&self, name: &str, merge_fn: fn (&[u8], Option<&[u8]>, &mut MergeOperands) -> Vec) { let cb = box MergeOperatorCallback { name: name.to_c_str(), merge_fn: merge_fn, @@ -418,7 +418,7 @@ impl <'a> Iterator<&'a [u8]> for &'a mut MergeOperands<'a> { struct MergeOperatorCallback { name: CString, - merge_fn: for <'b> fn (&[u8], Option<&[u8]>, &mut MergeOperands) -> Vec, + merge_fn: fn (&[u8], Option<&[u8]>, &mut MergeOperands) -> Vec, } extern "C" fn destructor_callback(raw_cb: *mut c_void) { @@ -479,7 +479,7 @@ extern "C" fn partial_merge_callback( } } -fn test_provided_merge<'a>(new_key: &[u8], existing_val: Option<&[u8]>, +fn test_provided_merge(new_key: &[u8], existing_val: Option<&[u8]>, mut operands: &mut MergeOperands) -> Vec { let mut result: Vec = Vec::with_capacity(operands.size_hint().val0()); match existing_val {