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