diff --git a/src/ffi.rs b/src/ffi.rs index d5cc415..5a15cfd 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -15,48 +15,45 @@ */ extern crate libc; use self::libc::{c_char, c_int, c_void, size_t}; +use std::ffi::CString; +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBOptions(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBInstance(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBWriteOptions(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBReadOptions(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBMergeOperator(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBBlockBasedTableOptions(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBCache(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBFilterPolicy(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBSnapshot(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBIterator(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBCFHandle(pub *const c_void); +#[derive(Copy, Clone)] #[repr(C)] pub struct RocksDBWriteBatch(pub *const c_void); -impl Copy for RocksDBOptions {} -impl Copy for RocksDBInstance {} -impl Copy for RocksDBWriteOptions {} -impl Copy for RocksDBReadOptions {} -impl Copy for RocksDBMergeOperator {} -impl Copy for RocksDBBlockBasedTableOptions {} -impl Copy for RocksDBCache {} -impl Copy for RocksDBFilterPolicy {} -impl Copy for RocksDBCompactionStyle {} -impl Copy for RocksDBCompressionType {} -impl Copy for RocksDBUniversalCompactionStyle {} -impl Copy for RocksDBSnapshot {} -impl Copy for RocksDBIterator {} -impl Copy for RocksDBCFHandle {} -impl Copy for RocksDBWriteBatch {} - pub fn new_bloom_filter(bits: c_int) -> RocksDBFilterPolicy { unsafe { rocksdb_filterpolicy_create_bloom(bits) @@ -329,7 +326,7 @@ fn internal() { rocksdb_options_set_create_if_missing(opts, true); let rustpath = "_rust_rocksdb_internaltest"; - let cpath = CString::from_slice(rustpath.as_bytes()); + let cpath = CString::new(rustpath).unwrap(); let cpath_ptr = cpath.as_ptr(); let err = 0 as *mut i8; diff --git a/src/main.rs b/src/main.rs index 1c62bdf..7458057 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,8 +71,17 @@ fn custom_merge() { 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.get(b"k1").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.close(); RocksDB::destroy(opts, path).is_ok(); } diff --git a/src/merge_operator.rs b/src/merge_operator.rs index 3621576..4784390 100644 --- a/src/merge_operator.rs +++ b/src/merge_operator.rs @@ -56,8 +56,8 @@ pub extern "C" fn full_merge_callback( &mut MergeOperands::new(operands_list, operands_list_len, num_operands); - let key: &[u8] = mem::transmute(slice::from_raw_buf(&raw_key, key_len as usize)); - let oldval: &[u8] = mem::transmute(slice::from_raw_buf(&existing_value, + let key: &[u8] = mem::transmute(slice::from_raw_parts(&raw_key, key_len as usize)); + let oldval: &[u8] = mem::transmute(slice::from_raw_parts(&existing_value, existing_value_len as usize)); let mut result = (cb.merge_fn)(key, Some(oldval), operands); @@ -67,7 +67,7 @@ pub extern "C" fn full_merge_callback( assert!(!buf.is_null()); *new_value_length = result.len() as size_t; *success = 1 as u8; - ptr::copy(&mut *buf, result.as_ptr() as *const c_void, result.len()); + ptr::copy(result.as_ptr() as *mut c_void, &mut *buf, result.len()); buf as *const c_char } } @@ -83,7 +83,7 @@ pub extern "C" fn partial_merge_callback( let operands = &mut MergeOperands::new(operands_list, operands_list_len, num_operands); - let key: &[u8] = mem::transmute(slice::from_raw_buf(&raw_key, key_len as usize)); + let key: &[u8] = mem::transmute(slice::from_raw_parts(&raw_key, key_len as usize)); let mut result = (cb.merge_fn)(key, None, operands); result.shrink_to_fit(); //TODO(tan) investigate zero-copy techniques to improve performance @@ -91,7 +91,7 @@ pub extern "C" fn partial_merge_callback( assert!(!buf.is_null()); *new_value_length = 1 as size_t; *success = 1 as u8; - ptr::copy(&mut *buf, result.as_ptr() as *const c_void, result.len()); + ptr::copy(result.as_ptr() as *mut c_void, &mut *buf, result.len()); buf as *const c_char } } diff --git a/src/rocksdb.rs b/src/rocksdb.rs index 942795d..ed67ac5 100644 --- a/src/rocksdb.rs +++ b/src/rocksdb.rs @@ -198,7 +198,7 @@ pub struct RocksDBVector { impl Deref for RocksDBVector { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { slice::from_raw_mut_buf(self.base.deref(), self.len) } + unsafe { slice::from_raw_parts(self.base.get(), self.len) } } } diff --git a/src/rocksdb_options.rs b/src/rocksdb_options.rs index 16bbecf..34f8c84 100644 --- a/src/rocksdb_options.rs +++ b/src/rocksdb_options.rs @@ -22,13 +22,12 @@ use rocksdb_ffi; use merge_operator::{MergeOperatorCallback, MergeOperands, destructor_callback, full_merge_callback, partial_merge_callback, name_callback}; +#[derive(Copy, Clone)] pub struct RocksDBOptions { pub inner: rocksdb_ffi::RocksDBOptions, block_options: rocksdb_ffi::RocksDBBlockBasedTableOptions, } -impl Copy for RocksDBOptions {} - impl RocksDBOptions { pub fn new() -> RocksDBOptions { unsafe {