Commit 8e198679 authored by Jay's avatar Jay Committed by GitHub

make code more rusty (#41)

parent 37e70775
......@@ -19,48 +19,27 @@ extern crate tempdir;
use libc::{c_char, c_uchar, c_int, c_void, size_t, uint64_t};
use std::ffi::CStr;
use std::str::from_utf8;
pub enum DBOptions {}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBInstance(pub *const c_void);
pub enum DBInstance {}
pub enum DBWriteOptions {}
pub enum DBReadOptions {}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBMergeOperator(pub *const c_void);
pub enum DBMergeOperator {}
pub enum DBBlockBasedTableOptions {}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBCache(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBFilterPolicy(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBSnapshot(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBIterator(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBCFHandle(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBWriteBatch(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBComparator(pub *const c_void);
#[derive(Copy, Clone)]
#[repr(C)]
pub struct DBFlushOptions(pub *const c_void);
pub fn new_bloom_filter(bits: c_int) -> DBFilterPolicy {
pub enum DBCache {}
pub enum DBFilterPolicy {}
pub enum DBSnapshot {}
pub enum DBIterator {}
pub enum DBCFHandle {}
pub enum DBWriteBatch {}
pub enum DBComparator {}
pub enum DBFlushOptions {}
pub fn new_bloom_filter(bits: c_int) -> *mut DBFilterPolicy {
unsafe { rocksdb_filterpolicy_create_bloom(bits) }
}
pub fn new_cache(capacity: size_t) -> DBCache {
pub fn new_cache(capacity: size_t) -> *mut DBCache {
unsafe { rocksdb_cache_create_lru(capacity) }
}
......@@ -97,9 +76,9 @@ pub enum DBRecoveryMode {
SkipAnyCorruptedRecords = 3,
}
pub fn error_message(ptr: *const i8) -> String {
let c_str = unsafe { CStr::from_ptr(ptr as *const _) };
let s = from_utf8(c_str.to_bytes()).unwrap().to_owned();
pub fn error_message(ptr: *mut c_char) -> String {
let c_str = unsafe { CStr::from_ptr(ptr) };
let s = format!("{}", c_str.to_string_lossy());
unsafe {
libc::free(ptr as *mut c_void);
}
......@@ -112,8 +91,8 @@ pub fn error_message(ptr: *const i8) -> String {
extern "C" {
pub fn rocksdb_options_create() -> *mut DBOptions;
pub fn rocksdb_options_destroy(opts: *mut DBOptions);
pub fn rocksdb_cache_create_lru(capacity: size_t) -> DBCache;
pub fn rocksdb_cache_destroy(cache: DBCache);
pub fn rocksdb_cache_create_lru(capacity: size_t) -> *mut DBCache;
pub fn rocksdb_cache_destroy(cache: *mut DBCache);
pub fn rocksdb_block_based_options_create() -> *mut DBBlockBasedTableOptions;
pub fn rocksdb_block_based_options_destroy(opts: *mut DBBlockBasedTableOptions);
pub fn rocksdb_block_based_options_set_block_size(
......@@ -129,14 +108,14 @@ extern "C" {
block_options: *mut DBBlockBasedTableOptions, v: c_uchar);
pub fn rocksdb_block_based_options_set_filter_policy(
block_options: *mut DBBlockBasedTableOptions,
filter_policy: DBFilterPolicy);
filter_policy: *mut DBFilterPolicy);
pub fn rocksdb_block_based_options_set_no_block_cache(
block_options: *mut DBBlockBasedTableOptions, no_block_cache: bool);
pub fn rocksdb_block_based_options_set_block_cache(
block_options: *mut DBBlockBasedTableOptions, block_cache: DBCache);
block_options: *mut DBBlockBasedTableOptions, block_cache: *mut DBCache);
pub fn rocksdb_block_based_options_set_block_cache_compressed(
block_options: *mut DBBlockBasedTableOptions,
block_cache_compressed: DBCache);
block_cache_compressed: *mut DBCache);
pub fn rocksdb_block_based_options_set_whole_key_filtering(
ck_options: *mut DBBlockBasedTableOptions, doit: bool);
pub fn rocksdb_options_set_block_based_table_factory(
......@@ -203,33 +182,33 @@ extern "C" {
pub fn rocksdb_options_set_report_bg_io_stats(options: *mut DBOptions, v: c_int);
pub fn rocksdb_options_set_wal_recovery_mode(options: *mut DBOptions, mode: DBRecoveryMode);
pub fn rocksdb_filterpolicy_create_bloom_full(bits_per_key: c_int)
-> DBFilterPolicy;
-> *mut DBFilterPolicy;
pub fn rocksdb_filterpolicy_create_bloom(bits_per_key: c_int)
-> DBFilterPolicy;
-> *mut DBFilterPolicy;
pub fn rocksdb_open(options: *mut DBOptions,
path: *const i8,
err: *mut *const i8)
-> DBInstance;
path: *const c_char,
err: *mut *mut c_char)
-> *mut DBInstance;
pub fn rocksdb_writeoptions_create() -> *mut DBWriteOptions;
pub fn rocksdb_writeoptions_destroy(writeopts: *mut DBWriteOptions);
pub fn rocksdb_writeoptions_set_sync(writeopts: *mut DBWriteOptions, v: bool);
pub fn rocksdb_writeoptions_disable_WAL(writeopts: *mut DBWriteOptions,
v: c_int);
pub fn rocksdb_put(db: DBInstance,
pub fn rocksdb_put(db: *mut DBInstance,
writeopts: *mut DBWriteOptions,
k: *const u8,
kLen: size_t,
v: *const u8,
vLen: size_t,
err: *mut *const i8);
pub fn rocksdb_put_cf(db: DBInstance,
err: *mut *mut c_char);
pub fn rocksdb_put_cf(db: *mut DBInstance,
writeopts: *mut DBWriteOptions,
cf: DBCFHandle,
cf: *mut DBCFHandle,
k: *const u8,
kLen: size_t,
v: *const u8,
vLen: size_t,
err: *mut *const i8);
err: *mut *mut c_char);
pub fn rocksdb_readoptions_create() -> *mut DBReadOptions;
pub fn rocksdb_readoptions_destroy(readopts: *mut DBReadOptions);
pub fn rocksdb_readoptions_set_verify_checksums(readopts: *mut DBReadOptions,
......@@ -237,7 +216,7 @@ extern "C" {
pub fn rocksdb_readoptions_set_fill_cache(readopts: *mut DBReadOptions,
v: bool);
pub fn rocksdb_readoptions_set_snapshot(readopts: *mut DBReadOptions,
snapshot: DBSnapshot); //TODO how do I make this a const ref?
snapshot: *const DBSnapshot); //TODO how do I make this a const ref?
pub fn rocksdb_readoptions_set_iterate_upper_bound(readopts: *mut DBReadOptions,
k: *const u8,
kLen: size_t);
......@@ -245,67 +224,65 @@ extern "C" {
tier: c_int);
pub fn rocksdb_readoptions_set_tailing(readopts: *mut DBReadOptions, v: bool);
pub fn rocksdb_get(db: DBInstance,
pub fn rocksdb_get(db: *const DBInstance,
readopts: *const DBReadOptions,
k: *const u8,
kLen: size_t,
valLen: *const size_t,
err: *mut *const i8)
-> *mut c_void;
pub fn rocksdb_get_cf(db: DBInstance,
err: *mut *mut c_char)
-> *mut u8;
pub fn rocksdb_get_cf(db: *const DBInstance,
readopts: *const DBReadOptions,
cf_handle: DBCFHandle,
cf_handle: *mut DBCFHandle,
k: *const u8,
kLen: size_t,
valLen: *const size_t,
err: *mut *const i8)
-> *mut c_void;
pub fn rocksdb_create_iterator(db: DBInstance,
err: *mut *mut c_char)
-> *mut u8;
pub fn rocksdb_create_iterator(db: *mut DBInstance,
readopts: *const DBReadOptions)
-> DBIterator;
pub fn rocksdb_create_iterator_cf(db: DBInstance,
-> *mut DBIterator;
pub fn rocksdb_create_iterator_cf(db: *mut DBInstance,
readopts: *const DBReadOptions,
cf_handle: DBCFHandle)
-> DBIterator;
pub fn rocksdb_create_snapshot(db: DBInstance) -> DBSnapshot;
pub fn rocksdb_release_snapshot(db: DBInstance, snapshot: DBSnapshot);
cf_handle: *mut DBCFHandle)
-> *mut DBIterator;
pub fn rocksdb_create_snapshot(db: *mut DBInstance) -> *const DBSnapshot;
pub fn rocksdb_release_snapshot(db: *mut DBInstance, snapshot: *const DBSnapshot);
pub fn rocksdb_delete(db: DBInstance,
pub fn rocksdb_delete(db: *mut DBInstance,
writeopts: *const DBWriteOptions,
k: *const u8,
kLen: size_t,
err: *mut *const i8)
-> *mut c_void;
pub fn rocksdb_delete_cf(db: DBInstance,
err: *mut *mut c_char);
pub fn rocksdb_delete_cf(db: *mut DBInstance,
writeopts: *const DBWriteOptions,
cf: DBCFHandle,
cf: *mut DBCFHandle,
k: *const u8,
kLen: size_t,
err: *mut *const i8)
-> *mut c_void;
pub fn rocksdb_close(db: DBInstance);
err: *mut *mut c_char);
pub fn rocksdb_close(db: *mut DBInstance);
pub fn rocksdb_destroy_db(options: *const DBOptions,
path: *const i8,
err: *mut *const i8);
path: *const c_char,
err: *mut *mut c_char);
pub fn rocksdb_repair_db(options: *const DBOptions,
path: *const i8,
err: *mut *const i8);
path: *const c_char,
err: *mut *mut c_char);
// Merge
pub fn rocksdb_merge(db: DBInstance,
pub fn rocksdb_merge(db: *mut DBInstance,
writeopts: *const DBWriteOptions,
k: *const u8,
kLen: size_t,
v: *const u8,
vLen: size_t,
err: *mut *const i8);
pub fn rocksdb_merge_cf(db: DBInstance,
err: *mut *mut c_char);
pub fn rocksdb_merge_cf(db: *mut DBInstance,
writeopts: *const DBWriteOptions,
cf: DBCFHandle,
cf: *mut DBCFHandle,
k: *const u8,
kLen: size_t,
v: *const u8,
vLen: size_t,
err: *mut *const i8);
err: *mut *mut c_char);
pub fn rocksdb_mergeoperator_create(
state: *mut c_void,
destroy: extern fn(*mut c_void) -> (),
......@@ -330,77 +307,77 @@ extern "C" {
value_len: *mut size_t
) -> ()>,
name_fn: extern fn(*mut c_void) -> *const c_char,
) -> DBMergeOperator;
pub fn rocksdb_mergeoperator_destroy(mo: DBMergeOperator);
) -> *mut DBMergeOperator;
pub fn rocksdb_mergeoperator_destroy(mo: *mut DBMergeOperator);
pub fn rocksdb_options_set_merge_operator(options: *mut DBOptions,
mo: DBMergeOperator);
mo: *mut DBMergeOperator);
// Iterator
pub fn rocksdb_iter_destroy(iter: DBIterator);
pub fn rocksdb_iter_valid(iter: DBIterator) -> bool;
pub fn rocksdb_iter_seek_to_first(iter: DBIterator);
pub fn rocksdb_iter_seek_to_last(iter: DBIterator);
pub fn rocksdb_iter_seek(iter: DBIterator, key: *const u8, klen: size_t);
pub fn rocksdb_iter_next(iter: DBIterator);
pub fn rocksdb_iter_prev(iter: DBIterator);
pub fn rocksdb_iter_key(iter: DBIterator, klen: *mut size_t) -> *mut u8;
pub fn rocksdb_iter_value(iter: DBIterator, vlen: *mut size_t) -> *mut u8;
pub fn rocksdb_iter_get_error(iter: DBIterator, err: *mut *const u8);
pub fn rocksdb_iter_destroy(iter: *mut DBIterator);
pub fn rocksdb_iter_valid(iter: *const DBIterator) -> bool;
pub fn rocksdb_iter_seek_to_first(iter: *mut DBIterator);
pub fn rocksdb_iter_seek_to_last(iter: *mut DBIterator);
pub fn rocksdb_iter_seek(iter: *mut DBIterator, key: *const u8, klen: size_t);
pub fn rocksdb_iter_next(iter: *mut DBIterator);
pub fn rocksdb_iter_prev(iter: *mut DBIterator);
pub fn rocksdb_iter_key(iter: *const DBIterator, klen: *mut size_t) -> *mut u8;
pub fn rocksdb_iter_value(iter: *const DBIterator, vlen: *mut size_t) -> *mut u8;
pub fn rocksdb_iter_get_error(iter: *const DBIterator, err: *mut *mut c_char);
// Write batch
pub fn rocksdb_write(db: DBInstance,
pub fn rocksdb_write(db: *mut DBInstance,
writeopts: *const DBWriteOptions,
batch: DBWriteBatch,
err: *mut *const i8);
pub fn rocksdb_writebatch_create() -> DBWriteBatch;
batch: *mut DBWriteBatch,
err: *mut *mut c_char);
pub fn rocksdb_writebatch_create() -> *mut DBWriteBatch;
pub fn rocksdb_writebatch_create_from(rep: *const u8,
size: size_t)
-> DBWriteBatch;
pub fn rocksdb_writebatch_destroy(batch: DBWriteBatch);
pub fn rocksdb_writebatch_clear(batch: DBWriteBatch);
pub fn rocksdb_writebatch_count(batch: DBWriteBatch) -> c_int;
pub fn rocksdb_writebatch_put(batch: DBWriteBatch,
-> *mut DBWriteBatch;
pub fn rocksdb_writebatch_destroy(batch: *mut DBWriteBatch);
pub fn rocksdb_writebatch_clear(batch: *mut DBWriteBatch);
pub fn rocksdb_writebatch_count(batch: *mut DBWriteBatch) -> c_int;
pub fn rocksdb_writebatch_put(batch: *mut DBWriteBatch,
key: *const u8,
klen: size_t,
val: *const u8,
vlen: size_t);
pub fn rocksdb_writebatch_put_cf(batch: DBWriteBatch,
cf: DBCFHandle,
pub fn rocksdb_writebatch_put_cf(batch: *mut DBWriteBatch,
cf: *mut DBCFHandle,
key: *const u8,
klen: size_t,
val: *const u8,
vlen: size_t);
pub fn rocksdb_writebatch_merge(batch: DBWriteBatch,
pub fn rocksdb_writebatch_merge(batch: *mut DBWriteBatch,
key: *const u8,
klen: size_t,
val: *const u8,
vlen: size_t);
pub fn rocksdb_writebatch_merge_cf(batch: DBWriteBatch,
cf: DBCFHandle,
pub fn rocksdb_writebatch_merge_cf(batch: *mut DBWriteBatch,
cf: *mut DBCFHandle,
key: *const u8,
klen: size_t,
val: *const u8,
vlen: size_t);
pub fn rocksdb_writebatch_delete(batch: DBWriteBatch,
pub fn rocksdb_writebatch_delete(batch: *mut DBWriteBatch,
key: *const u8,
klen: size_t);
pub fn rocksdb_writebatch_delete_cf(batch: DBWriteBatch,
cf: DBCFHandle,
pub fn rocksdb_writebatch_delete_cf(batch: *mut DBWriteBatch,
cf: *mut DBCFHandle,
key: *const u8,
klen: size_t);
pub fn rocksdb_writebatch_iterate(
batch: DBWriteBatch,
batch: *mut DBWriteBatch,
state: *mut c_void,
put_fn: extern fn(state: *mut c_void,
k: *const u8, klen: size_t,
v: *const u8, vlen: size_t),
deleted_fn: extern fn(state: *mut c_void,
k: *const u8, klen: size_t));
pub fn rocksdb_writebatch_data(batch: DBWriteBatch,
pub fn rocksdb_writebatch_data(batch: *mut DBWriteBatch,
size: *mut size_t)
-> *const u8;
// Comparator
pub fn rocksdb_options_set_comparator(options: *mut DBOptions,
cb: DBComparator);
cb: *mut DBComparator);
pub fn rocksdb_comparator_create(state: *mut c_void,
destroy: extern "C" fn(*mut c_void) -> (),
compare: extern "C" fn(arg: *mut c_void,
......@@ -411,78 +388,78 @@ extern "C" {
-> c_int,
name_fn: extern "C" fn(*mut c_void)
-> *const c_char)
-> DBComparator;
pub fn rocksdb_comparator_destroy(cmp: DBComparator);
-> *mut DBComparator;
pub fn rocksdb_comparator_destroy(cmp: *mut DBComparator);
// Column Family
pub fn rocksdb_open_column_families(options: *const DBOptions,
path: *const i8,
path: *const c_char,
num_column_families: c_int,
column_family_names: *const *const i8,
column_family_names: *const *const c_char,
column_family_options: *const *const DBOptions,
column_family_handles: *const DBCFHandle,
err: *mut *const i8
) -> DBInstance;
pub fn rocksdb_create_column_family(db: DBInstance,
column_family_handles: *const *mut DBCFHandle,
err: *mut *mut c_char
) -> *mut DBInstance;
pub fn rocksdb_create_column_family(db: *mut DBInstance,
column_family_options: *const DBOptions,
column_family_name: *const i8,
err: *mut *const i8)
-> DBCFHandle;
pub fn rocksdb_drop_column_family(db: DBInstance,
column_family_handle: DBCFHandle,
err: *mut *const i8);
pub fn rocksdb_column_family_handle_destroy(column_family_handle: DBCFHandle);
column_family_name: *const c_char,
err: *mut *mut c_char)
-> *mut DBCFHandle;
pub fn rocksdb_drop_column_family(db: *mut DBInstance,
column_family_handle: *mut DBCFHandle,
err: *mut *mut c_char);
pub fn rocksdb_column_family_handle_destroy(column_family_handle: *mut DBCFHandle);
pub fn rocksdb_list_column_families(db: *const DBOptions,
path: *const i8,
path: *const c_char,
lencf: *mut size_t,
err: *mut *const i8
) -> *const *const i8;
pub fn rocksdb_list_column_families_destroy(list: *mut *mut i8,
err: *mut *mut c_char
) -> *mut *mut c_char;
pub fn rocksdb_list_column_families_destroy(list: *mut *mut c_char,
len: size_t);
// Flush options
pub fn rocksdb_flushoptions_create() -> DBFlushOptions;
pub fn rocksdb_flushoptions_destroy(opt: DBFlushOptions);
pub fn rocksdb_flushoptions_set_wait(opt: DBFlushOptions,
pub fn rocksdb_flushoptions_create() -> *mut DBFlushOptions;
pub fn rocksdb_flushoptions_destroy(opt: *mut DBFlushOptions);
pub fn rocksdb_flushoptions_set_wait(opt: *mut DBFlushOptions,
whether_wait: bool);
pub fn rocksdb_flush(db: DBInstance,
options: DBFlushOptions,
err: *mut *const i8);
pub fn rocksdb_flush(db: *mut DBInstance,
options: *const DBFlushOptions,
err: *mut *mut c_char);
pub fn rocksdb_approximate_sizes(db: DBInstance,
pub fn rocksdb_approximate_sizes(db: *mut DBInstance,
num_ranges: c_int,
range_start_key: *const *const u8,
range_start_key_len: *const size_t,
range_limit_key: *const *const u8,
range_limit_key_len: *const size_t,
sizes: *mut uint64_t);
pub fn rocksdb_approximate_sizes_cf(db: DBInstance,
cf: DBCFHandle,
pub fn rocksdb_approximate_sizes_cf(db: *mut DBInstance,
cf: *mut DBCFHandle,
num_ranges: c_int,
range_start_key: *const *const u8,
range_start_key_len: *const size_t,
range_limit_key: *const *const u8,
range_limit_key_len: *const size_t,
sizes: *mut uint64_t);
pub fn rocksdb_delete_file_in_range(db: DBInstance,
pub fn rocksdb_delete_file_in_range(db: *mut DBInstance,
range_start_key: *const u8,
range_start_key_len: size_t,
range_limit_key: *const u8,
range_limit_key_len: size_t,
err: *mut *const i8);
pub fn rocksdb_delete_file_in_range_cf(db: DBInstance,
cf: DBCFHandle,
err: *mut *mut c_char);
pub fn rocksdb_delete_file_in_range_cf(db: *mut DBInstance,
cf: *mut DBCFHandle,
range_start_key: *const u8,
range_start_key_len: size_t,
range_limit_key: *const u8,
range_limit_key_len: size_t,
err: *mut *const i8);
pub fn rocksdb_property_value(db: DBInstance,
err: *mut *mut c_char);
pub fn rocksdb_property_value(db: *mut DBInstance,
propname: *const c_char)
-> *mut c_char;
pub fn rocksdb_property_value_cf(db: DBInstance,
cf: DBCFHandle,
pub fn rocksdb_property_value_cf(db: *mut DBInstance,
cf: *mut DBCFHandle,
propname: *const c_char)
-> *mut c_char;
}
......@@ -491,7 +468,7 @@ extern "C" {
mod test {
use super::*;
use std::ffi::{CStr, CString};
use libc::{self, c_void};
use libc::{self, c_void, c_char};
use tempdir::TempDir;
#[test]
......@@ -510,7 +487,7 @@ mod test {
.unwrap();
let cpath_ptr = cpath.as_ptr();
let mut err = 0 as *const i8;
let mut err = 0 as *mut c_char;
let db = rocksdb_open(opts, cpath_ptr, &mut err);
assert!(err.is_null(), error_message(err));
......
......@@ -24,9 +24,9 @@ pub mod rocksdb_options;
pub mod merge_operator;
pub mod comparator;
pub use librocksdb_sys::{DBCompactionStyle, DBComparator, DBCompressionType,
pub use librocksdb_sys::{DBCompactionStyle, DBCompressionType,
DBRecoveryMode, new_bloom_filter, self as rocksdb_ffi};
pub use merge_operator::MergeOperands;
pub use rocksdb::{DB, DBIterator, DBVector, Kv, SeekKey, Writable, WriteBatch};
pub use rocksdb::{DB, DBIterator, DBVector, Kv, SeekKey, Writable, WriteBatch, CFHandle};
pub use rocksdb_options::{BlockBasedOptions, Options, ReadOptions,
WriteOptions};
......@@ -143,7 +143,7 @@ fn main() {
#[cfg(test)]
mod tests {
use rocksdb::{BlockBasedOptions, DB, DBCompressionType, Options, ReadOptions, WriteOptions, SeekKey};
use rocksdb::{BlockBasedOptions, DB, DBCompressionType, Options};
use rocksdb::DBCompactionStyle::DBUniversal;
use rocksdb::DBRecoveryMode;
......
......@@ -14,11 +14,12 @@
//
use libc::{self, c_int, c_void, size_t};
use libc::{self, c_int, c_void, size_t, c_char};
use rocksdb_ffi::{self, DBCFHandle, error_message};
use rocksdb_ffi::{self, DBWriteBatch, DBCFHandle, error_message, DBInstance};
use rocksdb_options::{Options, ReadOptions, UnsafeSnap, WriteOptions};
use std::collections::BTreeMap;
use std::collections::btree_map::Entry;
use std::ffi::{CStr, CString};
use std::fs;
use std::ops::Deref;
......@@ -28,9 +29,19 @@ use std::str::from_utf8;
const DEFAULT_COLUMN_FAMILY: &'static str = "default";
pub struct CFHandle {
inner: *mut DBCFHandle,
}
impl Drop for CFHandle {
fn drop(&mut self) {
unsafe { rocksdb_ffi::rocksdb_column_family_handle_destroy(self.inner); }
}
}
pub struct DB {
inner: rocksdb_ffi::DBInstance,
cfs: BTreeMap<String, DBCFHandle>,
inner: *mut DBInstance,
cfs: BTreeMap<String, CFHandle>,
path: String,
}
......@@ -38,7 +49,7 @@ unsafe impl Send for DB {}
unsafe impl Sync for DB {}
pub struct WriteBatch {
inner: rocksdb_ffi::DBWriteBatch,
inner: *mut DBWriteBatch,
}
pub struct Snapshot<'a> {
......@@ -51,7 +62,7 @@ pub struct Snapshot<'a> {
pub struct DBIterator<'a> {
db: &'a DB,
readopts: ReadOptions,
inner: rocksdb_ffi::DBIterator,
inner: *mut rocksdb_ffi::DBIterator,
}
pub enum SeekKey<'a> {
......@@ -149,14 +160,14 @@ impl<'a> DBIterator<'a> {
}
pub fn new_cf(db: &'a DB,
cf_handle: DBCFHandle,
cf_handle: &CFHandle,
readopts: ReadOptions)
-> DBIterator<'a> {
unsafe {
let iterator =
rocksdb_ffi::rocksdb_create_iterator_cf(db.inner,
readopts.get_inner(),
cf_handle);
cf_handle.inner);
DBIterator {
db: db,
readopts: readopts,
......@@ -219,7 +230,7 @@ impl<'a> Snapshot<'a> {
}
pub fn get_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8])
-> Result<Option<DBVector>, String> {
let mut readopts = ReadOptions::new();
......@@ -240,18 +251,18 @@ impl<'a> Drop for Snapshot<'a> {
pub trait Writable {
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String>;
fn put_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8])
-> Result<(), String>;
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String>;
fn merge_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8])
-> Result<(), String>;
fn delete(&self, key: &[u8]) -> Result<(), String>;
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String>;
fn delete_cf(&self, cf: &CFHandle, key: &[u8]) -> Result<(), String>;
}
/// A range of keys, `start_key` is included, but not `end_key`.
......@@ -326,32 +337,30 @@ impl DB {
.collect();
// These handles will be populated by DB.
let cfhandles: Vec<rocksdb_ffi::DBCFHandle> = cfs_v.iter()
.map(|_| rocksdb_ffi::DBCFHandle(0 as *mut c_void))
let cfhandles: Vec<_> = cfs_v.iter()
.map(|_| 0 as *mut DBCFHandle)
.collect();
let cfopts: Vec<_> = cf_opts_v.iter()
.map(|x| x.inner as *const rocksdb_ffi::DBOptions)
.collect();
let db: rocksdb_ffi::DBInstance;
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
unsafe {
db = rocksdb_ffi::rocksdb_open_column_families(opts.inner,
cpath.as_ptr() as *const _,
let mut err = 0 as *mut c_char;
let db = unsafe {
rocksdb_ffi::rocksdb_open_column_families(opts.inner,
cpath.as_ptr(),
cfs_v.len() as c_int,
cfnames.as_ptr() as *const _,
cfnames.as_ptr(),
cfopts.as_ptr(),
cfhandles.as_ptr(),
err_ptr);
}
&mut err)
};
if !err.is_null() {
return Err(error_message(err));
}
for handle in &cfhandles {
if handle.0.is_null() {
if handle.is_null() {
return Err("Received null column family handle from DB."
.to_owned());
}
......@@ -359,10 +368,10 @@ impl DB {
let mut cf_map = BTreeMap::new();
for (n, h) in cfs_v.iter().zip(cfhandles) {
cf_map.insert((*n).to_owned(), h);
cf_map.insert((*n).to_owned(), CFHandle { inner: h });
}
if db.0.is_null() {
if db.is_null() {
return Err("Could not initialize database.".to_owned());
}
......@@ -375,14 +384,9 @@ impl DB {
pub fn destroy(opts: &Options, path: &str) -> Result<(), String> {
let cpath = CString::new(path.as_bytes()).unwrap();
let cpath_ptr = cpath.as_ptr();
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
unsafe {
rocksdb_ffi::rocksdb_destroy_db(opts.inner,
cpath_ptr as *const _,
err_ptr);
rocksdb_ffi::rocksdb_destroy_db(opts.inner, cpath.as_ptr(), &mut err);
}
if !err.is_null() {
return Err(error_message(err));
......@@ -392,14 +396,9 @@ impl DB {
pub fn repair(opts: Options, path: &str) -> Result<(), String> {
let cpath = CString::new(path.as_bytes()).unwrap();
let cpath_ptr = cpath.as_ptr();
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
unsafe {
rocksdb_ffi::rocksdb_repair_db(opts.inner,
cpath_ptr as *const _,
err_ptr);
rocksdb_ffi::rocksdb_repair_db(opts.inner, cpath.as_ptr(), &mut err);
}
if !err.is_null() {
return Err(error_message(err));
......@@ -418,24 +417,23 @@ impl DB {
let mut cfs: Vec<String> = vec![];
unsafe {
let mut lencf: size_t = 0;
let mut err: *const i8 = 0 as *const i8;
let mut err = 0 as *mut c_char;
let list = rocksdb_ffi::rocksdb_list_column_families(opts.inner,
cpath.as_ptr() as *const _,
cpath.as_ptr(),
&mut lencf,
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
let list_cfs = slice::from_raw_parts(list, lencf);
for cf_name in list_cfs {
let len = libc::strlen(*cf_name);
let cf = match String::from_utf8(slice::from_raw_parts(*cf_name as *const u8, len).to_vec()) {
for &cf_name in list_cfs {
let cf = match CStr::from_ptr(cf_name).to_owned().into_string() {
Ok(s) => s,
Err(_) => return Err("Invalid utf8 bytes".to_owned()),
Err(e) => return Err(format!("invalid utf8 bytes: {:?}", e)),
};
cfs.push(cf);
}
rocksdb_ffi::rocksdb_list_column_families_destroy(list as *mut *mut _, lencf);
rocksdb_ffi::rocksdb_list_column_families_destroy(list, lencf);
}
Ok(cfs)
......@@ -449,13 +447,12 @@ impl DB {
batch: WriteBatch,
writeopts: &WriteOptions)
-> Result<(), String> {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
unsafe {
rocksdb_ffi::rocksdb_write(self.inner,
writeopts.inner,
batch.inner,
err_ptr);
&mut err);
}
if !err.is_null() {
return Err(error_message(err));
......@@ -480,15 +477,14 @@ impl DB {
unsafe {
let val_len: size_t = 0;
let val_len_ptr = &val_len as *const size_t;
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
let val =
rocksdb_ffi::rocksdb_get(self.inner,
readopts.get_inner(),
key.as_ptr(),
key.len() as size_t,
val_len_ptr,
err_ptr) as *mut u8;
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -505,23 +501,22 @@ impl DB {
}
pub fn get_cf_opt(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
readopts: &ReadOptions)
-> Result<Option<DBVector>, String> {
unsafe {
let val_len: size_t = 0;
let val_len_ptr = &val_len as *const size_t;
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
let val =
rocksdb_ffi::rocksdb_get_cf(self.inner,
readopts.get_inner(),
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t,
val_len_ptr,
err_ptr) as *mut u8;
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -534,7 +529,7 @@ impl DB {
}
pub fn get_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8])
-> Result<Option<DBVector>, String> {
self.get_cf_opt(cf, key, &ReadOptions::new())
......@@ -543,7 +538,7 @@ impl DB {
pub fn create_cf(&mut self,
name: &str,
opts: &Options)
-> Result<DBCFHandle, String> {
-> Result<&CFHandle, String> {
let cname = match CString::new(name.as_bytes()) {
Ok(c) => c,
Err(_) => {
......@@ -553,35 +548,41 @@ impl DB {
}
};
let cname_ptr = cname.as_ptr();
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let cf_handler = unsafe {
let mut err = 0 as *mut c_char;
unsafe {
let cf_handler =
rocksdb_ffi::rocksdb_create_column_family(self.inner,
opts.inner,
cname_ptr as *const _,
err_ptr);
self.cfs.insert(name.to_owned(), cf_handler);
cf_handler
};
if !err.is_null() {
return Err(error_message(err));
cname_ptr,
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
let handle = CFHandle { inner: cf_handler };
Ok(match self.cfs.entry(name.to_owned()) {
Entry::Occupied(mut e) => {
e.insert(handle);
e.into_mut()
},
Entry::Vacant(e) => {
e.insert(handle)
}
})
}
Ok(cf_handler)
}
pub fn drop_cf(&mut self, name: &str) -> Result<(), String> {
let cf = self.cfs.get(name);
let cf = self.cfs.remove(name);
if cf.is_none() {
return Err(format!("Invalid column family: {}", name).clone());
}
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
unsafe {
rocksdb_ffi::rocksdb_drop_column_family(self.inner,
*cf.unwrap(),
err_ptr);
cf.unwrap().inner,
&mut err);
}
if !err.is_null() {
return Err(error_message(err));
......@@ -590,7 +591,7 @@ impl DB {
Ok(())
}
pub fn cf_handle(&self, name: &str) -> Option<&DBCFHandle> {
pub fn cf_handle(&self, name: &str) -> Option<&CFHandle> {
self.cfs.get(name)
}
......@@ -608,9 +609,9 @@ impl DB {
DBIterator::new(&self, opt)
}
pub fn iter_cf(&self, cf_handle: DBCFHandle) -> DBIterator {
pub fn iter_cf(&self, cf_handle: &CFHandle) -> DBIterator {
let opts = ReadOptions::new();
DBIterator::new_cf(&self, cf_handle, opts)
DBIterator::new_cf(self, cf_handle, opts)
}
pub fn snapshot(&self) -> Snapshot {
......@@ -631,15 +632,14 @@ impl DB {
writeopts: &WriteOptions)
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_put(self.inner,
writeopts.inner,
key.as_ptr(),
key.len() as size_t,
value.as_ptr(),
value.len() as size_t,
err_ptr);
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -648,22 +648,21 @@ impl DB {
}
pub fn put_cf_opt(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8],
writeopts: &WriteOptions)
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_put_cf(self.inner,
writeopts.inner,
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t,
value.as_ptr(),
value.len() as size_t,
err_ptr);
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -676,15 +675,14 @@ impl DB {
writeopts: &WriteOptions)
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_merge(self.inner,
writeopts.inner,
key.as_ptr(),
key.len() as size_t,
value.as_ptr(),
value.len() as size_t,
err_ptr);
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -692,22 +690,21 @@ impl DB {
}
}
fn merge_cf_opt(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8],
writeopts: &WriteOptions)
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_merge_cf(self.inner,
writeopts.inner,
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t,
value.as_ptr(),
value.len() as size_t,
err_ptr);
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -719,33 +716,32 @@ impl DB {
writeopts: &WriteOptions)
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_delete(self.inner,
writeopts.inner,
key.as_ptr(),
key.len() as size_t,
err_ptr);
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
Ok(())
}
}
fn delete_cf_opt(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
writeopts: &WriteOptions)
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_delete_cf(self.inner,
writeopts.inner,
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t,
err_ptr);
&mut err);
if !err.is_null() {
return Err(error_message(err));
}
......@@ -762,7 +758,7 @@ impl DB {
unsafe {
let opts = rocksdb_ffi::rocksdb_flushoptions_create();
rocksdb_ffi::rocksdb_flushoptions_set_wait(opts, sync);
let mut err = 0 as *const i8;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_flush(self.inner, opts, &mut err);
rocksdb_ffi::rocksdb_flushoptions_destroy(opts);
if !err.is_null() {
......@@ -784,27 +780,27 @@ impl DB {
}
pub fn get_approximate_sizes_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
ranges: &[Range])
-> Vec<u64> {
self.get_approximate_sizes_cfopt(Some(cf), ranges)
}
fn get_approximate_sizes_cfopt(&self,
cf: Option<DBCFHandle>,
cf: Option<&CFHandle>,
ranges: &[Range])
-> Vec<u64> {
let start_keys: Vec<*const u8> = ranges.iter()
.map(|x| x.start_key.as_ptr())
.collect();
let start_key_lens: Vec<usize> = ranges.iter()
.map(|x| x.start_key.len() as usize)
let start_key_lens: Vec<_> = ranges.iter()
.map(|x| x.start_key.len())
.collect();
let end_keys: Vec<*const u8> = ranges.iter()
.map(|x| x.end_key.as_ptr())
.collect();
let end_key_lens: Vec<usize> = ranges.iter()
.map(|x| x.end_key.len() as usize)
let end_key_lens: Vec<_> = ranges.iter()
.map(|x| x.end_key.len())
.collect();
let mut sizes: Vec<u64> = vec![0; ranges.len()];
let (n,
......@@ -830,7 +826,7 @@ impl DB {
},
Some(cf) => unsafe {
rocksdb_ffi::rocksdb_approximate_sizes_cf(self.inner,
cf,
cf.inner,
n,
start_key_ptr,
start_key_len_ptr,
......@@ -847,7 +843,7 @@ impl DB {
end_key: &[u8])
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_delete_file_in_range(self.inner,
start_key.as_ptr(),
......@@ -863,15 +859,14 @@ impl DB {
}
pub fn delete_file_in_range_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
start_key: &[u8],
end_key: &[u8])
-> Result<(), String> {
unsafe {
let mut err: *const i8 = 0 as *const i8;
let mut err = 0 as *mut c_char;
rocksdb_ffi::rocksdb_delete_file_in_range_cf(self.inner,
cf,
cf.inner,
start_key.as_ptr(),
start_key.len() as size_t,
end_key.as_ptr(),
......@@ -889,7 +884,7 @@ impl DB {
}
pub fn get_property_value_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
name: &str)
-> Option<String> {
self.get_property_value_cf_opt(Some(cf), name)
......@@ -902,14 +897,14 @@ impl DB {
}
pub fn get_property_int_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
name: &str)
-> Option<u64> {
self.get_property_int_cf_opt(Some(cf), name)
}
fn get_property_value_cf_opt(&self,
cf: Option<DBCFHandle>,
cf: Option<&CFHandle>,
name: &str)
-> Option<String> {
unsafe {
......@@ -922,7 +917,7 @@ impl DB {
}
Some(cf) => {
rocksdb_ffi::rocksdb_property_value_cf(self.inner,
cf,
cf.inner,
prop_name.as_ptr())
}
};
......@@ -939,7 +934,7 @@ impl DB {
}
fn get_property_int_cf_opt(&self,
cf: Option<DBCFHandle>,
cf: Option<&CFHandle>,
name: &str)
-> Option<u64> {
// Rocksdb guarantees that the return property int
......@@ -960,7 +955,7 @@ impl Writable for DB {
}
fn put_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8])
-> Result<(), String> {
......@@ -972,7 +967,7 @@ impl Writable for DB {
}
fn merge_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8])
-> Result<(), String> {
......@@ -983,7 +978,7 @@ impl Writable for DB {
self.delete_opt(key, &WriteOptions::new())
}
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String> {
fn delete_cf(&self, cf: &CFHandle, key: &[u8]) -> Result<(), String> {
self.delete_cf_opt(cf, key, &WriteOptions::new())
}
}
......@@ -1019,9 +1014,7 @@ impl Drop for WriteBatch {
impl Drop for DB {
fn drop(&mut self) {
unsafe {
for cf in self.cfs.values() {
rocksdb_ffi::rocksdb_column_family_handle_destroy(*cf);
}
self.cfs.clear();
rocksdb_ffi::rocksdb_close(self.inner);
}
}
......@@ -1040,13 +1033,13 @@ impl Writable for WriteBatch {
}
fn put_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8])
-> Result<(), String> {
unsafe {
rocksdb_ffi::rocksdb_writebatch_put_cf(self.inner,
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t,
value.as_ptr(),
......@@ -1067,13 +1060,13 @@ impl Writable for WriteBatch {
}
fn merge_cf(&self,
cf: DBCFHandle,
cf: &CFHandle,
key: &[u8],
value: &[u8])
-> Result<(), String> {
unsafe {
rocksdb_ffi::rocksdb_writebatch_merge_cf(self.inner,
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t,
value.as_ptr(),
......@@ -1091,10 +1084,10 @@ impl Writable for WriteBatch {
}
}
fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String> {
fn delete_cf(&self, cf: &CFHandle, key: &[u8]) -> Result<(), String> {
unsafe {
rocksdb_ffi::rocksdb_writebatch_delete_cf(self.inner,
cf,
cf.inner,
key.as_ptr(),
key.len() as size_t);
Ok(())
......
......@@ -20,7 +20,7 @@ use merge_operator::{self, MergeOperatorCallback, full_merge_callback,
use merge_operator::MergeFn;
use rocksdb_ffi::{self, DBOptions, DBWriteOptions, DBBlockBasedTableOptions,
DBReadOptions, DBCompressionType, DBRecoveryMode};
DBReadOptions, DBCompressionType, DBRecoveryMode, DBSnapshot, DBInstance};
use std::ffi::CString;
use std::mem;
......@@ -97,15 +97,15 @@ impl BlockBasedOptions {
/// This object is convenient for wrapping snapshot by yourself. In most
/// cases, using `Snapshot` is enough.
pub struct UnsafeSnap {
inner: rocksdb_ffi::DBSnapshot,
inner: *const DBSnapshot,
}
impl UnsafeSnap {
pub unsafe fn new(db: rocksdb_ffi::DBInstance) -> UnsafeSnap {
pub unsafe fn new(db: *mut DBInstance) -> UnsafeSnap {
UnsafeSnap { inner: rocksdb_ffi::rocksdb_create_snapshot(db) }
}
pub unsafe fn get_inner(&self) -> rocksdb_ffi::DBSnapshot {
pub unsafe fn get_inner(&self) -> *const DBSnapshot {
self.inner
}
}
......
......@@ -73,7 +73,7 @@ pub fn test_column_family() {
}
Err(e) => panic!("failed to open db with column family: {}", e),
};
let cf1 = *db.cf_handle("cf1").unwrap();
let cf1 = db.cf_handle("cf1").unwrap();
assert!(db.put_cf(cf1, b"k1", b"v1").is_ok());
assert!(db.get_cf(cf1, b"k1").unwrap().unwrap().to_utf8().unwrap() ==
"v1");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment