small refactor to get CF's working on batches at the cost of OOB CF handling

master
Tyler Neely 9 years ago
parent c5e6fb30dd
commit a09580fec7
  1. BIN
      src/.ffi.rs.swo
  2. BIN
      src/.merge_operator.rs.swo
  3. BIN
      src/.rocksdb.rs.swo
  4. 6
      src/comparator.rs
  5. 330
      src/ffi.rs
  6. 4
      src/lib.rs
  7. 28
      src/main.rs
  8. 8
      src/merge_operator.rs
  9. 261
      src/rocksdb.rs
  10. 16
      src/rocksdb_options.rs
  11. BIN
      test/.test_column_family.rs.swo
  12. 45
      test/test_column_family.rs
  13. 6
      test/test_iterator.rs
  14. 8
      test/test_multithreaded.rs

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -21,7 +21,7 @@ use std::ptr;
use std::slice; use std::slice;
use rocksdb_options::Options; use rocksdb_options::Options;
use rocksdb::RocksDB; use rocksdb::DB;
pub struct ComparatorCallback { pub struct ComparatorCallback {
pub name: CString, pub name: CString,
@ -75,8 +75,8 @@ fn test_reverse_compare(a: &[u8], b: &[u8]) -> c_int {
// opts.create_if_missing(true); // opts.create_if_missing(true);
// opts.add_comparator("test comparator", test_reverse_compare); // opts.add_comparator("test comparator", test_reverse_compare);
// { // {
// let db = RocksDB::open(&opts, path).unwrap(); // let db = DB::open(&opts, path).unwrap();
// // TODO add interesting test // // TODO add interesting test
// } // }
// assert!(RocksDB::destroy(&opts, path).is_ok()); // assert!(DB::destroy(&opts, path).is_ok());
//} //}

@ -19,75 +19,75 @@ use std::ffi::CString;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBOptions(pub *const c_void); pub struct DBOptions(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBInstance(pub *const c_void); pub struct DBInstance(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBWriteOptions(pub *const c_void); pub struct DBWriteOptions(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBReadOptions(pub *const c_void); pub struct DBReadOptions(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBMergeOperator(pub *const c_void); pub struct DBMergeOperator(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBBlockBasedTableOptions(pub *const c_void); pub struct DBBlockBasedTableOptions(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBCache(pub *const c_void); pub struct DBCache(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBFilterPolicy(pub *const c_void); pub struct DBFilterPolicy(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBSnapshot(pub *const c_void); pub struct DBSnapshot(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBIterator(pub *const c_void); pub struct DBIterator(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBCFHandle(pub *const c_void); pub struct DBCFHandle(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBWriteBatch(pub *const c_void); pub struct DBWriteBatch(pub *const c_void);
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
pub struct RocksDBComparator(pub *const c_void); pub struct DBComparator(pub *const c_void);
pub fn new_bloom_filter(bits: c_int) -> RocksDBFilterPolicy { pub fn new_bloom_filter(bits: c_int) -> DBFilterPolicy {
unsafe { unsafe {
rocksdb_filterpolicy_create_bloom(bits) rocksdb_filterpolicy_create_bloom(bits)
} }
} }
pub fn new_cache(capacity: size_t) -> RocksDBCache { pub fn new_cache(capacity: size_t) -> DBCache {
unsafe { unsafe {
rocksdb_cache_create_lru(capacity) rocksdb_cache_create_lru(capacity)
} }
} }
#[repr(C)] #[repr(C)]
pub enum RocksDBCompressionType { pub enum DBCompressionType {
RocksDBNoCompression = 0, DBNoCompression = 0,
RocksDBSnappyCompression = 1, DBSnappyCompression = 1,
RocksDBZlibCompression = 2, DBZlibCompression = 2,
RocksDBBz2Compression = 3, DBBz2Compression = 3,
RocksDBLz4Compression = 4, DBLz4Compression = 4,
RocksDBLz4hcCompression = 5, DBLz4hcCompression = 5,
} }
#[repr(C)] #[repr(C)]
pub enum RocksDBCompactionStyle { pub enum DBCompactionStyle {
RocksDBLevelCompaction = 0, DBLevelCompaction = 0,
RocksDBUniversalCompaction = 1, DBUniversalCompaction = 1,
RocksDBFifoCompaction = 2, DBFifoCompaction = 2,
} }
#[repr(C)] #[repr(C)]
pub enum RocksDBUniversalCompactionStyle { pub enum DBUniversalCompactionStyle {
rocksdb_similar_size_compaction_stop_style = 0, rocksdb_similar_size_compaction_stop_style = 0,
rocksdb_total_size_compaction_stop_style = 1, rocksdb_total_size_compaction_stop_style = 1,
} }
@ -95,178 +95,178 @@ pub enum RocksDBUniversalCompactionStyle {
//TODO audit the use of boolean arguments, b/c I think they need to be u8 instead... //TODO audit the use of boolean arguments, b/c I think they need to be u8 instead...
#[link(name = "rocksdb")] #[link(name = "rocksdb")]
extern { extern {
pub fn rocksdb_options_create() -> RocksDBOptions; pub fn rocksdb_options_create() -> DBOptions;
pub fn rocksdb_options_destroy(opts: RocksDBOptions); pub fn rocksdb_options_destroy(opts: DBOptions);
pub fn rocksdb_cache_create_lru(capacity: size_t) -> RocksDBCache; pub fn rocksdb_cache_create_lru(capacity: size_t) -> DBCache;
pub fn rocksdb_cache_destroy(cache: RocksDBCache); pub fn rocksdb_cache_destroy(cache: DBCache);
pub fn rocksdb_block_based_options_create() -> RocksDBBlockBasedTableOptions; pub fn rocksdb_block_based_options_create() -> DBBlockBasedTableOptions;
pub fn rocksdb_block_based_options_destroy(opts: RocksDBBlockBasedTableOptions); pub fn rocksdb_block_based_options_destroy(opts: DBBlockBasedTableOptions);
pub fn rocksdb_block_based_options_set_block_size( pub fn rocksdb_block_based_options_set_block_size(
block_options: RocksDBBlockBasedTableOptions, block_options: DBBlockBasedTableOptions,
block_size: size_t); block_size: size_t);
pub fn rocksdb_block_based_options_set_block_size_deviation( pub fn rocksdb_block_based_options_set_block_size_deviation(
block_options: RocksDBBlockBasedTableOptions, block_options: DBBlockBasedTableOptions,
block_size_deviation: c_int); block_size_deviation: c_int);
pub fn rocksdb_block_based_options_set_block_restart_interval( pub fn rocksdb_block_based_options_set_block_restart_interval(
block_options: RocksDBBlockBasedTableOptions, block_options: DBBlockBasedTableOptions,
block_restart_interval: c_int); block_restart_interval: c_int);
pub fn rocksdb_block_based_options_set_filter_policy( pub fn rocksdb_block_based_options_set_filter_policy(
block_options: RocksDBBlockBasedTableOptions, block_options: DBBlockBasedTableOptions,
filter_policy: RocksDBFilterPolicy); filter_policy: DBFilterPolicy);
pub fn rocksdb_block_based_options_set_no_block_cache( pub fn rocksdb_block_based_options_set_no_block_cache(
block_options: RocksDBBlockBasedTableOptions, no_block_cache: bool); block_options: 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: RocksDBBlockBasedTableOptions, block_cache: RocksDBCache); block_options: DBBlockBasedTableOptions, block_cache: DBCache);
pub fn rocksdb_block_based_options_set_block_cache_compressed( pub fn rocksdb_block_based_options_set_block_cache_compressed(
block_options: RocksDBBlockBasedTableOptions, block_options: DBBlockBasedTableOptions,
block_cache_compressed: RocksDBCache); block_cache_compressed: DBCache);
pub fn rocksdb_block_based_options_set_whole_key_filtering( pub fn rocksdb_block_based_options_set_whole_key_filtering(
ck_options: RocksDBBlockBasedTableOptions, doit: bool); ck_options: DBBlockBasedTableOptions, doit: bool);
pub fn rocksdb_options_set_block_based_table_factory( pub fn rocksdb_options_set_block_based_table_factory(
options: RocksDBOptions, options: DBOptions,
block_options: RocksDBBlockBasedTableOptions); block_options: DBBlockBasedTableOptions);
pub fn rocksdb_options_increase_parallelism( pub fn rocksdb_options_increase_parallelism(
options: RocksDBOptions, threads: c_int); options: DBOptions, threads: c_int);
pub fn rocksdb_options_optimize_level_style_compaction( pub fn rocksdb_options_optimize_level_style_compaction(
options: RocksDBOptions, memtable_memory_budget: c_int); options: DBOptions, memtable_memory_budget: c_int);
pub fn rocksdb_options_set_create_if_missing( pub fn rocksdb_options_set_create_if_missing(
options: RocksDBOptions, v: bool); options: DBOptions, v: bool);
pub fn rocksdb_options_set_max_open_files( pub fn rocksdb_options_set_max_open_files(
options: RocksDBOptions, files: c_int); options: DBOptions, files: c_int);
pub fn rocksdb_options_set_use_fsync( pub fn rocksdb_options_set_use_fsync(
options: RocksDBOptions, v: c_int); options: DBOptions, v: c_int);
pub fn rocksdb_options_set_bytes_per_sync( pub fn rocksdb_options_set_bytes_per_sync(
options: RocksDBOptions, bytes: u64); options: DBOptions, bytes: u64);
pub fn rocksdb_options_set_disable_data_sync( pub fn rocksdb_options_set_disable_data_sync(
options: RocksDBOptions, v: c_int); options: DBOptions, v: c_int);
pub fn rocksdb_options_optimize_for_point_lookup( pub fn rocksdb_options_optimize_for_point_lookup(
options: RocksDBOptions, block_cache_size_mb: u64); options: DBOptions, block_cache_size_mb: u64);
pub fn rocksdb_options_set_table_cache_numshardbits( pub fn rocksdb_options_set_table_cache_numshardbits(
options: RocksDBOptions, bits: c_int); options: DBOptions, bits: c_int);
pub fn rocksdb_options_set_max_write_buffer_number( pub fn rocksdb_options_set_max_write_buffer_number(
options: RocksDBOptions, bufno: c_int); options: DBOptions, bufno: c_int);
pub fn rocksdb_options_set_min_write_buffer_number_to_merge( pub fn rocksdb_options_set_min_write_buffer_number_to_merge(
options: RocksDBOptions, bufno: c_int); options: DBOptions, bufno: c_int);
pub fn rocksdb_options_set_level0_file_num_compaction_trigger( pub fn rocksdb_options_set_level0_file_num_compaction_trigger(
options: RocksDBOptions, no: c_int); options: DBOptions, no: c_int);
pub fn rocksdb_options_set_level0_slowdown_writes_trigger( pub fn rocksdb_options_set_level0_slowdown_writes_trigger(
options: RocksDBOptions, no: c_int); options: DBOptions, no: c_int);
pub fn rocksdb_options_set_level0_stop_writes_trigger( pub fn rocksdb_options_set_level0_stop_writes_trigger(
options: RocksDBOptions, no: c_int); options: DBOptions, no: c_int);
pub fn rocksdb_options_set_write_buffer_size( pub fn rocksdb_options_set_write_buffer_size(
options: RocksDBOptions, bytes: u64); options: DBOptions, bytes: u64);
pub fn rocksdb_options_set_target_file_size_base( pub fn rocksdb_options_set_target_file_size_base(
options: RocksDBOptions, bytes: u64); options: DBOptions, bytes: u64);
pub fn rocksdb_options_set_target_file_size_multiplier( pub fn rocksdb_options_set_target_file_size_multiplier(
options: RocksDBOptions, mul: c_int); options: DBOptions, mul: c_int);
pub fn rocksdb_options_set_max_log_file_size( pub fn rocksdb_options_set_max_log_file_size(
options: RocksDBOptions, bytes: u64); options: DBOptions, bytes: u64);
pub fn rocksdb_options_set_max_manifest_file_size( pub fn rocksdb_options_set_max_manifest_file_size(
options: RocksDBOptions, bytes: u64); options: DBOptions, bytes: u64);
pub fn rocksdb_options_set_hash_skip_list_rep( pub fn rocksdb_options_set_hash_skip_list_rep(
options: RocksDBOptions, bytes: u64, a1: i32, a2: i32); options: DBOptions, bytes: u64, a1: i32, a2: i32);
pub fn rocksdb_options_set_compaction_style( pub fn rocksdb_options_set_compaction_style(
options: RocksDBOptions, cs: RocksDBCompactionStyle); options: DBOptions, cs: DBCompactionStyle);
pub fn rocksdb_options_set_compression( pub fn rocksdb_options_set_compression(
options: RocksDBOptions, compression_style_no: c_int); options: DBOptions, compression_style_no: c_int);
pub fn rocksdb_options_set_max_background_compactions( pub fn rocksdb_options_set_max_background_compactions(
options: RocksDBOptions, max_bg_compactions: c_int); options: DBOptions, max_bg_compactions: c_int);
pub fn rocksdb_options_set_max_background_flushes( pub fn rocksdb_options_set_max_background_flushes(
options: RocksDBOptions, max_bg_flushes: c_int); options: DBOptions, max_bg_flushes: c_int);
pub fn rocksdb_options_set_filter_deletes( pub fn rocksdb_options_set_filter_deletes(
options: RocksDBOptions, v: bool); options: DBOptions, v: bool);
pub fn rocksdb_options_set_disable_auto_compactions( pub fn rocksdb_options_set_disable_auto_compactions(
options: RocksDBOptions, v: c_int); options: DBOptions, v: c_int);
pub fn rocksdb_filterpolicy_create_bloom( pub fn rocksdb_filterpolicy_create_bloom(
bits_per_key: c_int) -> RocksDBFilterPolicy; bits_per_key: c_int) -> DBFilterPolicy;
pub fn rocksdb_open(options: RocksDBOptions, pub fn rocksdb_open(options: DBOptions,
path: *const i8, path: *const i8,
err: *mut *const i8 err: *mut *const i8
) -> RocksDBInstance; ) -> DBInstance;
pub fn rocksdb_writeoptions_create() -> RocksDBWriteOptions; pub fn rocksdb_writeoptions_create() -> DBWriteOptions;
pub fn rocksdb_writeoptions_destroy(writeopts: RocksDBWriteOptions); pub fn rocksdb_writeoptions_destroy(writeopts: DBWriteOptions);
pub fn rocksdb_put(db: RocksDBInstance, pub fn rocksdb_put(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
v: *const u8, vLen: size_t, v: *const u8, vLen: size_t,
err: *mut *const i8); err: *mut *const i8);
pub fn rocksdb_put_cf(db: RocksDBInstance, pub fn rocksdb_put_cf(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
cf: RocksDBCFHandle, cf: DBCFHandle,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
v: *const u8, vLen: size_t, v: *const u8, vLen: size_t,
err: *mut *const i8); err: *mut *const i8);
pub fn rocksdb_readoptions_create() -> RocksDBReadOptions; pub fn rocksdb_readoptions_create() -> DBReadOptions;
pub fn rocksdb_readoptions_destroy(readopts: RocksDBReadOptions); pub fn rocksdb_readoptions_destroy(readopts: DBReadOptions);
pub fn rocksdb_readoptions_set_verify_checksums( pub fn rocksdb_readoptions_set_verify_checksums(
readopts: RocksDBReadOptions, readopts: DBReadOptions,
v: bool); v: bool);
pub fn rocksdb_readoptions_set_fill_cache( pub fn rocksdb_readoptions_set_fill_cache(
readopts: RocksDBReadOptions, readopts: DBReadOptions,
v: bool); v: bool);
pub fn rocksdb_readoptions_set_snapshot( pub fn rocksdb_readoptions_set_snapshot(
readopts: RocksDBReadOptions, readopts: DBReadOptions,
snapshot: RocksDBSnapshot); //TODO how do I make this a const ref? snapshot: DBSnapshot); //TODO how do I make this a const ref?
pub fn rocksdb_readoptions_set_iterate_upper_bound( pub fn rocksdb_readoptions_set_iterate_upper_bound(
readopts: RocksDBReadOptions, readopts: DBReadOptions,
k: *const u8, k: *const u8,
kLen: size_t); kLen: size_t);
pub fn rocksdb_readoptions_set_read_tier( pub fn rocksdb_readoptions_set_read_tier(
readopts: RocksDBReadOptions, readopts: DBReadOptions,
tier: c_int); tier: c_int);
pub fn rocksdb_readoptions_set_tailing( pub fn rocksdb_readoptions_set_tailing(
readopts: RocksDBReadOptions, readopts: DBReadOptions,
v: bool); v: bool);
pub fn rocksdb_get(db: RocksDBInstance, pub fn rocksdb_get(db: DBInstance,
readopts: RocksDBReadOptions, readopts: DBReadOptions,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
valLen: *const size_t, valLen: *const size_t,
err: *mut *const i8 err: *mut *const i8
) -> *mut c_void; ) -> *mut c_void;
pub fn rocksdb_get_cf(db: RocksDBInstance, pub fn rocksdb_get_cf(db: DBInstance,
readopts: RocksDBReadOptions, readopts: DBReadOptions,
cf_handle: RocksDBCFHandle, cf_handle: DBCFHandle,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
valLen: *const size_t, valLen: *const size_t,
err: *mut *const i8 err: *mut *const i8
) -> *mut c_void; ) -> *mut c_void;
pub fn rocksdb_create_iterator(db: RocksDBInstance, pub fn rocksdb_create_iterator(db: DBInstance,
readopts: RocksDBReadOptions readopts: DBReadOptions
) -> RocksDBIterator; ) -> DBIterator;
pub fn rocksdb_create_iterator_cf(db: RocksDBInstance, pub fn rocksdb_create_iterator_cf(db: DBInstance,
readopts: RocksDBReadOptions, readopts: DBReadOptions,
cf_handle: RocksDBCFHandle cf_handle: DBCFHandle
) -> RocksDBIterator; ) -> DBIterator;
pub fn rocksdb_create_snapshot(db: RocksDBInstance) -> RocksDBSnapshot; pub fn rocksdb_create_snapshot(db: DBInstance) -> DBSnapshot;
pub fn rocksdb_release_snapshot(db: RocksDBInstance, pub fn rocksdb_release_snapshot(db: DBInstance,
snapshot: RocksDBSnapshot); snapshot: DBSnapshot);
pub fn rocksdb_delete(db: RocksDBInstance, pub fn rocksdb_delete(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
err: *mut *const i8 err: *mut *const i8
) -> *mut c_void; ) -> *mut c_void;
pub fn rocksdb_delete_cf(db: RocksDBInstance, pub fn rocksdb_delete_cf(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
cf: RocksDBCFHandle, cf: DBCFHandle,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
err: *mut *const i8 err: *mut *const i8
) -> *mut c_void; ) -> *mut c_void;
pub fn rocksdb_close(db: RocksDBInstance); pub fn rocksdb_close(db: DBInstance);
pub fn rocksdb_destroy_db(options: RocksDBOptions, pub fn rocksdb_destroy_db(options: DBOptions,
path: *const i8, err: *mut *const i8); path: *const i8, err: *mut *const i8);
pub fn rocksdb_repair_db(options: RocksDBOptions, pub fn rocksdb_repair_db(options: DBOptions,
path: *const i8, err: *mut *const i8); path: *const i8, err: *mut *const i8);
// Merge // Merge
pub fn rocksdb_merge(db: RocksDBInstance, pub fn rocksdb_merge(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
v: *const u8, vLen: size_t, v: *const u8, vLen: size_t,
err: *mut *const i8); err: *mut *const i8);
pub fn rocksdb_merge_cf(db: RocksDBInstance, pub fn rocksdb_merge_cf(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
cf: RocksDBCFHandle, cf: DBCFHandle,
k: *const u8, kLen: size_t, k: *const u8, kLen: size_t,
v: *const u8, vLen: size_t, v: *const u8, vLen: size_t,
err: *mut *const i8); err: *mut *const i8);
@ -294,73 +294,73 @@ extern {
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,
) -> RocksDBMergeOperator; ) -> DBMergeOperator;
pub fn rocksdb_mergeoperator_destroy(mo: RocksDBMergeOperator); pub fn rocksdb_mergeoperator_destroy(mo: DBMergeOperator);
pub fn rocksdb_options_set_merge_operator(options: RocksDBOptions, pub fn rocksdb_options_set_merge_operator(options: DBOptions,
mo: RocksDBMergeOperator); mo: DBMergeOperator);
// Iterator // Iterator
pub fn rocksdb_iter_destroy(iter: RocksDBIterator); pub fn rocksdb_iter_destroy(iter: DBIterator);
pub fn rocksdb_iter_valid(iter: RocksDBIterator) -> bool; pub fn rocksdb_iter_valid(iter: DBIterator) -> bool;
pub fn rocksdb_iter_seek_to_first(iter: RocksDBIterator); pub fn rocksdb_iter_seek_to_first(iter: DBIterator);
pub fn rocksdb_iter_seek_to_last(iter: RocksDBIterator); pub fn rocksdb_iter_seek_to_last(iter: DBIterator);
pub fn rocksdb_iter_seek(iter: RocksDBIterator, pub fn rocksdb_iter_seek(iter: DBIterator,
key: *const u8, klen: size_t); key: *const u8, klen: size_t);
pub fn rocksdb_iter_next(iter: RocksDBIterator); pub fn rocksdb_iter_next(iter: DBIterator);
pub fn rocksdb_iter_prev(iter: RocksDBIterator); pub fn rocksdb_iter_prev(iter: DBIterator);
pub fn rocksdb_iter_key(iter: RocksDBIterator, pub fn rocksdb_iter_key(iter: DBIterator,
klen: *mut size_t) -> *mut u8; klen: *mut size_t) -> *mut u8;
pub fn rocksdb_iter_value(iter: RocksDBIterator, pub fn rocksdb_iter_value(iter: DBIterator,
vlen: *mut size_t) -> *mut u8; vlen: *mut size_t) -> *mut u8;
pub fn rocksdb_iter_get_error(iter: RocksDBIterator, pub fn rocksdb_iter_get_error(iter: DBIterator,
err: *mut *const u8); err: *mut *const u8);
// Write batch // Write batch
pub fn rocksdb_write(db: RocksDBInstance, pub fn rocksdb_write(db: DBInstance,
writeopts: RocksDBWriteOptions, writeopts: DBWriteOptions,
batch : RocksDBWriteBatch, batch : DBWriteBatch,
err: *mut *const i8); err: *mut *const i8);
pub fn rocksdb_writebatch_create() -> RocksDBWriteBatch; pub fn rocksdb_writebatch_create() -> DBWriteBatch;
pub fn rocksdb_writebatch_create_from(rep: *const u8, pub fn rocksdb_writebatch_create_from(rep: *const u8,
size: size_t) -> RocksDBWriteBatch; size: size_t) -> DBWriteBatch;
pub fn rocksdb_writebatch_destroy(batch: RocksDBWriteBatch); pub fn rocksdb_writebatch_destroy(batch: DBWriteBatch);
pub fn rocksdb_writebatch_clear(batch: RocksDBWriteBatch); pub fn rocksdb_writebatch_clear(batch: DBWriteBatch);
pub fn rocksdb_writebatch_count(batch: RocksDBWriteBatch) -> c_int; pub fn rocksdb_writebatch_count(batch: DBWriteBatch) -> c_int;
pub fn rocksdb_writebatch_put(batch: RocksDBWriteBatch, pub fn rocksdb_writebatch_put(batch: DBWriteBatch,
key: *const u8, klen: size_t, key: *const u8, klen: size_t,
val: *const u8, vlen: size_t); val: *const u8, vlen: size_t);
pub fn rocksdb_writebatch_put_cf(batch: RocksDBWriteBatch, pub fn rocksdb_writebatch_put_cf(batch: DBWriteBatch,
cf: RocksDBCFHandle, cf: DBCFHandle,
key: *const u8, klen: size_t, key: *const u8, klen: size_t,
val: *const u8, vlen: size_t); val: *const u8, vlen: size_t);
pub fn rocksdb_writebatch_merge( pub fn rocksdb_writebatch_merge(
batch: RocksDBWriteBatch, batch: DBWriteBatch,
key: *const u8, klen: size_t, key: *const u8, klen: size_t,
val: *const u8, vlen: size_t); val: *const u8, vlen: size_t);
pub fn rocksdb_writebatch_merge_cf( pub fn rocksdb_writebatch_merge_cf(
batch: RocksDBWriteBatch, batch: DBWriteBatch,
cf: RocksDBCFHandle, cf: DBCFHandle,
key: *const u8, klen: size_t, key: *const u8, klen: size_t,
val: *const u8, vlen: size_t); val: *const u8, vlen: size_t);
pub fn rocksdb_writebatch_delete( pub fn rocksdb_writebatch_delete(
batch: RocksDBWriteBatch, batch: DBWriteBatch,
key: *const u8, klen: size_t); key: *const u8, klen: size_t);
pub fn rocksdb_writebatch_delete_cf( pub fn rocksdb_writebatch_delete_cf(
batch: RocksDBWriteBatch, batch: DBWriteBatch,
cf: RocksDBCFHandle, cf: DBCFHandle,
key: *const u8, klen: size_t); key: *const u8, klen: size_t);
pub fn rocksdb_writebatch_iterate( pub fn rocksdb_writebatch_iterate(
batch: RocksDBWriteBatch, batch: 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: RocksDBWriteBatch, pub fn rocksdb_writebatch_data(batch: DBWriteBatch,
size: *mut size_t) -> *const u8; size: *mut size_t) -> *const u8;
// Comparator // Comparator
pub fn rocksdb_options_set_comparator(options: RocksDBOptions, pub fn rocksdb_options_set_comparator(options: DBOptions,
cb: RocksDBComparator); cb: DBComparator);
pub fn rocksdb_comparator_create( pub fn rocksdb_comparator_create(
state: *mut c_void, state: *mut c_void,
destroy: extern fn(*mut c_void) -> (), destroy: extern fn(*mut c_void) -> (),
@ -369,27 +369,27 @@ extern {
b: *const c_char, blen: size_t b: *const c_char, blen: size_t
) -> c_int, ) -> c_int,
name_fn: extern fn(*mut c_void) -> *const c_char name_fn: extern fn(*mut c_void) -> *const c_char
) -> RocksDBComparator; ) -> DBComparator;
pub fn rocksdb_comparator_destroy(cmp: RocksDBComparator); pub fn rocksdb_comparator_destroy(cmp: DBComparator);
// Column Family // Column Family
pub fn rocksdb_open_column_families(options: RocksDBOptions, pub fn rocksdb_open_column_families(options: DBOptions,
path: *const i8, path: *const i8,
num_column_families: c_int, num_column_families: c_int,
column_family_names: *const *const i8, column_family_names: *const *const i8,
column_family_options: *const RocksDBOptions, column_family_options: *const DBOptions,
column_family_handles: *const RocksDBCFHandle, column_family_handles: *const DBCFHandle,
err: *mut *const i8 err: *mut *const i8
) -> RocksDBInstance; ) -> DBInstance;
pub fn rocksdb_create_column_family(db: RocksDBInstance, pub fn rocksdb_create_column_family(db: DBInstance,
column_family_options: RocksDBOptions, column_family_options: DBOptions,
column_family_name: *const i8, column_family_name: *const i8,
err: *mut *const i8 err: *mut *const i8
) -> RocksDBCFHandle; ) -> DBCFHandle;
pub fn rocksdb_drop_column_family(db: RocksDBInstance, pub fn rocksdb_drop_column_family(db: DBInstance,
column_family_handle: RocksDBCFHandle, column_family_handle: DBCFHandle,
err: *mut *const i8); err: *mut *const i8);
pub fn rocksdb_column_family_handle_destroy(column_family_handle: RocksDBCFHandle); pub fn rocksdb_column_family_handle_destroy(column_family_handle: DBCFHandle);
} }

@ -17,8 +17,8 @@
#![crate_type = "lib"] #![crate_type = "lib"]
pub use ffi as rocksdb_ffi; pub use ffi as rocksdb_ffi;
pub use ffi::{new_bloom_filter, RocksDBCompactionStyle, RocksDBComparator}; pub use ffi::{new_bloom_filter, DBCompactionStyle, DBComparator};
pub use rocksdb::{RocksDB, RocksDBResult, RocksDBVector, WriteBatch, Writable, Direction}; pub use rocksdb::{DB, DBResult, DBVector, WriteBatch, Writable, Direction};
pub use rocksdb_options::{Options, BlockBasedOptions}; pub use rocksdb_options::{Options, BlockBasedOptions};
pub use merge_operator::MergeOperands; pub use merge_operator::MergeOperands;
pub mod rocksdb; pub mod rocksdb;

@ -14,13 +14,13 @@
limitations under the License. limitations under the License.
*/ */
extern crate rocksdb; extern crate rocksdb;
use rocksdb::{Options, RocksDB, MergeOperands, new_bloom_filter, Writable, }; use rocksdb::{Options, DB, MergeOperands, new_bloom_filter, Writable, };
use rocksdb::RocksDBCompactionStyle::RocksDBUniversalCompaction; use rocksdb::DBCompactionStyle::DBUniversalCompaction;
//fn snapshot_test() { //fn snapshot_test() {
// let path = "_rust_rocksdb_iteratortest"; // let path = "_rust_rocksdb_iteratortest";
// { // {
// let mut db = RocksDB::open_default(path).unwrap(); // let mut db = DB::open_default(path).unwrap();
// let p = db.put(b"k1", b"v1111"); // let p = db.put(b"k1", b"v1111");
// assert!(p.is_ok()); // assert!(p.is_ok());
// let p = db.put(b"k2", b"v2222"); // let p = db.put(b"k2", b"v2222");
@ -41,13 +41,13 @@ use rocksdb::RocksDBCompactionStyle::RocksDBUniversalCompaction;
// }; // };
// } // }
// let opts = Options::new(); // let opts = Options::new();
// assert!(RocksDB::destroy(&opts, path).is_ok()); // assert!(DB::destroy(&opts, path).is_ok());
//} //}
#[cfg(not(feature = "valgrind"))] #[cfg(not(feature = "valgrind"))]
fn main() { fn main() {
let path = "/tmp/rust-rocksdb"; let path = "/tmp/rust-rocksdb";
let mut db = RocksDB::open_default(path).unwrap(); let mut db = DB::open_default(path).unwrap();
assert!(db.put(b"my key", b"my value").is_ok()); assert!(db.put(b"my key", b"my value").is_ok());
db.get(b"my key").map( |value| { db.get(b"my key").map( |value| {
match value.to_utf8() { match value.to_utf8() {
@ -88,7 +88,7 @@ fn custom_merge() {
opts.create_if_missing(true); opts.create_if_missing(true);
opts.add_merge_operator("test operator", concat_merge); opts.add_merge_operator("test operator", concat_merge);
{ {
let mut db = RocksDB::open(&opts, path).unwrap(); let mut db = DB::open(&opts, path).unwrap();
db.put(b"k1", b"a"); db.put(b"k1", b"a");
db.merge(b"k1", b"b"); db.merge(b"k1", b"b");
db.merge(b"k1", b"c"); db.merge(b"k1", b"c");
@ -107,7 +107,7 @@ fn custom_merge() {
.on_error( |e| { println!("error retrieving value: {}", e) }); .on_error( |e| { println!("error retrieving value: {}", e) });
} }
RocksDB::destroy(&opts, path).is_ok(); DB::destroy(&opts, path).is_ok();
} }
#[cfg(feature = "valgrind")] #[cfg(feature = "valgrind")]
@ -116,7 +116,7 @@ fn main() {
let mut opts = Options::new(); let mut opts = Options::new();
opts.create_if_missing(true); opts.create_if_missing(true);
opts.add_merge_operator("test operator", concat_merge); opts.add_merge_operator("test operator", concat_merge);
let db = RocksDB::open(&opts, path).unwrap(); let db = DB::open(&opts, path).unwrap();
loop { loop {
db.put(b"k1", b"a"); db.put(b"k1", b"a");
db.merge(b"k1", b"b"); db.merge(b"k1", b"b");
@ -141,10 +141,10 @@ fn main() {
mod tests { mod tests {
use std::thread::sleep_ms; use std::thread::sleep_ms;
use rocksdb::{BlockBasedOptions, Options, RocksDB, MergeOperands, new_bloom_filter, Writable }; use rocksdb::{BlockBasedOptions, Options, DB, MergeOperands, new_bloom_filter, Writable };
use rocksdb::RocksDBCompactionStyle::RocksDBUniversalCompaction; use rocksdb::DBCompactionStyle::DBUniversalCompaction;
fn tuned_for_somebody_elses_disk(path: &str, opts: & mut Options, blockopts: &mut BlockBasedOptions) -> RocksDB { fn tuned_for_somebody_elses_disk(path: &str, opts: & mut Options, blockopts: &mut BlockBasedOptions) -> DB {
opts.create_if_missing(true); opts.create_if_missing(true);
opts.set_max_open_files(10000); opts.set_max_open_files(10000);
opts.set_use_fsync(false); opts.set_use_fsync(false);
@ -158,7 +158,7 @@ mod tests {
opts.set_min_write_buffer_number_to_merge(4); opts.set_min_write_buffer_number_to_merge(4);
opts.set_level_zero_stop_writes_trigger(2000); opts.set_level_zero_stop_writes_trigger(2000);
opts.set_level_zero_slowdown_writes_trigger(0); opts.set_level_zero_slowdown_writes_trigger(0);
opts.set_compaction_style(RocksDBUniversalCompaction); opts.set_compaction_style(DBUniversalCompaction);
opts.set_max_background_compactions(4); opts.set_max_background_compactions(4);
opts.set_max_background_flushes(4); opts.set_max_background_flushes(4);
opts.set_filter_deletes(false); opts.set_filter_deletes(false);
@ -169,7 +169,7 @@ mod tests {
let filter = new_bloom_filter(10); let filter = new_bloom_filter(10);
//opts.set_filter(filter); //opts.set_filter(filter);
RocksDB::open(&opts, path).unwrap() DB::open(&opts, path).unwrap()
} }
/* TODO(tyler) unstable /* TODO(tyler) unstable
@ -204,7 +204,7 @@ mod tests {
i += 1; i += 1;
}); });
} }
RocksDB::destroy(&opts, path).is_ok(); DB::destroy(&opts, path).is_ok();
} }
*/ */
} }

@ -21,7 +21,7 @@ use std::ptr;
use std::slice; use std::slice;
use rocksdb_options::Options; use rocksdb_options::Options;
use rocksdb::{RocksDB, RocksDBResult, RocksDBVector, Writable}; use rocksdb::{DB, DBResult, DBVector, Writable};
pub struct MergeOperatorCallback { pub struct MergeOperatorCallback {
pub name: CString, pub name: CString,
@ -187,7 +187,7 @@ fn mergetest() {
opts.create_if_missing(true); opts.create_if_missing(true);
opts.add_merge_operator("test operator", test_provided_merge); opts.add_merge_operator("test operator", test_provided_merge);
{ {
let mut db = RocksDB::open(&opts, path).unwrap(); let mut db = DB::open(&opts, path).unwrap();
let p = db.put(b"k1", b"a"); let p = db.put(b"k1", b"a");
assert!(p.is_ok()); assert!(p.is_ok());
db.merge(b"k1", b"b"); db.merge(b"k1", b"b");
@ -207,10 +207,10 @@ fn mergetest() {
.on_error( |e| { println!("error reading value")}); //: {", e) }); .on_error( |e| { println!("error reading value")}); //: {", e) });
assert!(m.is_ok()); assert!(m.is_ok());
let r: RocksDBResult<RocksDBVector, String> = db.get(b"k1"); let r: DBResult<DBVector, String> = db.get(b"k1");
assert!(r.unwrap().to_utf8().unwrap() == "abcdefgh"); assert!(r.unwrap().to_utf8().unwrap() == "abcdefgh");
assert!(db.delete(b"k1").is_ok()); assert!(db.delete(b"k1").is_ok());
assert!(db.get(b"k1").is_none()); assert!(db.get(b"k1").is_none());
} }
assert!(RocksDB::destroy(&opts, path).is_ok()); assert!(DB::destroy(&opts, path).is_ok());
} }

@ -15,43 +15,46 @@
*/ */
extern crate libc; extern crate libc;
use self::libc::{c_void, size_t};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ffi::{CString, CStr}; use std::ffi::{CString, CStr};
use std::fs; use std::fs;
use std::io;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::slice; use std::slice;
use std::str::from_utf8; use std::str::from_utf8;
use rocksdb_ffi; use self::libc::{c_void, size_t};
use rocksdb_ffi::{self, DBCFHandle};
use rocksdb_options::Options; use rocksdb_options::Options;
pub struct RocksDB { pub struct DB {
inner: rocksdb_ffi::RocksDBInstance, inner: rocksdb_ffi::DBInstance,
cfs: BTreeMap<String, rocksdb_ffi::RocksDBCFHandle>, cfs: BTreeMap<String, DBCFHandle>,
} }
unsafe impl Send for RocksDB {} unsafe impl Send for DB {}
unsafe impl Sync for RocksDB {} unsafe impl Sync for DB {}
pub struct WriteBatch { pub struct WriteBatch {
inner: rocksdb_ffi::RocksDBWriteBatch, inner: rocksdb_ffi::DBWriteBatch,
} }
pub struct ReadOptions { pub struct ReadOptions {
inner: rocksdb_ffi::RocksDBReadOptions, inner: rocksdb_ffi::DBReadOptions,
} }
pub struct Snapshot<'a> { pub struct Snapshot<'a> {
db: &'a RocksDB, db: &'a DB,
inner: rocksdb_ffi::RocksDBSnapshot, inner: rocksdb_ffi::DBSnapshot,
} }
pub struct DBIterator { pub struct DBIterator {
// TODO: should have a reference to DB to enforce scope, but it's trickier than I // TODO: should have a reference to DB to enforce scope, but it's trickier than I
// thought to add // thought to add
inner: rocksdb_ffi::RocksDBIterator, inner: rocksdb_ffi::DBIterator,
direction: Direction, direction: Direction,
just_seeked: bool, just_seeked: bool,
} }
@ -98,7 +101,7 @@ impl <'a> Iterator for SubDBIterator<'a> {
impl DBIterator { impl DBIterator {
//TODO alias db & opts to different lifetimes, and DBIterator to the db's lifetime //TODO alias db & opts to different lifetimes, and DBIterator to the db's lifetime
fn new(db: &RocksDB, readopts: &ReadOptions) -> DBIterator { fn new(db: &DB, readopts: &ReadOptions) -> DBIterator {
unsafe { unsafe {
let iterator = rocksdb_ffi::rocksdb_create_iterator(db.inner, readopts.inner); let iterator = rocksdb_ffi::rocksdb_create_iterator(db.inner, readopts.inner);
rocksdb_ffi::rocksdb_iter_seek_to_first(iterator); rocksdb_ffi::rocksdb_iter_seek_to_first(iterator);
@ -106,7 +109,7 @@ impl DBIterator {
} }
} }
fn new_cf(db: &RocksDB, cf_name: &str, readopts: &ReadOptions) -> Result<DBIterator, String> { fn new_cf(db: &DB, cf_name: &str, readopts: &ReadOptions) -> Result<DBIterator, String> {
let cf = db.cfs.get(cf_name); let cf = db.cfs.get(cf_name);
if cf.is_none() { if cf.is_none() {
return Err(format!("Invalid column family: {}", cf_name).to_string()); return Err(format!("Invalid column family: {}", cf_name).to_string());
@ -154,7 +157,7 @@ impl Drop for DBIterator {
} }
impl <'a> Snapshot<'a> { impl <'a> Snapshot<'a> {
pub fn new(db: &RocksDB) -> Snapshot { pub fn new(db: &DB) -> Snapshot {
let snapshot = unsafe { rocksdb_ffi::rocksdb_create_snapshot(db.inner) }; let snapshot = unsafe { rocksdb_ffi::rocksdb_create_snapshot(db.inner) };
Snapshot { db: db, inner: snapshot } Snapshot { db: db, inner: snapshot }
} }
@ -174,14 +177,14 @@ impl <'a> Drop for Snapshot<'a> {
} }
} }
// This is for the RocksDB and write batches to share the same API // This is for the DB and write batches to share the same API
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, cf: &str, key: &[u8], value: &[u8]) -> Result<(), String>; fn put_cf(&self, cf: DBCFHandle, key: &[u8], value: &[u8]) -> Result<(), String>;
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String>; fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String>;
fn merge_cf(&self, cf: &str, key: &[u8], value: &[u8]) -> Result<(), String>; fn merge_cf(&self, cf: DBCFHandle, key: &[u8], value: &[u8]) -> Result<(), String>;
fn delete(&self, key: &[u8]) -> Result<(), String>; fn delete(&self, key: &[u8]) -> Result<(), String>;
fn delete_cf(&self, cf: &str, key: &[u8]) -> Result<(), String>; fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String>;
} }
fn error_message(ptr: *const i8) -> String { fn error_message(ptr: *const i8) -> String {
@ -193,18 +196,18 @@ fn error_message(ptr: *const i8) -> String {
s s
} }
impl RocksDB { impl DB {
pub fn open_default(path: &str) -> Result<RocksDB, String> { pub fn open_default(path: &str) -> Result<DB, String> {
let mut opts = Options::new(); let mut opts = Options::new();
opts.create_if_missing(true); opts.create_if_missing(true);
RocksDB::open(&opts, path) DB::open(&opts, path)
} }
pub fn open(opts: &Options, path: &str) -> Result<RocksDB, String> { pub fn open(opts: &Options, path: &str) -> Result<DB, String> {
RocksDB::open_cf(opts, path, &[]) DB::open_cf(opts, path, &[])
} }
pub fn open_cf(opts: &Options, path: &str, cfs: &[&str]) -> Result<RocksDB, String> { pub fn open_cf(opts: &Options, path: &str, cfs: &[&str]) -> Result<DB, String> {
let cpath = match CString::new(path.as_bytes()) { let cpath = match CString::new(path.as_bytes()) {
Ok(c) => c, Ok(c) => c,
Err(_) => Err(_) =>
@ -220,7 +223,7 @@ impl RocksDB {
let mut err: *const i8 = 0 as *const i8; let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err; let err_ptr: *mut *const i8 = &mut err;
let db: rocksdb_ffi::RocksDBInstance; let db: rocksdb_ffi::DBInstance;
let mut cfMap = BTreeMap::new(); let mut cfMap = BTreeMap::new();
if cfs.len() == 0 { if cfs.len() == 0 {
@ -244,20 +247,20 @@ impl RocksDB {
cf.as_ptr() cf.as_ptr()
}).collect(); }).collect();
// These handles will be populated by RocksDB. // These handles will be populated by DB.
let mut cfhandles: Vec<rocksdb_ffi::RocksDBCFHandle> = let mut cfhandles: Vec<rocksdb_ffi::DBCFHandle> =
cfs_v.iter().map( |_| { cfs_v.iter().map( |_| {
rocksdb_ffi::RocksDBCFHandle(0 as *mut c_void) rocksdb_ffi::DBCFHandle(0 as *mut c_void)
}).collect(); }).collect();
// TODO(tyler) allow options to be passed in. // TODO(tyler) allow options to be passed in.
let cfopts: Vec<rocksdb_ffi::RocksDBOptions> = cfs_v.iter().map( |_| { let cfopts: Vec<rocksdb_ffi::DBOptions> = cfs_v.iter().map( |_| {
unsafe { rocksdb_ffi::rocksdb_options_create() } unsafe { rocksdb_ffi::rocksdb_options_create() }
}).collect(); }).collect();
// Prepare to ship to C. // Prepare to ship to C.
let copts: *const rocksdb_ffi::RocksDBOptions = cfopts.as_ptr(); let copts: *const rocksdb_ffi::DBOptions = cfopts.as_ptr();
let handles: *const rocksdb_ffi::RocksDBCFHandle = cfhandles.as_ptr(); let handles: *const rocksdb_ffi::DBCFHandle = cfhandles.as_ptr();
let nfam = cfs_v.len(); let nfam = cfs_v.len();
unsafe { unsafe {
db = rocksdb_ffi::rocksdb_open_column_families(opts.inner, cpath_ptr, db = rocksdb_ffi::rocksdb_open_column_families(opts.inner, cpath_ptr,
@ -268,7 +271,7 @@ impl RocksDB {
for handle in cfhandles.iter() { for handle in cfhandles.iter() {
if handle.0.is_null() { if handle.0.is_null() {
return Err("Received null column family handle from RocksDB.".to_string()); return Err("Received null column family handle from DB.".to_string());
} }
} }
@ -284,7 +287,7 @@ impl RocksDB {
return Err("Could not initialize database.".to_string()); return Err("Could not initialize database.".to_string());
} }
Ok(RocksDB { inner: db, cfs: cfMap }) Ok(DB { inner: db, cfs: cfMap })
} }
pub fn destroy(opts: &Options, path: &str) -> Result<(), String> { pub fn destroy(opts: &Options, path: &str) -> Result<(), String> {
@ -333,11 +336,11 @@ impl RocksDB {
return Ok(()) return Ok(())
} }
pub fn get(&self, key: &[u8]) -> RocksDBResult<RocksDBVector, String> { pub fn get(&self, key: &[u8]) -> DBResult<DBVector, String> {
unsafe { unsafe {
let readopts = rocksdb_ffi::rocksdb_readoptions_create(); let readopts = rocksdb_ffi::rocksdb_readoptions_create();
if readopts.0.is_null() { if readopts.0.is_null() {
return RocksDBResult::Error("Unable to create rocksdb read \ return DBResult::Error("Unable to create rocksdb read \
options. This is a fairly trivial call, and its failure \ options. This is a fairly trivial call, and its failure \
may be indicative of a mis-compiled or mis-loaded rocksdb \ may be indicative of a mis-compiled or mis-loaded rocksdb \
library.".to_string()); library.".to_string());
@ -351,26 +354,22 @@ impl RocksDB {
key.as_ptr(), key.len() as size_t, val_len_ptr, err_ptr) as *mut u8; key.as_ptr(), key.len() as size_t, val_len_ptr, err_ptr) as *mut u8;
rocksdb_ffi::rocksdb_readoptions_destroy(readopts); rocksdb_ffi::rocksdb_readoptions_destroy(readopts);
if !err.is_null() { if !err.is_null() {
return RocksDBResult::Error(error_message(err)); return DBResult::Error(error_message(err));
} }
match val.is_null() { match val.is_null() {
true => RocksDBResult::None, true => DBResult::None,
false => { false => {
RocksDBResult::Some(RocksDBVector::from_c(val, val_len)) DBResult::Some(DBVector::from_c(val, val_len))
} }
} }
} }
} }
pub fn get_cf(&self, cf_name: &str, key: &[u8]) -> RocksDBResult<RocksDBVector, String> { pub fn get_cf(&self, cf: DBCFHandle, key: &[u8]) -> DBResult<DBVector, String> {
let cf = self.cfs.get(cf_name);
if cf.is_none() {
return RocksDBResult::Error(format!("Invalid column family: {}", cf_name).to_string());
}
unsafe { unsafe {
let readopts = rocksdb_ffi::rocksdb_readoptions_create(); let readopts = rocksdb_ffi::rocksdb_readoptions_create();
if readopts.0.is_null() { if readopts.0.is_null() {
return RocksDBResult::Error("Unable to create rocksdb read \ return DBResult::Error("Unable to create rocksdb read \
options. This is a fairly trivial call, and its failure \ options. This is a fairly trivial call, and its failure \
may be indicative of a mis-compiled or mis-loaded rocksdb \ may be indicative of a mis-compiled or mis-loaded rocksdb \
library.".to_string()); library.".to_string());
@ -381,22 +380,22 @@ impl RocksDB {
let mut err: *const i8 = 0 as *const i8; let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err; let err_ptr: *mut *const i8 = &mut err;
let val = rocksdb_ffi::rocksdb_get_cf(self.inner, readopts.clone(), let val = rocksdb_ffi::rocksdb_get_cf(self.inner, readopts.clone(),
*cf.unwrap(), key.as_ptr(), key.len() as size_t, val_len_ptr, cf, key.as_ptr(), key.len() as size_t, val_len_ptr,
err_ptr) as *mut u8; err_ptr) as *mut u8;
rocksdb_ffi::rocksdb_readoptions_destroy(readopts); rocksdb_ffi::rocksdb_readoptions_destroy(readopts);
if !err.is_null() { if !err.is_null() {
return RocksDBResult::Error(error_message(err)); return DBResult::Error(error_message(err));
} }
match val.is_null() { match val.is_null() {
true => RocksDBResult::None, true => DBResult::None,
false => { false => {
RocksDBResult::Some(RocksDBVector::from_c(val, val_len)) DBResult::Some(DBVector::from_c(val, val_len))
} }
} }
} }
} }
pub fn create_cf(&mut self, name: &str, opts: &Options) -> Result<(), String> { pub fn create_cf(&mut self, name: &str, opts: &Options) -> Result<DBCFHandle, 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(_) =>
@ -405,13 +404,16 @@ impl RocksDB {
let cname_ptr = cname.as_ptr(); let cname_ptr = cname.as_ptr();
let mut err: *const i8 = 0 as *const i8; let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err; let err_ptr: *mut *const i8 = &mut err;
unsafe { let cf_handler = unsafe {
rocksdb_ffi::rocksdb_create_column_family(self.inner, opts.inner, cname_ptr, err_ptr); let cf_handler = rocksdb_ffi::rocksdb_create_column_family(
} self.inner, opts.inner, cname_ptr, err_ptr);
self.cfs.insert(name.to_string(), cf_handler);
cf_handler
};
if !err.is_null() { if !err.is_null() {
return Err(error_message(err)); return Err(error_message(err));
} }
Ok(()) Ok(cf_handler)
} }
pub fn drop_cf(&mut self, name: &str) -> Result<(), String> { pub fn drop_cf(&mut self, name: &str) -> Result<(), String> {
@ -432,6 +434,10 @@ impl RocksDB {
Ok(()) Ok(())
} }
pub fn cf_handle(&self, name: &str) -> Option<&DBCFHandle> {
self.cfs.get(name)
}
pub fn iterator(&self) -> DBIterator { pub fn iterator(&self) -> DBIterator {
let opts = ReadOptions::new(); let opts = ReadOptions::new();
DBIterator::new(&self, &opts) DBIterator::new(&self, &opts)
@ -447,7 +453,7 @@ impl RocksDB {
} }
} }
impl Writable for RocksDB { impl Writable for DB {
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String> { fn put(&self, key: &[u8], value: &[u8]) -> Result<(), String> {
unsafe { unsafe {
let writeopts = rocksdb_ffi::rocksdb_writeoptions_create(); let writeopts = rocksdb_ffi::rocksdb_writeoptions_create();
@ -464,16 +470,12 @@ impl Writable for RocksDB {
} }
} }
fn put_cf(&self, cf_name: &str, key: &[u8], value: &[u8]) -> Result<(), String> { fn put_cf(&self, cf: DBCFHandle, key: &[u8], value: &[u8]) -> Result<(), String> {
let cf = self.cfs.get(cf_name);
if cf.is_none() {
return Err(format!("Invalid column family: {}", cf_name).to_string());
}
unsafe { unsafe {
let writeopts = rocksdb_ffi::rocksdb_writeoptions_create(); let writeopts = rocksdb_ffi::rocksdb_writeoptions_create();
let mut err: *const i8 = 0 as *const i8; let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err; let err_ptr: *mut *const i8 = &mut err;
rocksdb_ffi::rocksdb_put_cf(self.inner, writeopts.clone(), *cf.unwrap(), rocksdb_ffi::rocksdb_put_cf(self.inner, writeopts.clone(), cf,
key.as_ptr(), key.len() as size_t, value.as_ptr(), key.as_ptr(), key.len() as size_t, value.as_ptr(),
value.len() as size_t, err_ptr); value.len() as size_t, err_ptr);
rocksdb_ffi::rocksdb_writeoptions_destroy(writeopts); rocksdb_ffi::rocksdb_writeoptions_destroy(writeopts);
@ -500,17 +502,13 @@ impl Writable for RocksDB {
} }
} }
fn merge_cf(&self, cf_name: &str, key: &[u8], value: &[u8]) -> Result<(), String> { fn merge_cf(&self, cf: DBCFHandle, key: &[u8], value: &[u8]) -> Result<(), String> {
let cf = self.cfs.get(cf_name);
if cf.is_none() {
return Err(format!("Invalid column family: {}", cf_name).to_string());
}
unsafe { unsafe {
let writeopts = rocksdb_ffi::rocksdb_writeoptions_create(); let writeopts = rocksdb_ffi::rocksdb_writeoptions_create();
let mut err: *const i8 = 0 as *const i8; let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err; let err_ptr: *mut *const i8 = &mut err;
rocksdb_ffi::rocksdb_merge_cf(self.inner, writeopts.clone(), rocksdb_ffi::rocksdb_merge_cf(self.inner, writeopts.clone(),
*cf.unwrap(), key.as_ptr(), cf, key.as_ptr(),
key.len() as size_t, value.as_ptr(), key.len() as size_t, value.as_ptr(),
value.len() as size_t, err_ptr); value.len() as size_t, err_ptr);
rocksdb_ffi::rocksdb_writeoptions_destroy(writeopts); rocksdb_ffi::rocksdb_writeoptions_destroy(writeopts);
@ -536,17 +534,13 @@ impl Writable for RocksDB {
} }
} }
fn delete_cf(&self, cf_name: &str, key: &[u8]) -> Result<(), String> { fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String> {
let cf = self.cfs.get(cf_name);
if cf.is_none() {
return Err(format!("Invalid column family: {}", cf_name).to_string());
}
unsafe { unsafe {
let writeopts = rocksdb_ffi::rocksdb_writeoptions_create(); let writeopts = rocksdb_ffi::rocksdb_writeoptions_create();
let mut err: *const i8 = 0 as *const i8; let mut err: *const i8 = 0 as *const i8;
let err_ptr: *mut *const i8 = &mut err; let err_ptr: *mut *const i8 = &mut err;
rocksdb_ffi::rocksdb_delete_cf(self.inner, writeopts.clone(), rocksdb_ffi::rocksdb_delete_cf(self.inner, writeopts.clone(),
*cf.unwrap(), key.as_ptr(), cf, key.as_ptr(),
key.len() as size_t, err_ptr); key.len() as size_t, err_ptr);
rocksdb_ffi::rocksdb_writeoptions_destroy(writeopts); rocksdb_ffi::rocksdb_writeoptions_destroy(writeopts);
if !err.is_null() { if !err.is_null() {
@ -575,7 +569,7 @@ impl Drop for WriteBatch {
} }
} }
impl Drop for RocksDB { impl Drop for DB {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
for (_, cf) in self.cfs.iter() { for (_, cf) in self.cfs.iter() {
@ -596,8 +590,13 @@ impl Writable for WriteBatch {
} }
} }
fn put_cf(&self, cf_name: &str, key: &[u8], value: &[u8]) -> Result<(), String> { fn put_cf(&self, cf: DBCFHandle, key: &[u8], value: &[u8]) -> Result<(), String> {
Err("not implemented for write batches yet".to_string()) unsafe {
rocksdb_ffi::rocksdb_writebatch_put_cf(self.inner, cf, key.as_ptr(),
key.len() as size_t, value.as_ptr(),
value.len() as size_t);
Ok(())
}
} }
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String> { fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), String> {
@ -609,8 +608,13 @@ impl Writable for WriteBatch {
} }
} }
fn merge_cf(&self, cf: &str, key: &[u8], value: &[u8]) -> Result<(), String> { fn merge_cf(&self, cf: DBCFHandle, key: &[u8], value: &[u8]) -> Result<(), String> {
Err("not implemented for write batches yet".to_string()) unsafe {
rocksdb_ffi::rocksdb_writebatch_merge_cf(self.inner, cf, key.as_ptr(),
key.len() as size_t, value.as_ptr(),
value.len() as size_t);
Ok(())
}
} }
fn delete(&self, key: &[u8]) -> Result<(), String> { fn delete(&self, key: &[u8]) -> Result<(), String> {
@ -621,8 +625,13 @@ impl Writable for WriteBatch {
} }
} }
fn delete_cf(&self, cf: &str, key: &[u8]) -> Result<(), String> { fn delete_cf(&self, cf: DBCFHandle, key: &[u8]) -> Result<(), String> {
Err("not implemented for write batches yet".to_string()) unsafe {
rocksdb_ffi::rocksdb_writebatch_delete_cf(self.inner,
cf, key.as_ptr(),
key.len() as size_t);
Ok(())
}
} }
} }
@ -656,19 +665,19 @@ impl ReadOptions {
} }
} }
pub struct RocksDBVector { pub struct DBVector {
base: *mut u8, base: *mut u8,
len: usize, len: usize,
} }
impl Deref for RocksDBVector { impl Deref for DBVector {
type Target = [u8]; type Target = [u8];
fn deref(&self) -> &[u8] { fn deref(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.base, self.len) } unsafe { slice::from_raw_parts(self.base, self.len) }
} }
} }
impl Drop for RocksDBVector { impl Drop for DBVector {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
libc::free(self.base as *mut libc::c_void); libc::free(self.base as *mut libc::c_void);
@ -676,10 +685,10 @@ impl Drop for RocksDBVector {
} }
} }
impl RocksDBVector { impl DBVector {
pub fn from_c(val: *mut u8, val_len: size_t) -> RocksDBVector { pub fn from_c(val: *mut u8, val_len: size_t) -> DBVector {
unsafe { unsafe {
RocksDBVector { DBVector {
base: val, base: val,
len: val_len as usize, len: val_len as usize,
} }
@ -691,72 +700,72 @@ impl RocksDBVector {
} }
} }
// RocksDBResult exists because of the inherent difference between // DBResult exists because of the inherent difference between
// an operational failure and the absence of a possible result. // an operational failure and the absence of a possible result.
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)] #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug)]
pub enum RocksDBResult<T, E> { pub enum DBResult<T, E> {
Some(T), Some(T),
None, None,
Error(E), Error(E),
} }
impl <T, E> RocksDBResult<T, E> { impl <T, E> DBResult<T, E> {
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> RocksDBResult<U, E> { pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> DBResult<U, E> {
match self { match self {
RocksDBResult::Some(x) => RocksDBResult::Some(f(x)), DBResult::Some(x) => DBResult::Some(f(x)),
RocksDBResult::None => RocksDBResult::None, DBResult::None => DBResult::None,
RocksDBResult::Error(e) => RocksDBResult::Error(e), DBResult::Error(e) => DBResult::Error(e),
} }
} }
pub fn unwrap(self) -> T { pub fn unwrap(self) -> T {
match self { match self {
RocksDBResult::Some(x) => x, DBResult::Some(x) => x,
RocksDBResult::None => DBResult::None =>
panic!("Attempted unwrap on RocksDBResult::None"), panic!("Attempted unwrap on DBResult::None"),
RocksDBResult::Error(_) => DBResult::Error(_) =>
panic!("Attempted unwrap on RocksDBResult::Error"), panic!("Attempted unwrap on DBResult::Error"),
} }
} }
pub fn on_error<U, F: FnOnce(E) -> U>(self, f: F) -> RocksDBResult<T, U> { pub fn on_error<U, F: FnOnce(E) -> U>(self, f: F) -> DBResult<T, U> {
match self { match self {
RocksDBResult::Some(x) => RocksDBResult::Some(x), DBResult::Some(x) => DBResult::Some(x),
RocksDBResult::None => RocksDBResult::None, DBResult::None => DBResult::None,
RocksDBResult::Error(e) => RocksDBResult::Error(f(e)), DBResult::Error(e) => DBResult::Error(f(e)),
} }
} }
pub fn on_absent<F: FnOnce() -> ()>(self, f: F) -> RocksDBResult<T, E> { pub fn on_absent<F: FnOnce() -> ()>(self, f: F) -> DBResult<T, E> {
match self { match self {
RocksDBResult::Some(x) => RocksDBResult::Some(x), DBResult::Some(x) => DBResult::Some(x),
RocksDBResult::None => { DBResult::None => {
f(); f();
RocksDBResult::None DBResult::None
}, },
RocksDBResult::Error(e) => RocksDBResult::Error(e), DBResult::Error(e) => DBResult::Error(e),
} }
} }
pub fn is_some(self) -> bool { pub fn is_some(self) -> bool {
match self { match self {
RocksDBResult::Some(_) => true, DBResult::Some(_) => true,
RocksDBResult::None => false, DBResult::None => false,
RocksDBResult::Error(_) => false, DBResult::Error(_) => false,
} }
} }
pub fn is_none(self) -> bool { pub fn is_none(self) -> bool {
match self { match self {
RocksDBResult::Some(_) => false, DBResult::Some(_) => false,
RocksDBResult::None => true, DBResult::None => true,
RocksDBResult::Error(_) => false, DBResult::Error(_) => false,
} }
} }
pub fn is_error(self) -> bool { pub fn is_error(self) -> bool {
match self { match self {
RocksDBResult::Some(_) => false, DBResult::Some(_) => false,
RocksDBResult::None => false, DBResult::None => false,
RocksDBResult::Error(_) => true, DBResult::Error(_) => true,
} }
} }
} }
@ -765,26 +774,26 @@ impl <T, E> RocksDBResult<T, E> {
fn external() { fn external() {
let path = "_rust_rocksdb_externaltest"; let path = "_rust_rocksdb_externaltest";
{ {
let mut db = RocksDB::open_default(path).unwrap(); let mut db = DB::open_default(path).unwrap();
let p = db.put(b"k1", b"v1111"); let p = db.put(b"k1", b"v1111");
assert!(p.is_ok()); assert!(p.is_ok());
let r: RocksDBResult<RocksDBVector, String> = db.get(b"k1"); let r: DBResult<DBVector, String> = db.get(b"k1");
assert!(r.unwrap().to_utf8().unwrap() == "v1111"); assert!(r.unwrap().to_utf8().unwrap() == "v1111");
assert!(db.delete(b"k1").is_ok()); assert!(db.delete(b"k1").is_ok());
assert!(db.get(b"k1").is_none()); assert!(db.get(b"k1").is_none());
} }
let opts = Options::new(); let opts = Options::new();
let result = RocksDB::destroy(&opts, path); let result = DB::destroy(&opts, path);
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[test] #[test]
fn errors_do_stuff() { fn errors_do_stuff() {
let path = "_rust_rocksdb_error"; let path = "_rust_rocksdb_error";
let mut db = RocksDB::open_default(path).unwrap(); let mut db = DB::open_default(path).unwrap();
let opts = Options::new(); let opts = Options::new();
// The DB will still be open when we try to destroy and the lock should fail // The DB will still be open when we try to destroy and the lock should fail
match RocksDB::destroy(&opts, path) { match DB::destroy(&opts, path) {
Err(ref s) => assert!(s == "IO error: lock _rust_rocksdb_error/LOCK: No locks available"), Err(ref s) => assert!(s == "IO error: lock _rust_rocksdb_error/LOCK: No locks available"),
Ok(_) => panic!("should fail") Ok(_) => panic!("should fail")
} }
@ -794,7 +803,7 @@ fn errors_do_stuff() {
fn writebatch_works() { fn writebatch_works() {
let path = "_rust_rocksdb_writebacktest"; let path = "_rust_rocksdb_writebacktest";
{ {
let mut db = RocksDB::open_default(path).unwrap(); let mut db = DB::open_default(path).unwrap();
{ // test put { // test put
let mut batch = WriteBatch::new(); let mut batch = WriteBatch::new();
assert!(db.get(b"k1").is_none()); assert!(db.get(b"k1").is_none());
@ -802,7 +811,7 @@ fn writebatch_works() {
assert!(db.get(b"k1").is_none()); assert!(db.get(b"k1").is_none());
let p = db.write(batch); let p = db.write(batch);
assert!(p.is_ok()); assert!(p.is_ok());
let r: RocksDBResult<RocksDBVector, String> = db.get(b"k1"); let r: DBResult<DBVector, String> = db.get(b"k1");
assert!(r.unwrap().to_utf8().unwrap() == "v1111"); assert!(r.unwrap().to_utf8().unwrap() == "v1111");
} }
{ // test delete { // test delete
@ -814,14 +823,14 @@ fn writebatch_works() {
} }
} }
let opts = Options::new(); let opts = Options::new();
assert!(RocksDB::destroy(&opts, path).is_ok()); assert!(DB::destroy(&opts, path).is_ok());
} }
#[test] #[test]
fn iterator_test() { fn iterator_test() {
let path = "_rust_rocksdb_iteratortest"; let path = "_rust_rocksdb_iteratortest";
{ {
let mut db = RocksDB::open_default(path).unwrap(); let mut db = DB::open_default(path).unwrap();
let p = db.put(b"k1", b"v1111"); let p = db.put(b"k1", b"v1111");
assert!(p.is_ok()); assert!(p.is_ok());
let p = db.put(b"k2", b"v2222"); let p = db.put(b"k2", b"v2222");
@ -834,5 +843,5 @@ fn iterator_test() {
} }
} }
let opts = Options::new(); let opts = Options::new();
assert!(RocksDB::destroy(&opts, path).is_ok()); assert!(DB::destroy(&opts, path).is_ok());
} }

@ -24,11 +24,11 @@ use merge_operator::{self, MergeOperatorCallback, MergeOperands,
use comparator::{self, ComparatorCallback, compare_callback}; use comparator::{self, ComparatorCallback, compare_callback};
pub struct BlockBasedOptions { pub struct BlockBasedOptions {
inner: rocksdb_ffi::RocksDBBlockBasedTableOptions, inner: rocksdb_ffi::DBBlockBasedTableOptions,
} }
pub struct Options { pub struct Options {
pub inner: rocksdb_ffi::RocksDBOptions, pub inner: rocksdb_ffi::DBOptions,
} }
impl Drop for Options { impl Drop for Options {
@ -50,7 +50,7 @@ impl Drop for BlockBasedOptions {
impl BlockBasedOptions { impl BlockBasedOptions {
pub fn new() -> BlockBasedOptions { pub fn new() -> BlockBasedOptions {
let block_opts = unsafe {rocksdb_ffi::rocksdb_block_based_options_create() }; let block_opts = unsafe {rocksdb_ffi::rocksdb_block_based_options_create() };
let rocksdb_ffi::RocksDBBlockBasedTableOptions(opt_ptr) = block_opts; let rocksdb_ffi::DBBlockBasedTableOptions(opt_ptr) = block_opts;
if opt_ptr.is_null() { if opt_ptr.is_null() {
panic!("Could not create rocksdb block based options".to_string()); panic!("Could not create rocksdb block based options".to_string());
} }
@ -65,21 +65,21 @@ impl BlockBasedOptions {
} }
//TODO figure out how to create these in a Rusty way //TODO figure out how to create these in a Rusty way
////pub fn set_filter(&mut self, filter: rocksdb_ffi::RocksDBFilterPolicy) { ////pub fn set_filter(&mut self, filter: rocksdb_ffi::DBFilterPolicy) {
//// unsafe { //// unsafe {
//// rocksdb_ffi::rocksdb_block_based_options_set_filter_policy( //// rocksdb_ffi::rocksdb_block_based_options_set_filter_policy(
//// self.inner, filter); //// self.inner, filter);
//// } //// }
////} ////}
////pub fn set_cache(&mut self, cache: rocksdb_ffi::RocksDBCache) { ////pub fn set_cache(&mut self, cache: rocksdb_ffi::DBCache) {
//// unsafe { //// unsafe {
//// rocksdb_ffi::rocksdb_block_based_options_set_block_cache( //// rocksdb_ffi::rocksdb_block_based_options_set_block_cache(
//// self.inner, cache); //// self.inner, cache);
//// } //// }
////} ////}
////pub fn set_cache_compressed(&mut self, cache: rocksdb_ffi::RocksDBCache) { ////pub fn set_cache_compressed(&mut self, cache: rocksdb_ffi::DBCache) {
//// unsafe { //// unsafe {
//// rocksdb_ffi::rocksdb_block_based_options_set_block_cache_compressed( //// rocksdb_ffi::rocksdb_block_based_options_set_block_cache_compressed(
//// self.inner, cache); //// self.inner, cache);
@ -92,7 +92,7 @@ impl Options {
pub fn new() -> Options { pub fn new() -> Options {
unsafe { unsafe {
let opts = rocksdb_ffi::rocksdb_options_create(); let opts = rocksdb_ffi::rocksdb_options_create();
let rocksdb_ffi::RocksDBOptions(opt_ptr) = opts; let rocksdb_ffi::DBOptions(opt_ptr) = opts;
if opt_ptr.is_null() { if opt_ptr.is_null() {
panic!("Could not create rocksdb options".to_string()); panic!("Could not create rocksdb options".to_string());
} }
@ -258,7 +258,7 @@ impl Options {
} }
} }
pub fn set_compaction_style(&mut self, style: rocksdb_ffi::RocksDBCompactionStyle) { pub fn set_compaction_style(&mut self, style: rocksdb_ffi::DBCompactionStyle) {
unsafe { unsafe {
rocksdb_ffi::rocksdb_options_set_compaction_style( rocksdb_ffi::rocksdb_options_set_compaction_style(
self.inner, style); self.inner, style);

Binary file not shown.

@ -13,7 +13,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
use rocksdb::{Options, RocksDB, RocksDBResult, Writable, Direction, MergeOperands}; use rocksdb::{Options, DB, DBResult, Writable, Direction, MergeOperands};
#[test] #[test]
pub fn test_column_family() { pub fn test_column_family() {
@ -24,7 +24,7 @@ pub fn test_column_family() {
let mut opts = Options::new(); let mut opts = Options::new();
opts.create_if_missing(true); opts.create_if_missing(true);
opts.add_merge_operator("test operator", test_provided_merge); opts.add_merge_operator("test operator", test_provided_merge);
let mut db = RocksDB::open(&opts, path).unwrap(); let mut db = DB::open(&opts, path).unwrap();
let opts = Options::new(); let opts = Options::new();
match db.create_cf("cf1", &opts) { match db.create_cf("cf1", &opts) {
Ok(_) => println!("cf1 created successfully"), Ok(_) => println!("cf1 created successfully"),
@ -38,7 +38,7 @@ pub fn test_column_family() {
{ {
let mut opts = Options::new(); let mut opts = Options::new();
opts.add_merge_operator("test operator", test_provided_merge); opts.add_merge_operator("test operator", test_provided_merge);
match RocksDB::open(&opts, path) { match DB::open(&opts, path) {
Ok(_) => panic!("should not have opened DB successfully without specifying column Ok(_) => panic!("should not have opened DB successfully without specifying column
families"), families"),
Err(e) => assert!(e.starts_with("Invalid argument: You have to open all column families.")), Err(e) => assert!(e.starts_with("Invalid argument: You have to open all column families.")),
@ -49,33 +49,34 @@ pub fn test_column_family() {
{ {
let mut opts = Options::new(); let mut opts = Options::new();
opts.add_merge_operator("test operator", test_provided_merge); opts.add_merge_operator("test operator", test_provided_merge);
match RocksDB::open_cf(&opts, path, &["cf1"]) { match DB::open_cf(&opts, path, &["cf1"]) {
Ok(_) => println!("successfully opened db with column family"), Ok(_) => println!("successfully opened db with column family"),
Err(e) => panic!("failed to open db with column family: {}", e), Err(e) => panic!("failed to open db with column family: {}", e),
} }
} }
// should be able to write, read, merge, batch, and iterate over a cf // TODO should be able to write, read, merge, batch, and iterate over a cf
{ {
let mut opts = Options::new(); let mut opts = Options::new();
opts.add_merge_operator("test operator", test_provided_merge); opts.add_merge_operator("test operator", test_provided_merge);
let mut db = match RocksDB::open_cf(&opts, path, &["cf1"]) { let mut db = match DB::open_cf(&opts, path, &["cf1"]) {
Ok(db) => { Ok(db) => {
println!("successfully opened db with column family"); println!("successfully opened db with column family");
db db
}, },
Err(e) => panic!("failed to open db with column family: {}", e), Err(e) => panic!("failed to open db with column family: {}", e),
}; };
assert!(db.put_cf("cf1", b"k1", b"v1").is_ok()); let cf1 = *db.cf_handle("cf1").unwrap();
assert!(db.get_cf("cf1", b"k1").unwrap().to_utf8().unwrap() == "v1"); assert!(db.put_cf(cf1, b"k1", b"v1").is_ok());
let p = db.put_cf("cf1", b"k1", b"a"); assert!(db.get_cf(cf1, b"k1").unwrap().to_utf8().unwrap() == "v1");
let p = db.put_cf(cf1, b"k1", b"a");
assert!(p.is_ok()); assert!(p.is_ok());
db.merge_cf("cf1", b"k1", b"b"); db.merge_cf(cf1, b"k1", b"b");
db.merge_cf("cf1", b"k1", b"c"); db.merge_cf(cf1, b"k1", b"c");
db.merge_cf("cf1", b"k1", b"d"); db.merge_cf(cf1, b"k1", b"d");
db.merge_cf("cf1", b"k1", b"efg"); db.merge_cf(cf1, b"k1", b"efg");
let m = db.merge_cf("cf1", b"k1", b"h"); let m = db.merge_cf(cf1, b"k1", b"h");
println!("m is {:?}", m); println!("m is {:?}", m);
assert!(m.is_ok()); // TODO assert!(m.is_ok());
db.get(b"k1").map( |value| { db.get(b"k1").map( |value| {
match value.to_utf8() { match value.to_utf8() {
Some(v) => Some(v) =>
@ -86,21 +87,27 @@ pub fn test_column_family() {
}).on_absent( || { println!("value not present!") }) }).on_absent( || { println!("value not present!") })
.on_error( |e| { println!("error reading value")}); //: {", e) }); .on_error( |e| { println!("error reading value")}); //: {", e) });
let r = db.get_cf("cf1", b"k1"); let r = db.get_cf(cf1, b"k1");
assert!(r.unwrap().to_utf8().unwrap() == "abcdefgh"); // TODO assert!(r.unwrap().to_utf8().unwrap() == "abcdefgh");
assert!(db.delete(b"k1").is_ok()); assert!(db.delete(b"k1").is_ok());
assert!(db.get(b"k1").is_none()); assert!(db.get(b"k1").is_none());
} }
// TODO should be able to use writebatch ops with a cf
{
}
// TODO should be able to iterate over a cf
{
}
// should b able to drop a cf // should b able to drop a cf
{ {
let mut db = RocksDB::open_cf(&Options::new(), path, &["cf1"]).unwrap(); let mut db = DB::open_cf(&Options::new(), path, &["cf1"]).unwrap();
match db.drop_cf("cf1") { match db.drop_cf("cf1") {
Ok(_) => println!("cf1 successfully dropped."), Ok(_) => println!("cf1 successfully dropped."),
Err(e) => panic!("failed to drop column family: {}", e), Err(e) => panic!("failed to drop column family: {}", e),
} }
} }
assert!(RocksDB::destroy(&Options::new(), path).is_ok()); assert!(DB::destroy(&Options::new(), path).is_ok());
} }
fn test_provided_merge(new_key: &[u8], fn test_provided_merge(new_key: &[u8],

@ -1,4 +1,4 @@
use rocksdb::{Options, RocksDB, Writable, Direction}; use rocksdb::{Options, DB, Writable, Direction};
use std; use std;
fn cba(input: &Box<[u8]>) -> Box<[u8]> { fn cba(input: &Box<[u8]>) -> Box<[u8]> {
@ -17,7 +17,7 @@ pub fn test_iterator() {
let v2:Box<[u8]> = b"v2222".to_vec().into_boxed_slice(); let v2:Box<[u8]> = b"v2222".to_vec().into_boxed_slice();
let v3:Box<[u8]> = b"v3333".to_vec().into_boxed_slice(); let v3:Box<[u8]> = b"v3333".to_vec().into_boxed_slice();
let v4:Box<[u8]> = b"v4444".to_vec().into_boxed_slice(); let v4:Box<[u8]> = b"v4444".to_vec().into_boxed_slice();
let mut db = RocksDB::open_default(path).unwrap(); let mut db = DB::open_default(path).unwrap();
let p = db.put(&*k1, &*v1); let p = db.put(&*k1, &*v1);
assert!(p.is_ok()); assert!(p.is_ok());
let p = db.put(&*k2, &*v2); let p = db.put(&*k2, &*v2);
@ -109,6 +109,6 @@ pub fn test_iterator() {
} }
} }
let opts = Options::new(); let opts = Options::new();
assert!(RocksDB::destroy(&opts, path).is_ok()); assert!(DB::destroy(&opts, path).is_ok());
} }

@ -1,4 +1,4 @@
use rocksdb::{Options, RocksDB, Writable, Direction, RocksDBResult}; use rocksdb::{Options, DB, Writable, Direction, DBResult};
use std::thread::{self, Builder}; use std::thread::{self, Builder};
use std::sync::Arc; use std::sync::Arc;
@ -8,7 +8,7 @@ const N: usize = 100_000;
pub fn test_multithreaded() { pub fn test_multithreaded() {
let path = "_rust_rocksdb_multithreadtest"; let path = "_rust_rocksdb_multithreadtest";
{ {
let db = RocksDB::open_default(path).unwrap(); let db = DB::open_default(path).unwrap();
let db = Arc::new(db); let db = Arc::new(db);
db.put(b"key", b"value1"); db.put(b"key", b"value1");
@ -31,7 +31,7 @@ pub fn test_multithreaded() {
let j3 = thread::spawn(move|| { let j3 = thread::spawn(move|| {
for i in 1..N { for i in 1..N {
match db3.get(b"key") { match db3.get(b"key") {
RocksDBResult::Some(v) => { DBResult::Some(v) => {
if &v[..] != b"value1" && &v[..] != b"value2" { if &v[..] != b"value1" && &v[..] != b"value2" {
assert!(false); assert!(false);
} }
@ -47,5 +47,5 @@ pub fn test_multithreaded() {
j2.join(); j2.join();
j3.join(); j3.join();
} }
assert!(RocksDB::destroy(&Options::new(), path).is_ok()); assert!(DB::destroy(&Options::new(), path).is_ok());
} }

Loading…
Cancel
Save