master
Tyler Neely 8 years ago
parent cfc3cbb551
commit 121ed9a993
  1. 18
      rocksdb-sys/build.rs
  2. 609
      rocksdb-sys/src/lib.rs
  3. 543
      rocksdb-sys/tests/ffi.rs
  4. 4
      rustfmt.toml
  5. 7
      src/comparator.rs
  6. 2
      src/ffi_util.rs
  7. 3
      src/lib.rs
  8. 37
      src/merge_operator.rs
  9. 293
      src/rocksdb.rs
  10. 52
      src/rocksdb_options.rs
  11. 5
      test/test_column_family.rs
  12. 35
      test/test_iterator.rs

@ -27,12 +27,14 @@ fn build_rocksdb() {
config.define("NDEBUG", Some("1")); config.define("NDEBUG", Some("1"));
config.define("SNAPPY", Some("1")); config.define("SNAPPY", Some("1"));
let mut lib_sources = include_str!("rocksdb_lib_sources.txt").split(" ").collect::<Vec<&'static str>>(); let mut lib_sources = include_str!("rocksdb_lib_sources.txt")
.split(" ")
.collect::<Vec<&'static str>>();
// We have a pregenerated a version of build_version.cc in the local directory // We have a pregenerated a version of build_version.cc in the local directory
lib_sources = lib_sources.iter().cloned().filter(|file| { lib_sources = lib_sources.iter()
*file != "util/build_version.cc" .cloned()
}) .filter(|file| *file != "util/build_version.cc")
.collect::<Vec<&'static str>>(); .collect::<Vec<&'static str>>();
if cfg!(target_os = "macos") { if cfg!(target_os = "macos") {
@ -45,7 +47,7 @@ fn build_rocksdb() {
config.define("OS_LINUX", Some("1")); config.define("OS_LINUX", Some("1"));
config.define("ROCKSDB_PLATFORM_POSIX", Some("1")); config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
config.define("ROCKSDB_LIB_IO_POSIX", Some("1")); config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
//COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp" // COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp"
} }
if cfg!(target_os = "freebsd") { if cfg!(target_os = "freebsd") {
config.define("OS_FREEBSD", Some("1")); config.define("OS_FREEBSD", Some("1"));
@ -58,12 +60,14 @@ fn build_rocksdb() {
config.define("OS_WIN", Some("1")); config.define("OS_WIN", Some("1"));
// Remove POSIX-specific sources // Remove POSIX-specific sources
lib_sources = lib_sources.iter().cloned().filter(|file| { lib_sources = lib_sources.iter()
.cloned()
.filter(|file| {
match *file { match *file {
"port/port_posix.cc" | "port/port_posix.cc" |
"util/env_posix.cc" | "util/env_posix.cc" |
"util/io_posix.cc" => false, "util/io_posix.cc" => false,
_ => true _ => true,
} }
}) })
.collect::<Vec<&'static str>>(); .collect::<Vec<&'static str>>();

@ -29,35 +29,59 @@ use libc::*;
extern "C" { extern "C" {
// Database operations // Database operations
pub fn rocksdb_open(options: *const rocksdb_options_t, name: *const c_char, errptr: *mut *mut c_char) -> *mut rocksdb_t; pub fn rocksdb_open(options: *const rocksdb_options_t,
name: *const c_char,
pub fn rocksdb_open_for_read_only(options: *const rocksdb_options_t, name: *const c_char, error_if_log_file_exist: c_uchar, errptr: *mut *mut c_char) -> *mut rocksdb_t; errptr: *mut *mut c_char)
-> *mut rocksdb_t;
pub fn rocksdb_backup_engine_open(options: *const rocksdb_options_t, path: *const c_char, errptr: *mut *mut c_char) -> *mut rocksdb_backup_engine_t;
pub fn rocksdb_open_for_read_only(options: *const rocksdb_options_t,
pub fn rocksdb_backup_engine_create_new_backup(be: *mut rocksdb_backup_engine_t, db: *mut rocksdb_t, errptr: *mut *mut c_char); name: *const c_char,
error_if_log_file_exist: c_uchar,
pub fn rocksdb_backup_engine_purge_old_backups(be: *mut rocksdb_backup_engine_t, num_backups_to_keep: uint32_t, errptr: *mut *mut c_char); errptr: *mut *mut c_char)
-> *mut rocksdb_t;
pub fn rocksdb_backup_engine_open(options: *const rocksdb_options_t,
path: *const c_char,
errptr: *mut *mut c_char)
-> *mut rocksdb_backup_engine_t;
pub fn rocksdb_backup_engine_create_new_backup(be: *mut rocksdb_backup_engine_t,
db: *mut rocksdb_t,
errptr: *mut *mut c_char);
pub fn rocksdb_backup_engine_purge_old_backups(be: *mut rocksdb_backup_engine_t,
num_backups_to_keep: uint32_t,
errptr: *mut *mut c_char);
pub fn rocksdb_restore_options_create() -> *mut rocksdb_restore_options_t; pub fn rocksdb_restore_options_create() -> *mut rocksdb_restore_options_t;
pub fn rocksdb_restore_options_destroy(opt: *mut rocksdb_restore_options_t); pub fn rocksdb_restore_options_destroy(opt: *mut rocksdb_restore_options_t);
pub fn rocksdb_restore_options_set_keep_log_files(opt: *mut rocksdb_restore_options_t, v: c_int); pub fn rocksdb_restore_options_set_keep_log_files(opt: *mut rocksdb_restore_options_t,
v: c_int);
pub fn rocksdb_backup_engine_restore_db_from_latest_backup(be: *mut rocksdb_backup_engine_t, db_dir: *const c_char, wal_dir: *const c_char, restore_options: *const rocksdb_restore_options_t, errptr: *mut *mut c_char); pub fn rocksdb_backup_engine_restore_db_from_latest_backup(be: *mut rocksdb_backup_engine_t, db_dir: *const c_char, wal_dir: *const c_char, restore_options: *const rocksdb_restore_options_t, errptr: *mut *mut c_char);
pub fn rocksdb_backup_engine_get_backup_info(be: *mut rocksdb_backup_engine_t) -> *const rocksdb_backup_engine_info_t; pub fn rocksdb_backup_engine_get_backup_info(be: *mut rocksdb_backup_engine_t)
-> *const rocksdb_backup_engine_info_t;
pub fn rocksdb_backup_engine_info_count(info: *const rocksdb_backup_engine_info_t) -> c_int; pub fn rocksdb_backup_engine_info_count(info: *const rocksdb_backup_engine_info_t) -> c_int;
pub fn rocksdb_backup_engine_info_timestamp(info: *const rocksdb_backup_engine_info_t, index: c_int) -> int64_t; pub fn rocksdb_backup_engine_info_timestamp(info: *const rocksdb_backup_engine_info_t,
index: c_int)
-> int64_t;
pub fn rocksdb_backup_engine_info_backup_id(info: *const rocksdb_backup_engine_info_t, index: c_int) -> uint32_t; pub fn rocksdb_backup_engine_info_backup_id(info: *const rocksdb_backup_engine_info_t,
index: c_int)
-> uint32_t;
pub fn rocksdb_backup_engine_info_size(info: *const rocksdb_backup_engine_info_t, index: c_int) -> uint64_t; pub fn rocksdb_backup_engine_info_size(info: *const rocksdb_backup_engine_info_t,
index: c_int)
-> uint64_t;
pub fn rocksdb_backup_engine_info_number_files(info: *const rocksdb_backup_engine_info_t, index: c_int) -> uint32_t; pub fn rocksdb_backup_engine_info_number_files(info: *const rocksdb_backup_engine_info_t,
index: c_int)
-> uint32_t;
pub fn rocksdb_backup_engine_info_destroy(info: *const rocksdb_backup_engine_info_t); pub fn rocksdb_backup_engine_info_destroy(info: *const rocksdb_backup_engine_info_t);
@ -67,45 +91,131 @@ extern "C" {
pub fn rocksdb_open_for_read_only_column_families(options: *const rocksdb_options_t, name: *const c_char, num_column_families: c_int, column_family_names: *const *const c_char, column_family_options: *const *const rocksdb_options_t, column_family_handles: *mut *mut rocksdb_column_family_handle_t, error_if_log_file_exist: c_uchar, errptr: *mut *mut c_char) -> *mut rocksdb_t; pub fn rocksdb_open_for_read_only_column_families(options: *const rocksdb_options_t, name: *const c_char, num_column_families: c_int, column_family_names: *const *const c_char, column_family_options: *const *const rocksdb_options_t, column_family_handles: *mut *mut rocksdb_column_family_handle_t, error_if_log_file_exist: c_uchar, errptr: *mut *mut c_char) -> *mut rocksdb_t;
pub fn rocksdb_list_column_families(options: *const rocksdb_options_t, name: *const c_char, lencf: *mut size_t, errptr: *mut *mut c_char) -> *mut *mut c_char; pub fn rocksdb_list_column_families(options: *const rocksdb_options_t,
name: *const c_char,
lencf: *mut size_t,
errptr: *mut *mut c_char)
-> *mut *mut c_char;
pub fn rocksdb_list_column_families_destroy(list: *mut *mut c_char, len: size_t); pub fn rocksdb_list_column_families_destroy(list: *mut *mut c_char, len: size_t);
pub fn rocksdb_create_column_family(db: *mut rocksdb_t, column_family_options: *const rocksdb_options_t, column_family_name: *const c_char, errptr: *mut *mut c_char) -> *mut rocksdb_column_family_handle_t; pub fn rocksdb_create_column_family(db: *mut rocksdb_t,
column_family_options: *const rocksdb_options_t,
column_family_name: *const c_char,
errptr: *mut *mut c_char)
-> *mut rocksdb_column_family_handle_t;
pub fn rocksdb_drop_column_family(db: *mut rocksdb_t, handle: *mut rocksdb_column_family_handle_t, errptr: *mut *mut c_char); pub fn rocksdb_drop_column_family(db: *mut rocksdb_t,
handle: *mut rocksdb_column_family_handle_t,
errptr: *mut *mut c_char);
pub fn rocksdb_column_family_handle_destroy(handle: *mut rocksdb_column_family_handle_t); pub fn rocksdb_column_family_handle_destroy(handle: *mut rocksdb_column_family_handle_t);
pub fn rocksdb_close(db: *mut rocksdb_t); pub fn rocksdb_close(db: *mut rocksdb_t);
pub fn rocksdb_put(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, key: *const c_char, keylen: size_t, val: *const c_char, vallen: size_t, errptr: *mut *mut c_char); pub fn rocksdb_put(db: *mut rocksdb_t,
options: *const rocksdb_writeoptions_t,
pub fn rocksdb_put_cf(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, keylen: size_t, val: *const c_char, vallen: size_t, errptr: *mut *mut c_char); key: *const c_char,
keylen: size_t,
pub fn rocksdb_delete(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, key: *const c_char, keylen: size_t, errptr: *mut *mut c_char); val: *const c_char,
vallen: size_t,
pub fn rocksdb_delete_cf(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, keylen: size_t, errptr: *mut *mut c_char); errptr: *mut *mut c_char);
pub fn rocksdb_merge(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, key: *const c_char, keylen: size_t, val: *const c_char, vallen: size_t, errptr: *mut *mut c_char); pub fn rocksdb_put_cf(db: *mut rocksdb_t,
options: *const rocksdb_writeoptions_t,
pub fn rocksdb_merge_cf(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, keylen: size_t, val: *const c_char, vallen: size_t, errptr: *mut *mut c_char); column_family: *mut rocksdb_column_family_handle_t,
key: *const c_char,
pub fn rocksdb_write(db: *mut rocksdb_t, options: *const rocksdb_writeoptions_t, batch: *mut rocksdb_writebatch_t, errptr: *mut *mut c_char); keylen: size_t,
val: *const c_char,
pub fn rocksdb_get(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t, key: *const c_char, keylen: size_t, vallen: *mut size_t, errptr: *mut *mut c_char) -> *mut c_char; vallen: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_get_cf(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, keylen: size_t, vallen: *mut size_t, errptr: *mut *mut c_char) -> *mut c_char;
pub fn rocksdb_delete(db: *mut rocksdb_t,
pub fn rocksdb_multi_get(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t, num_keys: size_t, keys_list: *const *const c_char, keys_list_sizes: *const size_t, values_list: *mut *mut c_char, values_list_sizes: *mut size_t, errs: *mut *mut c_char); options: *const rocksdb_writeoptions_t,
key: *const c_char,
pub fn rocksdb_multi_get_cf(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t, column_families: *const *const rocksdb_column_family_handle_t, num_keys: size_t, keys_list: *const *const c_char, keys_list_sizes: *const size_t, values_list: *mut *mut c_char, values_list_sizes: *mut size_t, errs: *mut *mut c_char); keylen: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_create_iterator(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t) -> *mut rocksdb_iterator_t;
pub fn rocksdb_delete_cf(db: *mut rocksdb_t,
pub fn rocksdb_create_iterator_cf(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t, column_family: *mut rocksdb_column_family_handle_t) -> *mut rocksdb_iterator_t; options: *const rocksdb_writeoptions_t,
column_family: *mut rocksdb_column_family_handle_t,
pub fn rocksdb_create_iterators(db: *mut rocksdb_t, opts: *mut rocksdb_readoptions_t, column_families: *mut *mut rocksdb_column_family_handle_t, iterators: *mut *mut rocksdb_iterator_t, size: size_t, errptr: *mut *mut c_char); key: *const c_char,
keylen: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_merge(db: *mut rocksdb_t,
options: *const rocksdb_writeoptions_t,
key: *const c_char,
keylen: size_t,
val: *const c_char,
vallen: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_merge_cf(db: *mut rocksdb_t,
options: *const rocksdb_writeoptions_t,
column_family: *mut rocksdb_column_family_handle_t,
key: *const c_char,
keylen: size_t,
val: *const c_char,
vallen: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_write(db: *mut rocksdb_t,
options: *const rocksdb_writeoptions_t,
batch: *mut rocksdb_writebatch_t,
errptr: *mut *mut c_char);
pub fn rocksdb_get(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t,
key: *const c_char,
keylen: size_t,
vallen: *mut size_t,
errptr: *mut *mut c_char)
-> *mut c_char;
pub fn rocksdb_get_cf(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t,
column_family: *mut rocksdb_column_family_handle_t,
key: *const c_char,
keylen: size_t,
vallen: *mut size_t,
errptr: *mut *mut c_char)
-> *mut c_char;
pub fn rocksdb_multi_get(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t,
num_keys: size_t,
keys_list: *const *const c_char,
keys_list_sizes: *const size_t,
values_list: *mut *mut c_char,
values_list_sizes: *mut size_t,
errs: *mut *mut c_char);
pub fn rocksdb_multi_get_cf(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t,
column_families: *const *const rocksdb_column_family_handle_t,
num_keys: size_t,
keys_list: *const *const c_char,
keys_list_sizes: *const size_t,
values_list: *mut *mut c_char,
values_list_sizes: *mut size_t,
errs: *mut *mut c_char);
pub fn rocksdb_create_iterator(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t)
-> *mut rocksdb_iterator_t;
pub fn rocksdb_create_iterator_cf(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t,
column_family: *mut rocksdb_column_family_handle_t)
-> *mut rocksdb_iterator_t;
pub fn rocksdb_create_iterators(db: *mut rocksdb_t,
opts: *mut rocksdb_readoptions_t,
column_families: *mut *mut rocksdb_column_family_handle_t,
iterators: *mut *mut rocksdb_iterator_t,
size: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_create_snapshot(db: *mut rocksdb_t) -> *const rocksdb_snapshot_t; pub fn rocksdb_create_snapshot(db: *mut rocksdb_t) -> *const rocksdb_snapshot_t;
@ -113,31 +223,64 @@ extern "C" {
pub fn rocksdb_property_value(db: *mut rocksdb_t, propname: *const c_char) -> *mut c_char; pub fn rocksdb_property_value(db: *mut rocksdb_t, propname: *const c_char) -> *mut c_char;
pub fn rocksdb_property_value_cf(db: *mut rocksdb_t, column_family: *mut rocksdb_column_family_handle_t, propname: *const c_char) -> *mut c_char; pub fn rocksdb_property_value_cf(db: *mut rocksdb_t,
column_family: *mut rocksdb_column_family_handle_t,
pub fn rocksdb_approximate_sizes(db: *mut rocksdb_t, num_ranges: c_int, range_start_key: *const *const c_char, range_start_key_len: *const size_t, range_limit_key: *const *const c_char, range_limit_key_len: *const size_t, sizes: *mut uint64_t); propname: *const c_char)
-> *mut c_char;
pub fn rocksdb_approximate_sizes_cf(db: *mut rocksdb_t, column_family: *mut rocksdb_column_family_handle_t, num_ranges: c_int, range_start_key: *const *const c_char, range_start_key_len: *const size_t, range_limit_key: *const *const c_char, range_limit_key_len: *const size_t, sizes: *mut uint64_t);
pub fn rocksdb_approximate_sizes(db: *mut rocksdb_t,
pub fn rocksdb_compact_range(db: *mut rocksdb_t, start_key: *const c_char, start_key_len: size_t, limit_key: *const c_char, limit_key_len: size_t); num_ranges: c_int,
range_start_key: *const *const c_char,
pub fn rocksdb_compact_range_cf(db: *mut rocksdb_t, column_family: *mut rocksdb_column_family_handle_t, start_key: *const c_char, start_key_len: size_t, limit_key: *const c_char, limit_key_len: size_t); range_start_key_len: *const size_t,
range_limit_key: *const *const c_char,
range_limit_key_len: *const size_t,
sizes: *mut uint64_t);
pub fn rocksdb_approximate_sizes_cf(db: *mut rocksdb_t,
column_family: *mut rocksdb_column_family_handle_t,
num_ranges: c_int,
range_start_key: *const *const c_char,
range_start_key_len: *const size_t,
range_limit_key: *const *const c_char,
range_limit_key_len: *const size_t,
sizes: *mut uint64_t);
pub fn rocksdb_compact_range(db: *mut rocksdb_t,
start_key: *const c_char,
start_key_len: size_t,
limit_key: *const c_char,
limit_key_len: size_t);
pub fn rocksdb_compact_range_cf(db: *mut rocksdb_t,
column_family: *mut rocksdb_column_family_handle_t,
start_key: *const c_char,
start_key_len: size_t,
limit_key: *const c_char,
limit_key_len: size_t);
pub fn rocksdb_delete_file(db: *mut rocksdb_t, name: *const c_char); pub fn rocksdb_delete_file(db: *mut rocksdb_t, name: *const c_char);
pub fn rocksdb_livefiles(db: *mut rocksdb_t) -> *const rocksdb_livefiles_t; pub fn rocksdb_livefiles(db: *mut rocksdb_t) -> *const rocksdb_livefiles_t;
pub fn rocksdb_flush(db: *mut rocksdb_t, options: *const rocksdb_flushoptions_t, errptr: *mut *mut c_char); pub fn rocksdb_flush(db: *mut rocksdb_t,
options: *const rocksdb_flushoptions_t,
errptr: *mut *mut c_char);
pub fn rocksdb_disable_file_deletions(db: *mut rocksdb_t, errptr: *mut *mut c_char); pub fn rocksdb_disable_file_deletions(db: *mut rocksdb_t, errptr: *mut *mut c_char);
pub fn rocksdb_enable_file_deletions(db: *mut rocksdb_t, force: c_uchar, errptr: *mut *mut c_char); pub fn rocksdb_enable_file_deletions(db: *mut rocksdb_t,
force: c_uchar,
errptr: *mut *mut c_char);
// Management operations // Management operations
pub fn rocksdb_destroy_db(options: *const rocksdb_options_t, name: *const c_char, errptr: *mut *mut c_char); pub fn rocksdb_destroy_db(options: *const rocksdb_options_t,
name: *const c_char,
errptr: *mut *mut c_char);
pub fn rocksdb_repair_db(options: *const rocksdb_options_t, name: *const c_char, errptr: *mut *mut c_char); pub fn rocksdb_repair_db(options: *const rocksdb_options_t,
name: *const c_char,
errptr: *mut *mut c_char);
// Iterator // Iterator
@ -155,9 +298,13 @@ extern "C" {
pub fn rocksdb_iter_prev(iterator: *mut rocksdb_iterator_t); pub fn rocksdb_iter_prev(iterator: *mut rocksdb_iterator_t);
pub fn rocksdb_iter_key(iterator: *const rocksdb_iterator_t, klen: *mut size_t) -> *const c_char; pub fn rocksdb_iter_key(iterator: *const rocksdb_iterator_t,
klen: *mut size_t)
-> *const c_char;
pub fn rocksdb_iter_value(iterator: *const rocksdb_iterator_t, vlen: *mut size_t) -> *const c_char; pub fn rocksdb_iter_value(iterator: *const rocksdb_iterator_t,
vlen: *mut size_t)
-> *const c_char;
pub fn rocksdb_iter_get_error(iterator: *const rocksdb_iterator_t, errptr: *mut *mut c_char); pub fn rocksdb_iter_get_error(iterator: *const rocksdb_iterator_t, errptr: *mut *mut c_char);
@ -165,7 +312,9 @@ extern "C" {
pub fn rocksdb_writebatch_create() -> *mut rocksdb_writebatch_t; pub fn rocksdb_writebatch_create() -> *mut rocksdb_writebatch_t;
pub fn rocksdb_writebatch_create_from(rep: *const c_char, size: size_t) -> *mut rocksdb_writebatch_t; pub fn rocksdb_writebatch_create_from(rep: *const c_char,
size: size_t)
-> *mut rocksdb_writebatch_t;
pub fn rocksdb_writebatch_destroy(batch: *mut rocksdb_writebatch_t); pub fn rocksdb_writebatch_destroy(batch: *mut rocksdb_writebatch_t);
@ -173,35 +322,104 @@ extern "C" {
pub fn rocksdb_writebatch_count(batch: *mut rocksdb_writebatch_t) -> c_int; pub fn rocksdb_writebatch_count(batch: *mut rocksdb_writebatch_t) -> c_int;
pub fn rocksdb_writebatch_put(batch: *mut rocksdb_writebatch_t, key: *const c_char, klen: size_t, val: *const c_char, vlen: size_t); pub fn rocksdb_writebatch_put(batch: *mut rocksdb_writebatch_t,
key: *const c_char,
pub fn rocksdb_writebatch_put_cf(batch: *mut rocksdb_writebatch_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, klen: size_t, val: *const c_char, vlen: size_t); klen: size_t,
val: *const c_char,
pub fn rocksdb_writebatch_putv(b: *mut rocksdb_writebatch_t, num_keys: c_int, keys_list: *const *const c_char, keys_list_sizes: *const size_t, num_values: c_int, values_list: *const *const c_char, values_list_sizes: *const size_t); vlen: size_t);
pub fn rocksdb_writebatch_putv_cf(b: *mut rocksdb_writebatch_t, column_family: *mut rocksdb_column_family_handle_t, num_keys: c_int, keys_list: *const *const c_char, keys_list_sizes: *const size_t, num_values: c_int, values_list: *const *const c_char, values_list_sizes: *const size_t); pub fn rocksdb_writebatch_put_cf(batch: *mut rocksdb_writebatch_t,
column_family: *mut rocksdb_column_family_handle_t,
pub fn rocksdb_writebatch_merge(batch: *mut rocksdb_writebatch_t, key: *const c_char, klen: size_t, val: *const c_char, vlen: size_t); key: *const c_char,
klen: size_t,
pub fn rocksdb_writebatch_merge_cf(batch: *mut rocksdb_writebatch_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, klen: size_t, val: *const c_char, vlen: size_t); val: *const c_char,
vlen: size_t);
pub fn rocksdb_writebatch_mergev(b: *mut rocksdb_writebatch_t, num_keys: c_int, keys_list: *const *const c_char, keys_list_sizes: *const size_t, num_values: c_int, values_list: *const *const c_char, values_list_sizes: *const size_t);
pub fn rocksdb_writebatch_putv(b: *mut rocksdb_writebatch_t,
pub fn rocksdb_writebatch_mergev_cf(b: *mut rocksdb_writebatch_t, column_family: *mut rocksdb_column_family_handle_t, num_keys: c_int, keys_list: *const *const c_char, keys_list_sizes: *const size_t, num_values: c_int, values_list: *const *const c_char, values_list_sizes: *const size_t); num_keys: c_int,
keys_list: *const *const c_char,
pub fn rocksdb_writebatch_delete(batch: *mut rocksdb_writebatch_t, key: *const c_char, klen: size_t); keys_list_sizes: *const size_t,
num_values: c_int,
pub fn rocksdb_writebatch_delete_cf(batch: *mut rocksdb_writebatch_t, column_family: *mut rocksdb_column_family_handle_t, key: *const c_char, klen: size_t); values_list: *const *const c_char,
values_list_sizes: *const size_t);
pub fn rocksdb_writebatch_deletev(b: *mut rocksdb_writebatch_t, num_keys: c_int, keys_list: *const *const c_char, keys_list_sizes: *const size_t);
pub fn rocksdb_writebatch_putv_cf(b: *mut rocksdb_writebatch_t,
pub fn rocksdb_writebatch_deletev_cf(b: *mut rocksdb_writebatch_t, column_family: *mut rocksdb_column_family_handle_t, num_keys: c_int, keys_list: *const *const c_char, keys_list_sizes: *const size_t); column_family: *mut rocksdb_column_family_handle_t,
num_keys: c_int,
pub fn rocksdb_writebatch_put_log_data(batch: *mut rocksdb_writebatch_t, blob: *const c_char, len: size_t); keys_list: *const *const c_char,
keys_list_sizes: *const size_t,
pub fn rocksdb_writebatch_iterate(batch: *mut rocksdb_writebatch_t, state: *mut c_void, put: Option<unsafe extern "C" fn(state: *mut c_void, k: *const c_char, klen: size_t, v: *const c_char, vlen: size_t)>, deleted: Option<unsafe extern "C" fn(state: *mut c_void, k: *const c_char, klen: size_t)>); num_values: c_int,
values_list: *const *const c_char,
pub fn rocksdb_writebatch_data(batch: *mut rocksdb_writebatch_t, size: *mut size_t) -> *const c_char; values_list_sizes: *const size_t);
pub fn rocksdb_writebatch_merge(batch: *mut rocksdb_writebatch_t,
key: *const c_char,
klen: size_t,
val: *const c_char,
vlen: size_t);
pub fn rocksdb_writebatch_merge_cf(batch: *mut rocksdb_writebatch_t,
column_family: *mut rocksdb_column_family_handle_t,
key: *const c_char,
klen: size_t,
val: *const c_char,
vlen: size_t);
pub fn rocksdb_writebatch_mergev(b: *mut rocksdb_writebatch_t,
num_keys: c_int,
keys_list: *const *const c_char,
keys_list_sizes: *const size_t,
num_values: c_int,
values_list: *const *const c_char,
values_list_sizes: *const size_t);
pub fn rocksdb_writebatch_mergev_cf(b: *mut rocksdb_writebatch_t,
column_family: *mut rocksdb_column_family_handle_t,
num_keys: c_int,
keys_list: *const *const c_char,
keys_list_sizes: *const size_t,
num_values: c_int,
values_list: *const *const c_char,
values_list_sizes: *const size_t);
pub fn rocksdb_writebatch_delete(batch: *mut rocksdb_writebatch_t,
key: *const c_char,
klen: size_t);
pub fn rocksdb_writebatch_delete_cf(batch: *mut rocksdb_writebatch_t,
column_family: *mut rocksdb_column_family_handle_t,
key: *const c_char,
klen: size_t);
pub fn rocksdb_writebatch_deletev(b: *mut rocksdb_writebatch_t,
num_keys: c_int,
keys_list: *const *const c_char,
keys_list_sizes: *const size_t);
pub fn rocksdb_writebatch_deletev_cf(b: *mut rocksdb_writebatch_t,
column_family: *mut rocksdb_column_family_handle_t,
num_keys: c_int,
keys_list: *const *const c_char,
keys_list_sizes: *const size_t);
pub fn rocksdb_writebatch_put_log_data(batch: *mut rocksdb_writebatch_t,
blob: *const c_char,
len: size_t);
pub fn rocksdb_writebatch_iterate(batch: *mut rocksdb_writebatch_t,
state: *mut c_void,
put: Option<unsafe extern "C" fn(state: *mut c_void,
k: *const c_char,
klen: size_t,
v: *const c_char,
vlen: size_t)>,
deleted: Option<unsafe extern "C" fn(state: *mut c_void,
k: *const c_char,
klen: size_t)>);
pub fn rocksdb_writebatch_data(batch: *mut rocksdb_writebatch_t,
size: *mut size_t)
-> *const c_char;
// Block-based table options // Block-based table options
@ -233,7 +451,9 @@ extern "C" {
pub fn rocksdb_block_based_options_set_cache_index_and_filter_blocks(options: *mut rocksdb_block_based_table_options_t, v: c_uchar); pub fn rocksdb_block_based_options_set_cache_index_and_filter_blocks(options: *mut rocksdb_block_based_table_options_t, v: c_uchar);
pub fn rocksdb_block_based_options_set_pin_l0_filter_and_index_blocks_in_cache(options: *mut rocksdb_block_based_table_options_t, v: c_uchar); pub fn rocksdb_block_based_options_set_pin_l0_filter_and_index_blocks_in_cache
(options: *mut rocksdb_block_based_table_options_t,
v: c_uchar);
pub fn rocksdb_block_based_options_set_skip_table_builder_flush(options: *mut rocksdb_block_based_table_options_t, skip_table_builder_flush: c_uchar); pub fn rocksdb_block_based_options_set_skip_table_builder_flush(options: *mut rocksdb_block_based_table_options_t, skip_table_builder_flush: c_uchar);
@ -245,15 +465,18 @@ extern "C" {
pub fn rocksdb_cuckoo_options_destroy(options: *mut rocksdb_cuckoo_table_options_t); pub fn rocksdb_cuckoo_options_destroy(options: *mut rocksdb_cuckoo_table_options_t);
pub fn rocksdb_cuckoo_options_set_hash_ratio(options: *mut rocksdb_cuckoo_table_options_t, v: f64); pub fn rocksdb_cuckoo_options_set_hash_ratio(options: *mut rocksdb_cuckoo_table_options_t,
v: f64);
pub fn rocksdb_cuckoo_options_set_max_search_depth(options: *mut rocksdb_cuckoo_table_options_t, v: uint32_t); pub fn rocksdb_cuckoo_options_set_max_search_depth(options: *mut rocksdb_cuckoo_table_options_t,
v: uint32_t);
pub fn rocksdb_cuckoo_options_set_cuckoo_block_size(options: *mut rocksdb_cuckoo_table_options_t, v: uint32_t); pub fn rocksdb_cuckoo_options_set_cuckoo_block_size(options: *mut rocksdb_cuckoo_table_options_t, v: uint32_t);
pub fn rocksdb_cuckoo_options_set_identity_as_first_hash(options: *mut rocksdb_cuckoo_table_options_t, v: c_uchar); pub fn rocksdb_cuckoo_options_set_identity_as_first_hash(options: *mut rocksdb_cuckoo_table_options_t, v: c_uchar);
pub fn rocksdb_cuckoo_options_set_use_module_hash(options: *mut rocksdb_cuckoo_table_options_t, v: c_uchar); pub fn rocksdb_cuckoo_options_set_use_module_hash(options: *mut rocksdb_cuckoo_table_options_t,
v: c_uchar);
pub fn rocksdb_options_set_cuckoo_table_factory(opt: *mut rocksdb_options_t, table_options: *mut rocksdb_cuckoo_table_options_t); pub fn rocksdb_options_set_cuckoo_table_factory(opt: *mut rocksdb_options_t, table_options: *mut rocksdb_cuckoo_table_options_t);
@ -263,31 +486,41 @@ extern "C" {
pub fn rocksdb_options_destroy(opt: *mut rocksdb_options_t); pub fn rocksdb_options_destroy(opt: *mut rocksdb_options_t);
pub fn rocksdb_options_increase_parallelism(opt: *mut rocksdb_options_t, total_threads: c_int); pub fn rocksdb_options_increase_parallelism(opt: *mut rocksdb_options_t,
total_threads: c_int);
pub fn rocksdb_options_optimize_for_point_lookup(opt: *mut rocksdb_options_t, block_cache_size_mb: uint64_t); pub fn rocksdb_options_optimize_for_point_lookup(opt: *mut rocksdb_options_t,
block_cache_size_mb: uint64_t);
pub fn rocksdb_options_optimize_level_style_compaction(opt: *mut rocksdb_options_t, memtable_memory_budget: uint64_t); pub fn rocksdb_options_optimize_level_style_compaction(opt: *mut rocksdb_options_t,
memtable_memory_budget: uint64_t);
pub fn rocksdb_options_optimize_universal_style_compaction(opt: *mut rocksdb_options_t, memtable_memory_budget: uint64_t); pub fn rocksdb_options_optimize_universal_style_compaction(opt: *mut rocksdb_options_t,
memtable_memory_budget: uint64_t);
pub fn rocksdb_options_set_compaction_filter(opt: *mut rocksdb_options_t, filter: *mut rocksdb_compactionfilter_t); pub fn rocksdb_options_set_compaction_filter(opt: *mut rocksdb_options_t,
filter: *mut rocksdb_compactionfilter_t);
pub fn rocksdb_options_set_compaction_filter_factory(opt: *mut rocksdb_options_t, factory: *mut rocksdb_compactionfilterfactory_t); pub fn rocksdb_options_set_compaction_filter_factory(opt: *mut rocksdb_options_t, factory: *mut rocksdb_compactionfilterfactory_t);
pub fn rocksdb_options_compaction_readahead_size(opt: *mut rocksdb_options_t, s: size_t); pub fn rocksdb_options_compaction_readahead_size(opt: *mut rocksdb_options_t, s: size_t);
pub fn rocksdb_options_set_comparator(opt: *mut rocksdb_options_t, cmp: *mut rocksdb_comparator_t); pub fn rocksdb_options_set_comparator(opt: *mut rocksdb_options_t,
cmp: *mut rocksdb_comparator_t);
pub fn rocksdb_options_set_merge_operator(opt: *mut rocksdb_options_t, merge_operator: *mut rocksdb_mergeoperator_t); pub fn rocksdb_options_set_merge_operator(opt: *mut rocksdb_options_t,
merge_operator: *mut rocksdb_mergeoperator_t);
pub fn rocksdb_options_set_uint64add_merge_operator(opt: *mut rocksdb_options_t); pub fn rocksdb_options_set_uint64add_merge_operator(opt: *mut rocksdb_options_t);
pub fn rocksdb_options_set_compression_per_level(opt: *mut rocksdb_options_t, level_values: *const c_int, num_levels: size_t); pub fn rocksdb_options_set_compression_per_level(opt: *mut rocksdb_options_t,
level_values: *const c_int,
num_levels: size_t);
pub fn rocksdb_options_set_create_if_missing(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_create_if_missing(opt: *mut rocksdb_options_t, v: c_uchar);
pub fn rocksdb_options_set_create_missing_column_families(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_create_missing_column_families(opt: *mut rocksdb_options_t,
v: c_uchar);
pub fn rocksdb_options_set_error_if_exists(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_error_if_exists(opt: *mut rocksdb_options_t, v: c_uchar);
@ -307,15 +540,22 @@ extern "C" {
pub fn rocksdb_options_set_max_total_wal_size(opt: *mut rocksdb_options_t, n: uint64_t); pub fn rocksdb_options_set_max_total_wal_size(opt: *mut rocksdb_options_t, n: uint64_t);
pub fn rocksdb_options_set_compression_options(opt: *mut rocksdb_options_t, w_bits: c_int, level: c_int, strategy: c_int, max_dict_bytes: c_int); pub fn rocksdb_options_set_compression_options(opt: *mut rocksdb_options_t,
w_bits: c_int,
level: c_int,
strategy: c_int,
max_dict_bytes: c_int);
pub fn rocksdb_options_set_prefix_extractor(opt: *mut rocksdb_options_t, prefix_extractor: *mut rocksdb_slicetransform_t); pub fn rocksdb_options_set_prefix_extractor(opt: *mut rocksdb_options_t,
prefix_extractor: *mut rocksdb_slicetransform_t);
pub fn rocksdb_options_set_num_levels(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_num_levels(opt: *mut rocksdb_options_t, n: c_int);
pub fn rocksdb_options_set_level0_file_num_compaction_trigger(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_level0_file_num_compaction_trigger(opt: *mut rocksdb_options_t,
n: c_int);
pub fn rocksdb_options_set_level0_slowdown_writes_trigger(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_level0_slowdown_writes_trigger(opt: *mut rocksdb_options_t,
n: c_int);
pub fn rocksdb_options_set_level0_stop_writes_trigger(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_level0_stop_writes_trigger(opt: *mut rocksdb_options_t, n: c_int);
@ -327,11 +567,13 @@ extern "C" {
pub fn rocksdb_options_set_max_bytes_for_level_base(opt: *mut rocksdb_options_t, n: uint64_t); pub fn rocksdb_options_set_max_bytes_for_level_base(opt: *mut rocksdb_options_t, n: uint64_t);
pub fn rocksdb_options_set_max_bytes_for_level_multiplier(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_max_bytes_for_level_multiplier(opt: *mut rocksdb_options_t,
n: c_int);
pub fn rocksdb_options_set_expanded_compaction_factor(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_expanded_compaction_factor(opt: *mut rocksdb_options_t, v: c_int);
pub fn rocksdb_options_set_max_grandparent_overlap_factor(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_max_grandparent_overlap_factor(opt: *mut rocksdb_options_t,
v: c_int);
pub fn rocksdb_options_set_max_bytes_for_level_multiplier_additional(opt: *mut rocksdb_options_t, level_values: *mut c_int, num_levels: size_t); pub fn rocksdb_options_set_max_bytes_for_level_multiplier_additional(opt: *mut rocksdb_options_t, level_values: *mut c_int, num_levels: size_t);
@ -341,9 +583,11 @@ extern "C" {
pub fn rocksdb_options_set_max_write_buffer_number(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_max_write_buffer_number(opt: *mut rocksdb_options_t, n: c_int);
pub fn rocksdb_options_set_min_write_buffer_number_to_merge(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_min_write_buffer_number_to_merge(opt: *mut rocksdb_options_t,
n: c_int);
pub fn rocksdb_options_set_max_write_buffer_number_to_maintain(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_max_write_buffer_number_to_maintain(opt: *mut rocksdb_options_t,
n: c_int);
pub fn rocksdb_options_set_max_background_compactions(opt: *mut rocksdb_options_t, n: c_int); pub fn rocksdb_options_set_max_background_compactions(opt: *mut rocksdb_options_t, n: c_int);
@ -361,13 +605,15 @@ extern "C" {
pub fn rocksdb_options_set_hard_rate_limit(opt: *mut rocksdb_options_t, v: f64); pub fn rocksdb_options_set_hard_rate_limit(opt: *mut rocksdb_options_t, v: f64);
pub fn rocksdb_options_set_rate_limit_delay_max_milliseconds(opt: *mut rocksdb_options_t, v: c_uint); pub fn rocksdb_options_set_rate_limit_delay_max_milliseconds(opt: *mut rocksdb_options_t,
v: c_uint);
pub fn rocksdb_options_set_max_manifest_file_size(opt: *mut rocksdb_options_t, v: size_t); pub fn rocksdb_options_set_max_manifest_file_size(opt: *mut rocksdb_options_t, v: size_t);
pub fn rocksdb_options_set_table_cache_numshardbits(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_table_cache_numshardbits(opt: *mut rocksdb_options_t, v: c_int);
pub fn rocksdb_options_set_table_cache_remove_scan_count_limit(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_table_cache_remove_scan_count_limit(opt: *mut rocksdb_options_t,
v: c_int);
pub fn rocksdb_options_set_arena_block_size(opt: *mut rocksdb_options_t, v: size_t); pub fn rocksdb_options_set_arena_block_size(opt: *mut rocksdb_options_t, v: size_t);
@ -381,9 +627,11 @@ extern "C" {
pub fn rocksdb_options_set_WAL_size_limit_MB(opt: *mut rocksdb_options_t, limit: uint64_t); pub fn rocksdb_options_set_WAL_size_limit_MB(opt: *mut rocksdb_options_t, limit: uint64_t);
pub fn rocksdb_options_set_manifest_preallocation_size(opt: *mut rocksdb_options_t, v: size_t); pub fn rocksdb_options_set_manifest_preallocation_size(opt: *mut rocksdb_options_t,
v: size_t);
pub fn rocksdb_options_set_purge_redundant_kvs_while_flush(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_purge_redundant_kvs_while_flush(opt: *mut rocksdb_options_t,
v: c_uchar);
pub fn rocksdb_options_set_allow_os_buffer(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_allow_os_buffer(opt: *mut rocksdb_options_t, v: c_uchar);
@ -393,29 +641,34 @@ extern "C" {
pub fn rocksdb_options_set_is_fd_close_on_exec(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_is_fd_close_on_exec(opt: *mut rocksdb_options_t, v: c_uchar);
pub fn rocksdb_options_set_skip_log_error_on_recovery(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_skip_log_error_on_recovery(opt: *mut rocksdb_options_t,
v: c_uchar);
pub fn rocksdb_options_set_stats_dump_period_sec(opt: *mut rocksdb_options_t, v: c_uint); pub fn rocksdb_options_set_stats_dump_period_sec(opt: *mut rocksdb_options_t, v: c_uint);
pub fn rocksdb_options_set_advise_random_on_open(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_advise_random_on_open(opt: *mut rocksdb_options_t, v: c_uchar);
pub fn rocksdb_options_set_access_hint_on_compaction_start(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_access_hint_on_compaction_start(opt: *mut rocksdb_options_t,
v: c_int);
pub fn rocksdb_options_set_use_adaptive_mutex(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_use_adaptive_mutex(opt: *mut rocksdb_options_t, v: c_uchar);
pub fn rocksdb_options_set_bytes_per_sync(opt: *mut rocksdb_options_t, v: uint64_t); pub fn rocksdb_options_set_bytes_per_sync(opt: *mut rocksdb_options_t, v: uint64_t);
pub fn rocksdb_options_set_verify_checksums_in_compaction(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_verify_checksums_in_compaction(opt: *mut rocksdb_options_t,
v: c_uchar);
pub fn rocksdb_options_set_filter_deletes(opt: *mut rocksdb_options_t, v: c_uchar); pub fn rocksdb_options_set_filter_deletes(opt: *mut rocksdb_options_t, v: c_uchar);
pub fn rocksdb_options_set_max_sequential_skip_in_iterations(opt: *mut rocksdb_options_t, v: uint64_t); pub fn rocksdb_options_set_max_sequential_skip_in_iterations(opt: *mut rocksdb_options_t,
v: uint64_t);
pub fn rocksdb_options_set_disable_data_sync(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_disable_data_sync(opt: *mut rocksdb_options_t, v: c_int);
pub fn rocksdb_options_set_disable_auto_compactions(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_disable_auto_compactions(opt: *mut rocksdb_options_t, v: c_int);
pub fn rocksdb_options_set_delete_obsolete_files_period_micros(opt: *mut rocksdb_options_t, v: uint64_t); pub fn rocksdb_options_set_delete_obsolete_files_period_micros(opt: *mut rocksdb_options_t,
v: uint64_t);
pub fn rocksdb_options_set_source_compaction_factor(opt: *mut rocksdb_options_t, v: c_int); pub fn rocksdb_options_set_source_compaction_factor(opt: *mut rocksdb_options_t, v: c_int);
@ -423,23 +676,34 @@ extern "C" {
pub fn rocksdb_options_set_memtable_vector_rep(opt: *mut rocksdb_options_t); pub fn rocksdb_options_set_memtable_vector_rep(opt: *mut rocksdb_options_t);
pub fn rocksdb_options_set_hash_skip_list_rep(opt: *mut rocksdb_options_t, bucket_count: size_t, skiplist_height: int32_t, skiplist_branching_factor: int32_t); pub fn rocksdb_options_set_hash_skip_list_rep(opt: *mut rocksdb_options_t,
bucket_count: size_t,
skiplist_height: int32_t,
skiplist_branching_factor: int32_t);
pub fn rocksdb_options_set_hash_link_list_rep(opt: *mut rocksdb_options_t, bucket_count: size_t); pub fn rocksdb_options_set_hash_link_list_rep(opt: *mut rocksdb_options_t,
bucket_count: size_t);
pub fn rocksdb_options_set_plain_table_factory(opt: *mut rocksdb_options_t, user_key_len: uint32_t, bloom_bits_per_key: c_int, hash_table_ratio: f64, index_sparseness: size_t); pub fn rocksdb_options_set_plain_table_factory(opt: *mut rocksdb_options_t,
user_key_len: uint32_t,
bloom_bits_per_key: c_int,
hash_table_ratio: f64,
index_sparseness: size_t);
pub fn rocksdb_options_set_min_level_to_compress(opt: *mut rocksdb_options_t, level: c_int); pub fn rocksdb_options_set_min_level_to_compress(opt: *mut rocksdb_options_t, level: c_int);
pub fn rocksdb_options_set_memtable_prefix_bloom_bits(opt: *mut rocksdb_options_t, v: uint32_t); pub fn rocksdb_options_set_memtable_prefix_bloom_bits(opt: *mut rocksdb_options_t,
v: uint32_t);
pub fn rocksdb_options_set_memtable_prefix_bloom_probes(opt: *mut rocksdb_options_t, v: uint32_t); pub fn rocksdb_options_set_memtable_prefix_bloom_probes(opt: *mut rocksdb_options_t,
v: uint32_t);
pub fn rocksdb_options_set_memtable_huge_page_size(opt: *mut rocksdb_options_t, v: size_t); pub fn rocksdb_options_set_memtable_huge_page_size(opt: *mut rocksdb_options_t, v: size_t);
pub fn rocksdb_options_set_max_successive_merges(opt: *mut rocksdb_options_t, v: size_t); pub fn rocksdb_options_set_max_successive_merges(opt: *mut rocksdb_options_t, v: size_t);
pub fn rocksdb_options_set_min_partial_merge_operands(opt: *mut rocksdb_options_t, v: uint32_t); pub fn rocksdb_options_set_min_partial_merge_operands(opt: *mut rocksdb_options_t,
v: uint32_t);
pub fn rocksdb_options_set_bloom_locality(opt: *mut rocksdb_options_t, v: uint32_t); pub fn rocksdb_options_set_bloom_locality(opt: *mut rocksdb_options_t, v: uint32_t);
@ -457,13 +721,29 @@ extern "C" {
pub fn rocksdb_options_set_universal_compaction_options(opt: *mut rocksdb_options_t, uco: *mut rocksdb_universal_compaction_options_t); pub fn rocksdb_options_set_universal_compaction_options(opt: *mut rocksdb_options_t, uco: *mut rocksdb_universal_compaction_options_t);
pub fn rocksdb_options_set_fifo_compaction_options(opt: *mut rocksdb_options_t, fifo: *mut rocksdb_fifo_compaction_options_t); pub fn rocksdb_options_set_fifo_compaction_options(opt: *mut rocksdb_options_t,
fifo: *mut rocksdb_fifo_compaction_options_t);
// Compaction filter // Compaction filter
pub fn rocksdb_compactionfilter_create(state: *mut c_void, destructor: Option<unsafe extern "C" fn(state: *mut c_void)>, filter: Option<unsafe extern "C" fn(state: *mut c_void, level: c_int, key: *const c_char, key_length: size_t, existing_value: *const c_char, value_length: size_t, new_value: *mut *mut c_char, new_value_length: *mut size_t, value_changed: *mut c_uchar) -> c_uchar>, name: Option<unsafe extern "C" fn(state: *mut c_void) -> *const c_char>) -> *mut rocksdb_compactionfilter_t; pub fn rocksdb_compactionfilter_create
(state: *mut c_void,
pub fn rocksdb_compactionfilter_set_ignore_snapshots(filter: *mut rocksdb_compactionfilter_t, v: c_uchar); destructor: Option<unsafe extern "C" fn(state: *mut c_void)>,
filter: Option<unsafe extern "C" fn(state: *mut c_void,
level: c_int,
key: *const c_char,
key_length: size_t,
existing_value: *const c_char,
value_length: size_t,
new_value: *mut *mut c_char,
new_value_length: *mut size_t,
value_changed: *mut c_uchar)
-> c_uchar>,
name: Option<unsafe extern "C" fn(state: *mut c_void) -> *const c_char>)
-> *mut rocksdb_compactionfilter_t;
pub fn rocksdb_compactionfilter_set_ignore_snapshots(filter: *mut rocksdb_compactionfilter_t,
v: c_uchar);
pub fn rocksdb_compactionfilter_destroy(filter: *mut rocksdb_compactionfilter_t); pub fn rocksdb_compactionfilter_destroy(filter: *mut rocksdb_compactionfilter_t);
@ -481,7 +761,17 @@ extern "C" {
// Comparator // Comparator
pub fn rocksdb_comparator_create(state: *mut c_void, destructor: Option<unsafe extern "C" fn(state: *mut c_void)>, compare: Option<unsafe extern "C" fn(state: *mut c_void, a: *const c_char, alen: size_t, b: *const c_char, blen: size_t) -> c_int>, name: Option<unsafe extern "C" fn(state: *mut c_void) -> *const c_char>) -> *mut rocksdb_comparator_t; pub fn rocksdb_comparator_create(state: *mut c_void,
destructor: Option<unsafe extern "C" fn(state: *mut c_void)>,
compare: Option<unsafe extern "C" fn(state: *mut c_void,
a: *const c_char,
alen: size_t,
b: *const c_char,
blen: size_t)
-> c_int>,
name: Option<unsafe extern "C" fn(state: *mut c_void)
-> *const c_char>)
-> *mut rocksdb_comparator_t;
pub fn rocksdb_comparator_destroy(cmp: *mut rocksdb_comparator_t); pub fn rocksdb_comparator_destroy(cmp: *mut rocksdb_comparator_t);
@ -511,9 +801,12 @@ extern "C" {
pub fn rocksdb_readoptions_set_fill_cache(opt: *mut rocksdb_readoptions_t, v: c_uchar); pub fn rocksdb_readoptions_set_fill_cache(opt: *mut rocksdb_readoptions_t, v: c_uchar);
pub fn rocksdb_readoptions_set_snapshot(opt: *mut rocksdb_readoptions_t, v: *const rocksdb_snapshot_t); pub fn rocksdb_readoptions_set_snapshot(opt: *mut rocksdb_readoptions_t,
v: *const rocksdb_snapshot_t);
pub fn rocksdb_readoptions_set_iterate_upper_bound(opt: *mut rocksdb_readoptions_t, key: *const c_char, keylen: size_t); pub fn rocksdb_readoptions_set_iterate_upper_bound(opt: *mut rocksdb_readoptions_t,
key: *const c_char,
keylen: size_t);
pub fn rocksdb_readoptions_set_read_tier(opt: *mut rocksdb_readoptions_t, v: c_int); pub fn rocksdb_readoptions_set_read_tier(opt: *mut rocksdb_readoptions_t, v: c_int);
@ -573,7 +866,9 @@ extern "C" {
// Universal Compaction options // Universal Compaction options
pub fn rocksdb_universal_compaction_options_create() -> *mut rocksdb_universal_compaction_options_t; pub fn rocksdb_universal_compaction_options_create
()
-> *mut rocksdb_universal_compaction_options_t;
pub fn rocksdb_universal_compaction_options_set_size_ratio(uco: *mut rocksdb_universal_compaction_options_t, ratio: c_int); pub fn rocksdb_universal_compaction_options_set_size_ratio(uco: *mut rocksdb_universal_compaction_options_t, ratio: c_int);
@ -581,9 +876,13 @@ extern "C" {
pub fn rocksdb_universal_compaction_options_set_max_merge_width(uco: *mut rocksdb_universal_compaction_options_t, w: c_int); pub fn rocksdb_universal_compaction_options_set_max_merge_width(uco: *mut rocksdb_universal_compaction_options_t, w: c_int);
pub fn rocksdb_universal_compaction_options_set_max_size_amplification_percent(uco: *mut rocksdb_universal_compaction_options_t, p: c_int); pub fn rocksdb_universal_compaction_options_set_max_size_amplification_percent
(uco: *mut rocksdb_universal_compaction_options_t,
p: c_int);
pub fn rocksdb_universal_compaction_options_set_compression_size_percent(uco: *mut rocksdb_universal_compaction_options_t, p: c_int); pub fn rocksdb_universal_compaction_options_set_compression_size_percent
(uco: *mut rocksdb_universal_compaction_options_t,
p: c_int);
pub fn rocksdb_universal_compaction_options_set_stop_style(uco: *mut rocksdb_universal_compaction_options_t, style: c_int); pub fn rocksdb_universal_compaction_options_set_stop_style(uco: *mut rocksdb_universal_compaction_options_t, style: c_int);
@ -597,25 +896,47 @@ extern "C" {
pub fn rocksdb_livefiles_count(files: *const rocksdb_livefiles_t) -> c_int; pub fn rocksdb_livefiles_count(files: *const rocksdb_livefiles_t) -> c_int;
pub fn rocksdb_livefiles_name(files: *const rocksdb_livefiles_t, index: c_int) -> *const c_char; pub fn rocksdb_livefiles_name(files: *const rocksdb_livefiles_t,
index: c_int)
-> *const c_char;
pub fn rocksdb_livefiles_level(files: *const rocksdb_livefiles_t, index: c_int) -> c_int; pub fn rocksdb_livefiles_level(files: *const rocksdb_livefiles_t, index: c_int) -> c_int;
pub fn rocksdb_livefiles_size(files: *const rocksdb_livefiles_t, index: c_int) -> size_t; pub fn rocksdb_livefiles_size(files: *const rocksdb_livefiles_t, index: c_int) -> size_t;
pub fn rocksdb_livefiles_smallestkey(files: *const rocksdb_livefiles_t, index: c_int, size: *mut size_t) -> *const c_char; pub fn rocksdb_livefiles_smallestkey(files: *const rocksdb_livefiles_t,
index: c_int,
size: *mut size_t)
-> *const c_char;
pub fn rocksdb_livefiles_largestkey(files: *const rocksdb_livefiles_t, index: c_int, size: *mut size_t) -> *const c_char; pub fn rocksdb_livefiles_largestkey(files: *const rocksdb_livefiles_t,
index: c_int,
size: *mut size_t)
-> *const c_char;
pub fn rocksdb_livefiles_destroy(files: *const rocksdb_livefiles_t); pub fn rocksdb_livefiles_destroy(files: *const rocksdb_livefiles_t);
// Utilities // Utilities
pub fn rocksdb_get_options_from_string(base_options: *const rocksdb_options_t, opts_str: *const c_char, new_options: *mut rocksdb_options_t, errptr: *mut *mut c_char); pub fn rocksdb_get_options_from_string(base_options: *const rocksdb_options_t,
opts_str: *const c_char,
pub fn rocksdb_delete_file_in_range(db: *mut rocksdb_t, start_key: *const c_char, start_key_len: size_t, limit_key: *const c_char, limit_key_len: size_t, errptr: *mut *mut c_char); new_options: *mut rocksdb_options_t,
errptr: *mut *mut c_char);
pub fn rocksdb_delete_file_in_range_cf(db: *mut rocksdb_t, column_family: *mut rocksdb_column_family_handle_t, start_key: *const c_char, start_key_len: size_t, limit_key: *const c_char, limit_key_len: size_t, errptr: *mut *mut c_char);
pub fn rocksdb_delete_file_in_range(db: *mut rocksdb_t,
start_key: *const c_char,
start_key_len: size_t,
limit_key: *const c_char,
limit_key_len: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_delete_file_in_range_cf(db: *mut rocksdb_t,
column_family: *mut rocksdb_column_family_handle_t,
start_key: *const c_char,
start_key_len: size_t,
limit_key: *const c_char,
limit_key_len: size_t,
errptr: *mut *mut c_char);
pub fn rocksdb_free(ptr: *mut c_void); pub fn rocksdb_free(ptr: *mut c_void);
} }

@ -89,10 +89,14 @@ macro_rules! CheckCondition {
unsafe fn CheckEqual(expected: *const c_char, v: *const c_char, n: size_t) { unsafe fn CheckEqual(expected: *const c_char, v: *const c_char, n: size_t) {
if expected.is_null() && v.is_null() { if expected.is_null() && v.is_null() {
// ok // ok
} else if !expected.is_null() && !v.is_null() && n == strlen(expected) && memcmp(expected as *const c_void, v as *const c_void, n) == 0 { } else if !expected.is_null() && !v.is_null() && n == strlen(expected) &&
memcmp(expected as *const c_void, v as *const c_void, n) == 0 {
// ok // ok
} else { } else {
panic!("{}: expected '{}', got '{}'", phase, rstr(strndup(expected, n)), rstr(strndup(v, 5))); panic!("{}: expected '{}', got '{}'",
phase,
rstr(strndup(expected, n)),
rstr(strndup(v, 5)));
} }
} }
@ -103,25 +107,41 @@ unsafe fn Free<T>(ptr: *mut *mut T) {
} }
} }
unsafe fn CheckGet(mut db: *mut rocksdb_t, options: *mut rocksdb_readoptions_t, key: *const c_char, expected: *const c_char) { unsafe fn CheckGet(mut db: *mut rocksdb_t,
options: *mut rocksdb_readoptions_t,
key: *const c_char,
expected: *const c_char) {
let mut err: *mut c_char = ptr::null_mut(); let mut err: *mut c_char = ptr::null_mut();
let mut val_len: size_t = 0; let mut val_len: size_t = 0;
let mut val: *mut c_char = rocksdb_get(db, options, key, strlen(key), &mut val_len, &mut err); let mut val: *mut c_char =
rocksdb_get(db, options, key, strlen(key), &mut val_len, &mut err);
CheckNoError!(err); CheckNoError!(err);
CheckEqual(expected, val, val_len); CheckEqual(expected, val, val_len);
Free(&mut val); Free(&mut val);
} }
unsafe fn CheckGetCF(db: *mut rocksdb_t, options: *const rocksdb_readoptions_t, handle: *mut rocksdb_column_family_handle_t, key: *const c_char, expected: *const c_char) { unsafe fn CheckGetCF(db: *mut rocksdb_t,
options: *const rocksdb_readoptions_t,
handle: *mut rocksdb_column_family_handle_t,
key: *const c_char,
expected: *const c_char) {
let mut err: *mut c_char = ptr::null_mut(); let mut err: *mut c_char = ptr::null_mut();
let mut val_len: size_t = 0; let mut val_len: size_t = 0;
let mut val: *mut c_char = rocksdb_get_cf(db, options, handle, key, strlen(key), &mut val_len, &mut err); let mut val: *mut c_char = rocksdb_get_cf(db,
options,
handle,
key,
strlen(key),
&mut val_len,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckEqual(expected, val, val_len); CheckEqual(expected, val, val_len);
Free(&mut val); Free(&mut val);
} }
unsafe fn CheckIter(iter: *mut rocksdb_iterator_t, key: *const c_char, val: *const c_char) { unsafe fn CheckIter(iter: *mut rocksdb_iterator_t,
key: *const c_char,
val: *const c_char) {
let mut len: size_t = 0; let mut len: size_t = 0;
let mut str: *const c_char; let mut str: *const c_char;
str = rocksdb_iter_key(iter, &mut len); str = rocksdb_iter_key(iter, &mut len);
@ -131,35 +151,50 @@ unsafe fn CheckIter(iter: *mut rocksdb_iterator_t, key: *const c_char, val: *con
} }
// Callback from rocksdb_writebatch_iterate() // Callback from rocksdb_writebatch_iterate()
unsafe extern "C" fn CheckPut(ptr: *mut c_void, k: *const c_char, klen: size_t, v: *const c_char, vlen: size_t) { unsafe extern "C" fn CheckPut(ptr: *mut c_void,
k: *const c_char,
klen: size_t,
v: *const c_char,
vlen: size_t) {
let mut state: *mut c_int = ptr as *mut c_int; let mut state: *mut c_int = ptr as *mut c_int;
CheckCondition!(*state < 2); CheckCondition!(*state < 2);
match *state { match *state {
0 => { 0 => {
CheckEqual(cstrp!("bar"), k, klen); CheckEqual(cstrp!("bar"), k, klen);
CheckEqual(cstrp!("b"), v, vlen); CheckEqual(cstrp!("b"), v, vlen);
}, }
1 => { 1 => {
CheckEqual(cstrp!("box"), k, klen); CheckEqual(cstrp!("box"), k, klen);
CheckEqual(cstrp!("c"), v, vlen); CheckEqual(cstrp!("c"), v, vlen);
}, }
_ => { }, _ => {}
} }
*state += 1; *state += 1;
} }
// Callback from rocksdb_writebatch_iterate() // Callback from rocksdb_writebatch_iterate()
unsafe extern "C" fn CheckDel(ptr: *mut c_void, k: *const c_char, klen: size_t) { unsafe extern "C" fn CheckDel(ptr: *mut c_void,
k: *const c_char,
klen: size_t) {
let mut state: *mut c_int = ptr as *mut c_int; let mut state: *mut c_int = ptr as *mut c_int;
CheckCondition!(*state == 2); CheckCondition!(*state == 2);
CheckEqual(cstrp!("bar"), k, klen); CheckEqual(cstrp!("bar"), k, klen);
*state += 1; *state += 1;
} }
unsafe extern "C" fn CmpDestroy(arg: *mut c_void) { } unsafe extern "C" fn CmpDestroy(arg: *mut c_void) {}
unsafe extern "C" fn CmpCompare(arg: *mut c_void, a: *const c_char, alen: size_t, b: *const c_char, blen: size_t) -> c_int { unsafe extern "C" fn CmpCompare(arg: *mut c_void,
let n = if alen < blen { alen } else { blen }; a: *const c_char,
alen: size_t,
b: *const c_char,
blen: size_t)
-> c_int {
let n = if alen < blen {
alen
} else {
blen
};
let mut r = memcmp(a as *const c_void, b as *const c_void, n); let mut r = memcmp(a as *const c_void, b as *const c_void, n);
if r == 0 { if r == 0 {
if alen < blen { if alen < blen {
@ -179,38 +214,63 @@ unsafe extern "C" fn CmpName(arg: *mut c_void) -> *const c_char {
static mut fake_filter_result: c_uchar = 1; static mut fake_filter_result: c_uchar = 1;
unsafe extern "C" fn FilterDestroy(arg: *mut c_void) { } unsafe extern "C" fn FilterDestroy(arg: *mut c_void) {}
unsafe extern "C" fn FilterName(arg: *mut c_void) -> *const c_char { unsafe extern "C" fn FilterName(arg: *mut c_void) -> *const c_char {
cstrp!("TestFilter") cstrp!("TestFilter")
} }
unsafe extern "C" fn FilterCreate(arg: *mut c_void, key_array: *const *const c_char, key_length_array: *const size_t, num_keys: c_int, filter_length: *mut size_t) -> *mut c_char { unsafe extern "C" fn FilterCreate(arg: *mut c_void,
key_array: *const *const c_char,
key_length_array: *const size_t,
num_keys: c_int,
filter_length: *mut size_t)
-> *mut c_char {
*filter_length = 4; *filter_length = 4;
let result = malloc(4); let result = malloc(4);
memcpy(result, cstrp!("fake") as *const c_void, 4); memcpy(result, cstrp!("fake") as *const c_void, 4);
result as *mut c_char result as *mut c_char
} }
unsafe extern "C" fn FilterKeyMatch(arg: *mut c_void, key: *const c_char, length: size_t, filter: *const c_char, filter_length: size_t) -> c_uchar { unsafe extern "C" fn FilterKeyMatch(arg: *mut c_void,
key: *const c_char,
length: size_t,
filter: *const c_char,
filter_length: size_t)
-> c_uchar {
CheckCondition!(filter_length == 4); CheckCondition!(filter_length == 4);
CheckCondition!(memcmp(filter as *const c_void, cstrp!("fake") as *const c_void, filter_length) == 0); CheckCondition!(memcmp(filter as *const c_void,
cstrp!("fake") as *const c_void,
filter_length) == 0);
fake_filter_result fake_filter_result
} }
// Custom compaction filter // Custom compaction filter
unsafe extern "C" fn CFilterDestroy(arg: *mut c_void) { } unsafe extern "C" fn CFilterDestroy(arg: *mut c_void) {}
unsafe extern "C" fn CFilterName(arg: *mut c_void) -> *const c_char { unsafe extern "C" fn CFilterName(arg: *mut c_void) -> *const c_char {
cstrp!("foo") cstrp!("foo")
} }
unsafe extern "C" fn CFilterFilter(arg: *mut c_void, level: c_int, key: *const c_char, key_length: size_t, existing_value: *const c_char, value_length: size_t, new_value: *mut *mut c_char, new_value_length: *mut size_t, value_changed: *mut u8) -> c_uchar { unsafe extern "C" fn CFilterFilter(arg: *mut c_void,
level: c_int,
key: *const c_char,
key_length: size_t,
existing_value: *const c_char,
value_length: size_t,
new_value: *mut *mut c_char,
new_value_length: *mut size_t,
value_changed: *mut u8)
-> c_uchar {
if key_length == 3 { if key_length == 3 {
if memcmp(mem::transmute(key), mem::transmute(cstrp!("bar")), key_length) == 0 { if memcmp(mem::transmute(key),
mem::transmute(cstrp!("bar")),
key_length) == 0 {
return 1; return 1;
} else if memcmp(mem::transmute(key), mem::transmute(cstrp!("baz")), key_length) == 0 { } else if memcmp(mem::transmute(key),
mem::transmute(cstrp!("baz")),
key_length) == 0 {
*value_changed = 1; *value_changed = 1;
*new_value = cstrp!("newbazvalue") as *mut c_char; *new_value = cstrp!("newbazvalue") as *mut c_char;
*new_value_length = 11; *new_value_length = 11;
@ -220,27 +280,53 @@ unsafe extern "C" fn CFilterFilter(arg: *mut c_void, level: c_int, key: *const c
0 0
} }
unsafe extern "C" fn CFilterFactoryDestroy(arg: *mut c_void) { } unsafe extern "C" fn CFilterFactoryDestroy(arg: *mut c_void) {}
unsafe extern "C" fn CFilterFactoryName(arg: *mut c_void) -> *const c_char { unsafe extern "C" fn CFilterFactoryName(arg: *mut c_void) -> *const c_char {
cstrp!("foo") cstrp!("foo")
} }
unsafe extern "C" fn CFilterCreate(arg: *mut c_void, context: *mut rocksdb_compactionfiltercontext_t) -> *mut rocksdb_compactionfilter_t { unsafe extern "C" fn CFilterCreate(arg: *mut c_void, context: *mut rocksdb_compactionfiltercontext_t) -> *mut rocksdb_compactionfilter_t {
rocksdb_compactionfilter_create(ptr::null_mut(), Some(CFilterDestroy), Some(CFilterFilter), Some(CFilterName)) rocksdb_compactionfilter_create(ptr::null_mut(),
Some(CFilterDestroy),
Some(CFilterFilter),
Some(CFilterName))
} }
unsafe fn CheckCompaction(dbname: *const c_char, db: *mut rocksdb_t, options: *const rocksdb_options_t, roptions: *mut rocksdb_readoptions_t, woptions: *mut rocksdb_writeoptions_t) -> *mut rocksdb_t { unsafe fn CheckCompaction(dbname: *const c_char,
db: *mut rocksdb_t,
options: *const rocksdb_options_t,
roptions: *mut rocksdb_readoptions_t,
woptions: *mut rocksdb_writeoptions_t)
-> *mut rocksdb_t {
let mut err: *mut c_char = ptr::null_mut(); let mut err: *mut c_char = ptr::null_mut();
let db = rocksdb_open(options, dbname, &mut err); let db = rocksdb_open(options, dbname, &mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo"), 3, cstrp!("foovalue"), 8, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo"),
3,
cstrp!("foovalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("foo"), cstrp!("foovalue")); CheckGet(db, roptions, cstrp!("foo"), cstrp!("foovalue"));
rocksdb_put(db, woptions, cstrp!("bar"), 3, cstrp!("barvalue"), 8, &mut err); rocksdb_put(db,
woptions,
cstrp!("bar"),
3,
cstrp!("barvalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("bar"), cstrp!("barvalue")); CheckGet(db, roptions, cstrp!("bar"), cstrp!("barvalue"));
rocksdb_put(db, woptions, cstrp!("baz"), 3, cstrp!("bazvalue"), 8, &mut err); rocksdb_put(db,
woptions,
cstrp!("baz"),
3,
cstrp!("bazvalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("baz"), cstrp!("bazvalue")); CheckGet(db, roptions, cstrp!("baz"), cstrp!("bazvalue"));
@ -255,13 +341,23 @@ unsafe fn CheckCompaction(dbname: *const c_char, db: *mut rocksdb_t, options: *c
// Custom merge operator // Custom merge operator
unsafe extern "C" fn MergeOperatorDestroy(arg: *mut c_void) { } unsafe extern "C" fn MergeOperatorDestroy(arg: *mut c_void) {}
unsafe extern "C" fn MergeOperatorName(arg: *mut c_void) -> *const c_char { unsafe extern "C" fn MergeOperatorName(arg: *mut c_void) -> *const c_char {
cstrp!("foo") cstrp!("foo")
} }
unsafe extern "C" fn MergeOperatorFullMerge(arg: *mut c_void, key: *const c_char, key_length: size_t, existing_value: *const c_char, existing_value_length: size_t, operands_list: *const *const c_char, operands_list_length: *const size_t, num_operands: c_int, success: *mut u8, new_value_length: *mut size_t) -> *mut c_char { unsafe extern "C" fn MergeOperatorFullMerge(arg: *mut c_void,
key: *const c_char,
key_length: size_t,
existing_value: *const c_char,
existing_value_length: size_t,
operands_list: *const *const c_char,
operands_list_length: *const size_t,
num_operands: c_int,
success: *mut u8,
new_value_length: *mut size_t)
-> *mut c_char {
*new_value_length = 4; *new_value_length = 4;
*success = 1; *success = 1;
let result: *mut c_char = malloc(4) as *mut _; let result: *mut c_char = malloc(4) as *mut _;
@ -308,7 +404,10 @@ fn ffi() {
let dbbackupname = dbbackupname.as_ptr(); let dbbackupname = dbbackupname.as_ptr();
StartPhase("create_objects"); StartPhase("create_objects");
cmp = rocksdb_comparator_create(ptr::null_mut(), Some(CmpDestroy), Some(CmpCompare), Some(CmpName)); cmp = rocksdb_comparator_create(ptr::null_mut(),
Some(CmpDestroy),
Some(CmpCompare),
Some(CmpName));
env = rocksdb_create_default_env(); env = rocksdb_create_default_env();
cache = rocksdb_cache_create_lru(100000); cache = rocksdb_cache_create_lru(100000);
@ -360,7 +459,13 @@ fn ffi() {
CheckGet(db, roptions, cstrp!("foo") as *const _, ptr::null()); CheckGet(db, roptions, cstrp!("foo") as *const _, ptr::null());
StartPhase("put"); StartPhase("put");
rocksdb_put(db, woptions, cstrp!("foo"), 3, cstrp!("hello"), 5, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo"),
3,
cstrp!("hello"),
5,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("foo"), cstrp!("hello")); CheckGet(db, roptions, cstrp!("foo"), cstrp!("hello"));
@ -369,27 +474,34 @@ fn ffi() {
rocksdb_destroy_db(options, dbbackupname, &mut err); rocksdb_destroy_db(options, dbbackupname, &mut err);
CheckNoError!(err); CheckNoError!(err);
let be = rocksdb_backup_engine_open(options, dbbackupname, &mut err); let be =
rocksdb_backup_engine_open(options, dbbackupname, &mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_backup_engine_create_new_backup(be, db, &mut err); rocksdb_backup_engine_create_new_backup(be, db, &mut err);
CheckNoError!(err); CheckNoError!(err);
// need a change to trigger a new backup // need a change to trigger a new backup
rocksdb_delete(db, woptions, cstrp!("does-not-exist"), 14, &mut err); rocksdb_delete(db,
woptions,
cstrp!("does-not-exist"),
14,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_backup_engine_create_new_backup(be, db, &mut err); rocksdb_backup_engine_create_new_backup(be, db, &mut err);
CheckNoError!(err); CheckNoError!(err);
let bei: *const rocksdb_backup_engine_info_t = rocksdb_backup_engine_get_backup_info(be); let bei: *const rocksdb_backup_engine_info_t =
rocksdb_backup_engine_get_backup_info(be);
CheckCondition!(rocksdb_backup_engine_info_count(bei) > 1); CheckCondition!(rocksdb_backup_engine_info_count(bei) > 1);
rocksdb_backup_engine_info_destroy(bei); rocksdb_backup_engine_info_destroy(bei);
rocksdb_backup_engine_purge_old_backups(be, 1, &mut err); rocksdb_backup_engine_purge_old_backups(be, 1, &mut err);
CheckNoError!(err); CheckNoError!(err);
let bei: *const rocksdb_backup_engine_info_t = rocksdb_backup_engine_get_backup_info(be); let bei: *const rocksdb_backup_engine_info_t =
rocksdb_backup_engine_get_backup_info(be);
CheckCondition!(rocksdb_backup_engine_info_count(bei) == 1); CheckCondition!(rocksdb_backup_engine_info_count(bei) == 1);
rocksdb_backup_engine_info_destroy(bei); rocksdb_backup_engine_info_destroy(bei);
@ -439,7 +551,10 @@ fn ffi() {
CheckGet(db, roptions, cstrp!("bar"), ptr::null()); CheckGet(db, roptions, cstrp!("bar"), ptr::null());
CheckGet(db, roptions, cstrp!("box"), cstrp!("c")); CheckGet(db, roptions, cstrp!("box"), cstrp!("c"));
let mut pos: c_int = 0; let mut pos: c_int = 0;
rocksdb_writebatch_iterate(wb, mem::transmute(&mut pos), Some(CheckPut), Some(CheckDel)); rocksdb_writebatch_iterate(wb,
mem::transmute(&mut pos),
Some(CheckPut),
Some(CheckDel));
CheckCondition!(pos == 3); CheckCondition!(pos == 3);
rocksdb_writebatch_destroy(wb); rocksdb_writebatch_destroy(wb);
} }
@ -449,9 +564,16 @@ fn ffi() {
let wb = rocksdb_writebatch_create(); let wb = rocksdb_writebatch_create();
let k_list: [*const c_char; 2] = [cstrp!("z"), cstrp!("ap")]; let k_list: [*const c_char; 2] = [cstrp!("z"), cstrp!("ap")];
let k_sizes: [size_t; 2] = [1, 2]; let k_sizes: [size_t; 2] = [1, 2];
let v_list: [*const c_char; 3] = [cstrp!("x"), cstrp!("y"), cstrp!("z")]; let v_list: [*const c_char; 3] =
[cstrp!("x"), cstrp!("y"), cstrp!("z")];
let v_sizes: [size_t; 3] = [1, 1, 1]; let v_sizes: [size_t; 3] = [1, 1, 1];
rocksdb_writebatch_putv(wb, k_list.len() as c_int, k_list.as_ptr(), k_sizes.as_ptr(), v_list.len() as c_int, v_list.as_ptr(), v_sizes.as_ptr()); rocksdb_writebatch_putv(wb,
k_list.len() as c_int,
k_list.as_ptr(),
k_sizes.as_ptr(),
v_list.len() as c_int,
v_list.as_ptr(),
v_sizes.as_ptr());
rocksdb_write(db, woptions, wb, &mut err); rocksdb_write(db, woptions, wb, &mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("zap"), cstrp!("xyz")); CheckGet(db, roptions, cstrp!("zap"), cstrp!("xyz"));
@ -469,9 +591,12 @@ fn ffi() {
rocksdb_writebatch_put(wb1, cstrp!("quux"), 4, cstrp!("e"), 1); rocksdb_writebatch_put(wb1, cstrp!("quux"), 4, cstrp!("e"), 1);
rocksdb_writebatch_delete(wb1, cstrp!("quux"), 4); rocksdb_writebatch_delete(wb1, cstrp!("quux"), 4);
let mut repsize1: size_t = 0; let mut repsize1: size_t = 0;
let mut rep = rocksdb_writebatch_data(wb1, &mut repsize1) as *const c_void; let mut rep =
let mut wb2 = rocksdb_writebatch_create_from(rep as *const c_char, repsize1); rocksdb_writebatch_data(wb1, &mut repsize1) as *const c_void;
CheckCondition!(rocksdb_writebatch_count(wb1) == rocksdb_writebatch_count(wb2)); let mut wb2 = rocksdb_writebatch_create_from(rep as *const c_char,
repsize1);
CheckCondition!(rocksdb_writebatch_count(wb1) ==
rocksdb_writebatch_count(wb2));
let mut repsize2: size_t = 0; let mut repsize2: size_t = 0;
CheckCondition!(memcmp(rep, rocksdb_writebatch_data(wb2, &mut repsize2) as *const c_void, repsize1) == 0); CheckCondition!(memcmp(rep, rocksdb_writebatch_data(wb2, &mut repsize2) as *const c_void, repsize1) == 0);
rocksdb_writebatch_destroy(wb1); rocksdb_writebatch_destroy(wb1);
@ -502,12 +627,22 @@ fn ffi() {
StartPhase("multiget"); StartPhase("multiget");
{ {
let keys: [*const c_char; 3] = [cstrp!("box"), cstrp!("foo"), cstrp!("notfound")]; let keys: [*const c_char; 3] =
[cstrp!("box"), cstrp!("foo"), cstrp!("notfound")];
let keys_sizes: [size_t; 3] = [3, 3, 8]; let keys_sizes: [size_t; 3] = [3, 3, 8];
let mut vals: [*mut c_char; 3] = [ptr::null_mut(), ptr::null_mut(), ptr::null_mut()]; let mut vals: [*mut c_char; 3] =
[ptr::null_mut(), ptr::null_mut(), ptr::null_mut()];
let mut vals_sizes: [size_t; 3] = [0, 0, 0]; let mut vals_sizes: [size_t; 3] = [0, 0, 0];
let mut errs: [*mut c_char; 3] = [ptr::null_mut(), ptr::null_mut(), ptr::null_mut()]; let mut errs: [*mut c_char; 3] =
rocksdb_multi_get(db, roptions, 3, keys.as_ptr(), keys_sizes.as_ptr(), vals.as_mut_ptr(), vals_sizes.as_mut_ptr(), errs.as_mut_ptr()); [ptr::null_mut(), ptr::null_mut(), ptr::null_mut()];
rocksdb_multi_get(db,
roptions,
3,
keys.as_ptr(),
keys_sizes.as_ptr(),
vals.as_mut_ptr(),
vals_sizes.as_mut_ptr(),
errs.as_mut_ptr());
for i in 0..3 { for i in 0..3 {
CheckEqual(ptr::null(), errs[i], 0); CheckEqual(ptr::null(), errs[i], 0);
@ -515,7 +650,7 @@ fn ffi() {
0 => CheckEqual(cstrp!("c"), vals[i], vals_sizes[i]), 0 => CheckEqual(cstrp!("c"), vals[i], vals_sizes[i]),
1 => CheckEqual(cstrp!("hello"), vals[i], vals_sizes[i]), 1 => CheckEqual(cstrp!("hello"), vals[i], vals_sizes[i]),
2 => CheckEqual(ptr::null(), vals[i], vals_sizes[i]), 2 => CheckEqual(ptr::null(), vals[i], vals_sizes[i]),
_ => { }, _ => {}
} }
Free(&mut vals[i]); Free(&mut vals[i]);
} }
@ -524,20 +659,34 @@ fn ffi() {
StartPhase("approximate_sizes"); StartPhase("approximate_sizes");
{ {
let mut sizes: [uint64_t; 2] = [0, 0]; let mut sizes: [uint64_t; 2] = [0, 0];
let start: [*const c_char; 2] = [cstrp!("a"), cstrp!("k00000000000000010000")]; let start: [*const c_char; 2] = [cstrp!("a"),
cstrp!("k00000000000000010000")];
let start_len: [size_t; 2] = [1, 21]; let start_len: [size_t; 2] = [1, 21];
let limit: [*const c_char; 2] = [cstrp!("k00000000000000010000"), cstrp!("z")]; let limit: [*const c_char; 2] = [cstrp!("k00000000000000010000"),
cstrp!("z")];
let limit_len: [size_t; 2] = [21, 1]; let limit_len: [size_t; 2] = [21, 1];
rocksdb_writeoptions_set_sync(woptions, 0); rocksdb_writeoptions_set_sync(woptions, 0);
for i in 0 .. 20000 { for i in 0..20000 {
let keybuf = CString::new(format!("k{:020}", i)).unwrap(); let keybuf = CString::new(format!("k{:020}", i)).unwrap();
let key = keybuf.to_bytes_with_nul(); let key = keybuf.to_bytes_with_nul();
let valbuf = CString::new(format!("v{:020}", i)).unwrap(); let valbuf = CString::new(format!("v{:020}", i)).unwrap();
let val = valbuf.to_bytes_with_nul(); let val = valbuf.to_bytes_with_nul();
rocksdb_put(db, woptions, key.as_ptr() as *const c_char, key.len() as size_t, val.as_ptr() as *const c_char, val.len() as size_t, &mut err); rocksdb_put(db,
woptions,
key.as_ptr() as *const c_char,
key.len() as size_t,
val.as_ptr() as *const c_char,
val.len() as size_t,
&mut err);
CheckNoError!(err); CheckNoError!(err);
} }
rocksdb_approximate_sizes(db, 2, start.as_ptr(), start_len.as_ptr(), limit.as_ptr(), limit_len.as_ptr(), sizes.as_mut_ptr()); rocksdb_approximate_sizes(db,
2,
start.as_ptr(),
start_len.as_ptr(),
limit.as_ptr(),
limit_len.as_ptr(),
sizes.as_mut_ptr());
CheckCondition!(sizes[0] > 0); CheckCondition!(sizes[0] > 0);
CheckCondition!(sizes[1] > 0); CheckCondition!(sizes[1] > 0);
} }
@ -584,26 +733,45 @@ fn ffi() {
} }
StartPhase("filter"); StartPhase("filter");
for run in 0 .. 2 { for run in 0..2 {
// First run uses custom filter, second run uses bloom filter // First run uses custom filter, second run uses bloom filter
CheckNoError!(err); CheckNoError!(err);
let mut policy: *mut rocksdb_filterpolicy_t = if run == 0 { let mut policy: *mut rocksdb_filterpolicy_t = if run == 0 {
rocksdb_filterpolicy_create(ptr::null_mut(), Some(FilterDestroy), Some(FilterCreate), Some(FilterKeyMatch), None, Some(FilterName)) rocksdb_filterpolicy_create(ptr::null_mut(),
Some(FilterDestroy),
Some(FilterCreate),
Some(FilterKeyMatch),
None,
Some(FilterName))
} else { } else {
rocksdb_filterpolicy_create_bloom(10) rocksdb_filterpolicy_create_bloom(10)
}; };
rocksdb_block_based_options_set_filter_policy(table_options, policy); rocksdb_block_based_options_set_filter_policy(table_options,
policy);
// Create new database // Create new database
rocksdb_close(db); rocksdb_close(db);
rocksdb_destroy_db(options, dbname, &mut err); rocksdb_destroy_db(options, dbname, &mut err);
rocksdb_options_set_block_based_table_factory(options, table_options); rocksdb_options_set_block_based_table_factory(options,
table_options);
db = rocksdb_open(options, dbname, &mut err); db = rocksdb_open(options, dbname, &mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo"), 3, cstrp!("foovalue"), 8, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo"),
3,
cstrp!("foovalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("bar"), 3, cstrp!("barvalue"), 8, &mut err); rocksdb_put(db,
woptions,
cstrp!("bar"),
3,
cstrp!("barvalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_compact_range(db, ptr::null(), 0, ptr::null(), 0); rocksdb_compact_range(db, ptr::null(), 0, ptr::null(), 0);
@ -621,22 +789,32 @@ fn ffi() {
CheckGet(db, roptions, cstrp!("bar"), cstrp!("barvalue")); CheckGet(db, roptions, cstrp!("bar"), cstrp!("barvalue"));
} }
// Reset the policy // Reset the policy
rocksdb_block_based_options_set_filter_policy(table_options, ptr::null_mut()); rocksdb_block_based_options_set_filter_policy(table_options,
rocksdb_options_set_block_based_table_factory(options, table_options); ptr::null_mut());
rocksdb_options_set_block_based_table_factory(options,
table_options);
} }
StartPhase("compaction_filter"); StartPhase("compaction_filter");
{ {
let options_with_filter = rocksdb_options_create(); let options_with_filter = rocksdb_options_create();
rocksdb_options_set_create_if_missing(options_with_filter, 1); rocksdb_options_set_create_if_missing(options_with_filter, 1);
let cfilter = rocksdb_compactionfilter_create(ptr::null_mut(), Some(CFilterDestroy), Some(CFilterFilter), Some(CFilterName)); let cfilter = rocksdb_compactionfilter_create(ptr::null_mut(),
Some(CFilterDestroy),
Some(CFilterFilter),
Some(CFilterName));
// Create new database // Create new database
rocksdb_close(db); rocksdb_close(db);
rocksdb_destroy_db(options_with_filter, dbname, &mut err); rocksdb_destroy_db(options_with_filter, dbname, &mut err);
rocksdb_options_set_compaction_filter(options_with_filter, cfilter); rocksdb_options_set_compaction_filter(options_with_filter, cfilter);
db = CheckCompaction(dbname, db, options_with_filter, roptions, woptions); db = CheckCompaction(dbname,
db,
rocksdb_options_set_compaction_filter(options_with_filter, ptr::null_mut()); options_with_filter,
roptions,
woptions);
rocksdb_options_set_compaction_filter(options_with_filter,
ptr::null_mut());
rocksdb_compactionfilter_destroy(cfilter); rocksdb_compactionfilter_destroy(cfilter);
rocksdb_options_destroy(options_with_filter); rocksdb_options_destroy(options_with_filter);
} }
@ -644,13 +822,18 @@ fn ffi() {
StartPhase("compaction_filter_factory"); StartPhase("compaction_filter_factory");
{ {
let mut options_with_filter_factory = rocksdb_options_create(); let mut options_with_filter_factory = rocksdb_options_create();
rocksdb_options_set_create_if_missing(options_with_filter_factory, 1); rocksdb_options_set_create_if_missing(options_with_filter_factory,
1);
let mut factory = rocksdb_compactionfilterfactory_create(ptr::null_mut(), Some(CFilterFactoryDestroy), Some(CFilterCreate), Some(CFilterFactoryName)); let mut factory = rocksdb_compactionfilterfactory_create(ptr::null_mut(), Some(CFilterFactoryDestroy), Some(CFilterCreate), Some(CFilterFactoryName));
// Create new database // Create new database
rocksdb_close(db); rocksdb_close(db);
rocksdb_destroy_db(options_with_filter_factory, dbname, &mut err); rocksdb_destroy_db(options_with_filter_factory, dbname, &mut err);
rocksdb_options_set_compaction_filter_factory(options_with_filter_factory, factory); rocksdb_options_set_compaction_filter_factory(options_with_filter_factory, factory);
db = CheckCompaction(dbname, db, options_with_filter_factory, roptions, woptions); db = CheckCompaction(dbname,
db,
options_with_filter_factory,
roptions,
woptions);
rocksdb_options_set_compaction_filter_factory(options_with_filter_factory, ptr::null_mut()); rocksdb_options_set_compaction_filter_factory(options_with_filter_factory, ptr::null_mut());
rocksdb_options_destroy(options_with_filter_factory); rocksdb_options_destroy(options_with_filter_factory);
@ -658,22 +841,46 @@ fn ffi() {
StartPhase("merge_operator"); StartPhase("merge_operator");
{ {
let mut merge_operator = rocksdb_mergeoperator_create(ptr::null_mut(), Some(MergeOperatorDestroy), Some(MergeOperatorFullMerge), Some(MergeOperatorPartialMerge), None, Some(MergeOperatorName)); let mut merge_operator =
rocksdb_mergeoperator_create(ptr::null_mut(),
Some(MergeOperatorDestroy),
Some(MergeOperatorFullMerge),
Some(MergeOperatorPartialMerge),
None,
Some(MergeOperatorName));
// Create new database // Create new database
rocksdb_close(db); rocksdb_close(db);
rocksdb_destroy_db(options, dbname, &mut err); rocksdb_destroy_db(options, dbname, &mut err);
rocksdb_options_set_merge_operator(options, merge_operator); rocksdb_options_set_merge_operator(options, merge_operator);
db = rocksdb_open(options, dbname, &mut err); db = rocksdb_open(options, dbname, &mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo"), 3, cstrp!("foovalue"), 8, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo"),
3,
cstrp!("foovalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("foo"), cstrp!("foovalue")); CheckGet(db, roptions, cstrp!("foo"), cstrp!("foovalue"));
rocksdb_merge(db, woptions, cstrp!("foo"), 3, cstrp!("barvalue"), 8, &mut err); rocksdb_merge(db,
woptions,
cstrp!("foo"),
3,
cstrp!("barvalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("foo"), cstrp!("fake")); CheckGet(db, roptions, cstrp!("foo"), cstrp!("fake"));
// Merge of a non-existing value // Merge of a non-existing value
rocksdb_merge(db, woptions, cstrp!("bar"), 3, cstrp!("barvalue"), 8, &mut err); rocksdb_merge(db,
woptions,
cstrp!("bar"),
3,
cstrp!("barvalue"),
8,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGet(db, roptions, cstrp!("bar"), cstrp!("fake")); CheckGet(db, roptions, cstrp!("bar"), cstrp!("fake"));
} }
@ -688,14 +895,21 @@ fn ffi() {
rocksdb_options_set_create_if_missing(db_options, 1); rocksdb_options_set_create_if_missing(db_options, 1);
db = rocksdb_open(db_options, dbname, &mut err); db = rocksdb_open(db_options, dbname, &mut err);
CheckNoError!(err); CheckNoError!(err);
let mut cfh = rocksdb_create_column_family(db, db_options, cstrp!("cf1"), & mut err); let mut cfh = rocksdb_create_column_family(db,
db_options,
cstrp!("cf1"),
&mut err);
rocksdb_column_family_handle_destroy(cfh); rocksdb_column_family_handle_destroy(cfh);
CheckNoError!(err); CheckNoError!(err);
rocksdb_close(db); rocksdb_close(db);
let mut cflen: size_t = 0; let mut cflen: size_t = 0;
let column_fams_raw = rocksdb_list_column_families(db_options, dbname, &mut cflen, &mut err); let column_fams_raw = rocksdb_list_column_families(db_options,
let column_fams = slice::from_raw_parts(column_fams_raw, cflen as usize); dbname,
&mut cflen,
&mut err);
let column_fams = slice::from_raw_parts(column_fams_raw,
cflen as usize);
CheckEqual(cstrp!("default"), column_fams[0], 7); CheckEqual(cstrp!("default"), column_fams[0], 7);
CheckEqual(cstrp!("cf1"), column_fams[1], 3); CheckEqual(cstrp!("cf1"), column_fams[1], 3);
CheckCondition!(cflen == 2); CheckCondition!(cflen == 2);
@ -703,27 +917,67 @@ fn ffi() {
let mut cf_options = rocksdb_options_create(); let mut cf_options = rocksdb_options_create();
let cf_names: [*const c_char; 2] = [cstrp!("default"), cstrp!("cf1")]; let cf_names: [*const c_char; 2] = [cstrp!("default"),
let cf_opts: [*const rocksdb_options_t; 2] = [cf_options, cf_options]; cstrp!("cf1")];
let mut handles: [*mut rocksdb_column_family_handle_t; 2] = [ptr::null_mut(), ptr::null_mut()]; let cf_opts: [*const rocksdb_options_t; 2] = [cf_options,
db = rocksdb_open_column_families(db_options, dbname, 2, cf_names.as_ptr(), cf_opts.as_ptr(), handles.as_mut_ptr(), &mut err); cf_options];
let mut handles: [*mut rocksdb_column_family_handle_t; 2] =
[ptr::null_mut(), ptr::null_mut()];
db = rocksdb_open_column_families(db_options,
dbname,
2,
cf_names.as_ptr(),
cf_opts.as_ptr(),
handles.as_mut_ptr(),
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put_cf(db, woptions, handles[1], cstrp!("foo"), 3, cstrp!("hello"), 5, &mut err); rocksdb_put_cf(db,
woptions,
handles[1],
cstrp!("foo"),
3,
cstrp!("hello"),
5,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGetCF(db, roptions, handles[1], cstrp!("foo"), cstrp!("hello")); CheckGetCF(db,
roptions,
rocksdb_delete_cf(db, woptions, handles[1], cstrp!("foo"), 3, &mut err); handles[1],
cstrp!("foo"),
cstrp!("hello"));
rocksdb_delete_cf(db,
woptions,
handles[1],
cstrp!("foo"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
CheckGetCF(db, roptions, handles[1], cstrp!("foo"), ptr::null()); CheckGetCF(db, roptions, handles[1], cstrp!("foo"), ptr::null());
let mut wb = rocksdb_writebatch_create(); let mut wb = rocksdb_writebatch_create();
rocksdb_writebatch_put_cf(wb, handles[1], cstrp!("baz"), 3, cstrp!("a"), 1); rocksdb_writebatch_put_cf(wb,
handles[1],
cstrp!("baz"),
3,
cstrp!("a"),
1);
rocksdb_writebatch_clear(wb); rocksdb_writebatch_clear(wb);
rocksdb_writebatch_put_cf(wb, handles[1], cstrp!("bar"), 3, cstrp!("b"), 1); rocksdb_writebatch_put_cf(wb,
rocksdb_writebatch_put_cf(wb, handles[1], cstrp!("box"), 3, cstrp!("c"), 1); handles[1],
cstrp!("bar"),
3,
cstrp!("b"),
1);
rocksdb_writebatch_put_cf(wb,
handles[1],
cstrp!("box"),
3,
cstrp!("c"),
1);
rocksdb_writebatch_delete_cf(wb, handles[1], cstrp!("bar"), 3); rocksdb_writebatch_delete_cf(wb, handles[1], cstrp!("bar"), 3);
rocksdb_write(db, woptions, wb, &mut err); rocksdb_write(db, woptions, wb, &mut err);
CheckNoError!(err); CheckNoError!(err);
@ -732,21 +986,33 @@ fn ffi() {
CheckGetCF(db, roptions, handles[1], cstrp!("box"), cstrp!("c")); CheckGetCF(db, roptions, handles[1], cstrp!("box"), cstrp!("c"));
rocksdb_writebatch_destroy(wb); rocksdb_writebatch_destroy(wb);
let keys: [*const c_char; 3] = [cstrp!("box"), cstrp!("box"), cstrp!("barfooxx")]; let keys: [*const c_char; 3] =
let get_handles: [*const rocksdb_column_family_handle_t; 3] = [handles[0], handles[1], handles[1]]; [cstrp!("box"), cstrp!("box"), cstrp!("barfooxx")];
let get_handles: [*const rocksdb_column_family_handle_t; 3] =
[handles[0], handles[1], handles[1]];
let keys_sizes: [size_t; 3] = [3, 3, 8]; let keys_sizes: [size_t; 3] = [3, 3, 8];
let mut vals: [*mut c_char; 3] = [ptr::null_mut(), ptr::null_mut(), ptr::null_mut()]; let mut vals: [*mut c_char; 3] =
[ptr::null_mut(), ptr::null_mut(), ptr::null_mut()];
let mut vals_sizes: [size_t; 3] = [0, 0, 0]; let mut vals_sizes: [size_t; 3] = [0, 0, 0];
let mut errs: [*mut c_char; 3] = [ptr::null_mut(), ptr::null_mut(), ptr::null_mut()]; let mut errs: [*mut c_char; 3] =
rocksdb_multi_get_cf(db, roptions, get_handles.as_ptr(), 3, keys.as_ptr(), keys_sizes.as_ptr(), vals.as_mut_ptr(), vals_sizes.as_mut_ptr(), errs.as_mut_ptr()); [ptr::null_mut(), ptr::null_mut(), ptr::null_mut()];
rocksdb_multi_get_cf(db,
roptions,
get_handles.as_ptr(),
3,
keys.as_ptr(),
keys_sizes.as_ptr(),
vals.as_mut_ptr(),
vals_sizes.as_mut_ptr(),
errs.as_mut_ptr());
for i in 0 .. 3 { for i in 0..3 {
CheckEqual(ptr::null(), errs[i], 0); CheckEqual(ptr::null(), errs[i], 0);
match i { match i {
0 => CheckEqual(ptr::null(), vals[i], vals_sizes[i]), // wrong cf 0 => CheckEqual(ptr::null(), vals[i], vals_sizes[i]), // wrong cf
1 => CheckEqual(cstrp!("c"), vals[i], vals_sizes[i]), // bingo 1 => CheckEqual(cstrp!("c"), vals[i], vals_sizes[i]), // bingo
2 => CheckEqual(ptr::null(), vals[i], vals_sizes[i]), // normal not found 2 => CheckEqual(ptr::null(), vals[i], vals_sizes[i]), // normal not found
_ => { }, _ => {}
} }
Free(&mut vals[i]); Free(&mut vals[i]);
} }
@ -767,8 +1033,14 @@ fn ffi() {
rocksdb_iter_destroy(iter); rocksdb_iter_destroy(iter);
let mut iters_cf_handles: [*mut rocksdb_column_family_handle_t; 2] = [handles[0], handles[1]]; let mut iters_cf_handles: [*mut rocksdb_column_family_handle_t; 2] = [handles[0], handles[1]];
let mut iters_handles: [*mut rocksdb_iterator_t; 2] = [ptr::null_mut(), ptr::null_mut()]; let mut iters_handles: [*mut rocksdb_iterator_t; 2] =
rocksdb_create_iterators(db, roptions, iters_cf_handles.as_mut_ptr(), iters_handles.as_mut_ptr(), 2, &mut err); [ptr::null_mut(), ptr::null_mut()];
rocksdb_create_iterators(db,
roptions,
iters_cf_handles.as_mut_ptr(),
iters_handles.as_mut_ptr(),
2,
&mut err);
CheckNoError!(err); CheckNoError!(err);
iter = iters_handles[0]; iter = iters_handles[0];
@ -814,17 +1086,53 @@ fn ffi() {
db = rocksdb_open(options, dbname, &mut err); db = rocksdb_open(options, dbname, &mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo1"), 4, cstrp!("foo"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo1"),
4,
cstrp!("foo"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo2"), 4, cstrp!("foo"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo2"),
4,
cstrp!("foo"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo3"), 4, cstrp!("foo"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo3"),
4,
cstrp!("foo"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("bar1"), 4, cstrp!("bar"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("bar1"),
4,
cstrp!("bar"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("bar2"), 4, cstrp!("bar"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("bar2"),
4,
cstrp!("bar"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("bar3"), 4, cstrp!("bar"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("bar3"),
4,
cstrp!("bar"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
let mut iter = rocksdb_create_iterator(db, roptions); let mut iter = rocksdb_create_iterator(db, roptions);
@ -854,7 +1162,8 @@ fn ffi() {
rocksdb_cuckoo_options_set_hash_ratio(cuckoo_options, 0.5); rocksdb_cuckoo_options_set_hash_ratio(cuckoo_options, 0.5);
rocksdb_cuckoo_options_set_max_search_depth(cuckoo_options, 200); rocksdb_cuckoo_options_set_max_search_depth(cuckoo_options, 200);
rocksdb_cuckoo_options_set_cuckoo_block_size(cuckoo_options, 10); rocksdb_cuckoo_options_set_cuckoo_block_size(cuckoo_options, 10);
rocksdb_cuckoo_options_set_identity_as_first_hash(cuckoo_options, 1); rocksdb_cuckoo_options_set_identity_as_first_hash(cuckoo_options,
1);
rocksdb_cuckoo_options_set_use_module_hash(cuckoo_options, 0); rocksdb_cuckoo_options_set_use_module_hash(cuckoo_options, 0);
rocksdb_options_set_cuckoo_table_factory(options, cuckoo_options); rocksdb_options_set_cuckoo_table_factory(options, cuckoo_options);
@ -877,16 +1186,36 @@ fn ffi() {
rocksdb_put(db, woptions, cstrp!("a"), 1, cstrp!("0"), 1, &mut err); rocksdb_put(db, woptions, cstrp!("a"), 1, cstrp!("0"), 1, &mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo"), 3, cstrp!("bar"), 3, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo"),
3,
cstrp!("bar"),
3,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("foo1"), 4, cstrp!("bar1"), 4, &mut err); rocksdb_put(db,
woptions,
cstrp!("foo1"),
4,
cstrp!("bar1"),
4,
&mut err);
CheckNoError!(err); CheckNoError!(err);
rocksdb_put(db, woptions, cstrp!("g1"), 2, cstrp!("0"), 1, &mut err); rocksdb_put(db,
woptions,
cstrp!("g1"),
2,
cstrp!("0"),
1,
&mut err);
CheckNoError!(err); CheckNoError!(err);
// testing basic case with no iterate_upper_bound and no prefix_extractor // testing basic case with no iterate_upper_bound and no prefix_extractor
{ {
rocksdb_readoptions_set_iterate_upper_bound(roptions, ptr::null(), 0); rocksdb_readoptions_set_iterate_upper_bound(roptions,
ptr::null(),
0);
let mut iter = rocksdb_create_iterator(db, roptions); let mut iter = rocksdb_create_iterator(db, roptions);
rocksdb_iter_seek(iter, cstrp!("foo"), 3); rocksdb_iter_seek(iter, cstrp!("foo"), 3);
@ -908,7 +1237,9 @@ fn ffi() {
// to make sure it stops at bound // to make sure it stops at bound
{ {
// iterate_upper_bound points beyond the last expected entry // iterate_upper_bound points beyond the last expected entry
rocksdb_readoptions_set_iterate_upper_bound(roptions, cstrp!("foo2"), 4); rocksdb_readoptions_set_iterate_upper_bound(roptions,
cstrp!("foo2"),
4);
let mut iter = rocksdb_create_iterator(db, roptions); let mut iter = rocksdb_create_iterator(db, roptions);

@ -1,3 +1,3 @@
reorder_imports = true reorder_imports = true
max_width = 80 max_width = 100
ideal_width = 80 ideal_width = 100

@ -34,7 +34,12 @@ pub unsafe extern "C" fn name_callback(raw_cb: *mut c_void) -> *const c_char {
ptr as *const c_char ptr as *const c_char
} }
pub unsafe extern "C" fn compare_callback(raw_cb: *mut c_void, a_raw: *const c_char, a_len: size_t, b_raw: *const c_char, b_len: size_t) -> c_int { pub unsafe extern "C" fn compare_callback(raw_cb: *mut c_void,
a_raw: *const c_char,
a_len: size_t,
b_raw: *const c_char,
b_len: size_t)
-> c_int {
let cb: &mut ComparatorCallback = &mut *(raw_cb as *mut ComparatorCallback); let cb: &mut ComparatorCallback = &mut *(raw_cb as *mut ComparatorCallback);
let a: &[u8] = slice::from_raw_parts(a_raw as *const u8, a_len as usize); let a: &[u8] = slice::from_raw_parts(a_raw as *const u8, a_len as usize);
let b: &[u8] = slice::from_raw_parts(b_raw as *const u8, b_len as usize); let b: &[u8] = slice::from_raw_parts(b_raw as *const u8, b_len as usize);

@ -14,7 +14,7 @@
// //
use libc::{self, c_char, c_void}; use libc::{self, c_char, c_void};
use std::ffi::{CStr}; use std::ffi::CStr;
use std::str; use std::str;
pub fn error_message(ptr: *const c_char) -> String { pub fn error_message(ptr: *const c_char) -> String {

@ -24,7 +24,8 @@ pub mod merge_operator;
mod rocksdb; mod rocksdb;
mod rocksdb_options; mod rocksdb_options;
pub use rocksdb::{DB, DBCompressionType, DBCompactionStyle, DBRecoveryMode, DBIterator, DBVector, Direction, Error, IteratorMode, Writable, WriteBatch, Snapshot, new_bloom_filter}; pub use rocksdb::{DB, DBCompactionStyle, DBCompressionType, DBIterator, DBRecoveryMode, DBVector,
Direction, Error, IteratorMode, Snapshot, Writable, WriteBatch, new_bloom_filter};
pub use merge_operator::MergeOperands; pub use merge_operator::MergeOperands;
pub struct BlockBasedOptions { pub struct BlockBasedOptions {

@ -36,7 +36,17 @@ pub unsafe extern "C" fn name_callback(raw_cb: *mut c_void) -> *const c_char {
cb.name.as_ptr() cb.name.as_ptr()
} }
pub unsafe extern "C" fn full_merge_callback(raw_cb: *mut c_void, raw_key: *const c_char, key_len: size_t, existing_value: *const c_char, existing_value_len: size_t, operands_list: *const *const c_char, operands_list_len: *const size_t, num_operands: c_int, success: *mut u8, new_value_length: *mut size_t) -> *mut c_char { pub unsafe extern "C" fn full_merge_callback(raw_cb: *mut c_void,
raw_key: *const c_char,
key_len: size_t,
existing_value: *const c_char,
existing_value_len: size_t,
operands_list: *const *const c_char,
operands_list_len: *const size_t,
num_operands: c_int,
success: *mut u8,
new_value_length: *mut size_t)
-> *mut c_char {
let cb = &mut *(raw_cb as *mut MergeOperatorCallback); let cb = &mut *(raw_cb as *mut MergeOperatorCallback);
let operands = &mut MergeOperands::new(operands_list, operands_list_len, num_operands); let operands = &mut MergeOperands::new(operands_list, operands_list_len, num_operands);
let key = slice::from_raw_parts(raw_key as *const u8, key_len as usize); let key = slice::from_raw_parts(raw_key as *const u8, key_len as usize);
@ -52,7 +62,15 @@ pub unsafe extern "C" fn full_merge_callback(raw_cb: *mut c_void, raw_key: *cons
buf as *mut c_char buf as *mut c_char
} }
pub unsafe extern "C" fn partial_merge_callback(raw_cb: *mut c_void, raw_key: *const c_char, key_len: size_t, operands_list: *const *const c_char, operands_list_len: *const size_t, num_operands: c_int, success: *mut u8, new_value_length: *mut size_t) -> *mut c_char { pub unsafe extern "C" fn partial_merge_callback(raw_cb: *mut c_void,
raw_key: *const c_char,
key_len: size_t,
operands_list: *const *const c_char,
operands_list_len: *const size_t,
num_operands: c_int,
success: *mut u8,
new_value_length: *mut size_t)
-> *mut c_char {
let cb = &mut *(raw_cb as *mut MergeOperatorCallback); let cb = &mut *(raw_cb as *mut MergeOperatorCallback);
let operands = &mut MergeOperands::new(operands_list, operands_list_len, num_operands); let operands = &mut MergeOperands::new(operands_list, operands_list_len, num_operands);
let key = slice::from_raw_parts(raw_key as *const u8, key_len as usize); let key = slice::from_raw_parts(raw_key as *const u8, key_len as usize);
@ -76,7 +94,10 @@ pub struct MergeOperands {
} }
impl MergeOperands { impl MergeOperands {
fn new(operands_list: *const *const c_char, operands_list_len: *const size_t, num_operands: c_int) -> MergeOperands { fn new(operands_list: *const *const c_char,
operands_list_len: *const size_t,
num_operands: c_int)
-> MergeOperands {
assert!(num_operands >= 0); assert!(num_operands >= 0);
MergeOperands { MergeOperands {
operands_list: operands_list, operands_list: operands_list,
@ -103,7 +124,8 @@ impl<'a> Iterator for &'a mut MergeOperands {
let len = *len_ptr as usize; let len = *len_ptr as usize;
let ptr = base + (spacing * self.cursor); let ptr = base + (spacing * self.cursor);
self.cursor += 1; self.cursor += 1;
Some(mem::transmute(slice::from_raw_parts(*(ptr as *const *const u8) as *const u8, len))) Some(mem::transmute(slice::from_raw_parts(*(ptr as *const *const u8) as *const u8,
len)))
} }
} }
} }
@ -116,7 +138,10 @@ impl<'a> Iterator for &'a mut MergeOperands {
#[cfg(test)] #[cfg(test)]
#[allow(unused_variables)] #[allow(unused_variables)]
fn test_provided_merge(new_key: &[u8], existing_val: Option<&[u8]>, operands: &mut MergeOperands) -> Vec<u8> { fn test_provided_merge(new_key: &[u8],
existing_val: Option<&[u8]>,
operands: &mut MergeOperands)
-> Vec<u8> {
let nops = operands.size_hint().0; let nops = operands.size_hint().0;
let mut result: Vec<u8> = Vec::with_capacity(nops); let mut result: Vec<u8> = Vec::with_capacity(nops);
if let Some(v) = existing_val { if let Some(v) = existing_val {
@ -134,7 +159,7 @@ fn test_provided_merge(new_key: &[u8], existing_val: Option<&[u8]>, operands: &m
#[test] #[test]
fn mergetest() { fn mergetest() {
use {Options}; use Options;
use rocksdb::{DB, Writable}; use rocksdb::{DB, Writable};
let path = "_rust_rocksdb_mergetest"; let path = "_rust_rocksdb_mergetest";

@ -14,7 +14,7 @@
// //
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ffi::{CString}; use std::ffi::CString;
use std::fmt; use std::fmt;
use std::fs; use std::fs;
use std::ops::Deref; use std::ops::Deref;
@ -23,7 +23,7 @@ use std::ptr;
use std::slice; use std::slice;
use std::str; use std::str;
use libc::{self, c_char, c_uchar, c_int, c_void, size_t}; use libc::{self, c_char, c_int, c_uchar, c_void, size_t};
use {Options, WriteOptions}; use {Options, WriteOptions};
use ffi; use ffi;
@ -42,8 +42,8 @@ pub struct DB {
path: PathBuf, path: PathBuf,
} }
unsafe impl Send for DB { } unsafe impl Send for DB {}
unsafe impl Sync for DB { } unsafe impl Sync for DB {}
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum DBCompressionType { pub enum DBCompressionType {
@ -141,9 +141,11 @@ impl Iterator for DBIterator {
let key_len_ptr: *mut size_t = &mut key_len; let key_len_ptr: *mut size_t = &mut key_len;
let mut val_len: size_t = 0; let mut val_len: size_t = 0;
let val_len_ptr: *mut size_t = &mut val_len; let val_len_ptr: *mut size_t = &mut val_len;
let key_ptr = unsafe { ffi::rocksdb_iter_key(native_iter, key_len_ptr) as *const c_uchar }; let key_ptr =
unsafe { ffi::rocksdb_iter_key(native_iter, key_len_ptr) as *const c_uchar };
let key = unsafe { slice::from_raw_parts(key_ptr, key_len as usize) }; let key = unsafe { slice::from_raw_parts(key_ptr, key_len as usize) };
let val_ptr = unsafe { ffi::rocksdb_iter_value(native_iter, val_len_ptr) as *const c_uchar }; let val_ptr =
unsafe { ffi::rocksdb_iter_value(native_iter, val_len_ptr) as *const c_uchar };
let val = unsafe { slice::from_raw_parts(val_ptr, val_len as usize) }; let val = unsafe { slice::from_raw_parts(val_ptr, val_len as usize) };
Some((key.to_vec().into_boxed_slice(), val.to_vec().into_boxed_slice())) Some((key.to_vec().into_boxed_slice(), val.to_vec().into_boxed_slice()))
@ -186,7 +188,9 @@ impl DBIterator {
self.direction = Direction::Reverse; self.direction = Direction::Reverse;
} }
IteratorMode::From(key, dir) => { IteratorMode::From(key, dir) => {
ffi::rocksdb_iter_seek(self.inner, key.as_ptr() as *const c_char, key.len() as size_t); ffi::rocksdb_iter_seek(self.inner,
key.as_ptr() as *const c_char,
key.len() as size_t);
self.direction = dir; self.direction = dir;
} }
}; };
@ -198,7 +202,11 @@ impl DBIterator {
unsafe { ffi::rocksdb_iter_valid(self.inner) != 0 } unsafe { ffi::rocksdb_iter_valid(self.inner) != 0 }
} }
fn new_cf(db: &DB, cf_handle: *mut ffi::rocksdb_column_family_handle_t, readopts: &ReadOptions, mode: IteratorMode) -> Result<DBIterator, Error> { fn new_cf(db: &DB,
cf_handle: *mut ffi::rocksdb_column_family_handle_t,
readopts: &ReadOptions,
mode: IteratorMode)
-> Result<DBIterator, Error> {
unsafe { unsafe {
let iterator = ffi::rocksdb_create_iterator_cf(db.inner, readopts.inner, cf_handle); let iterator = ffi::rocksdb_create_iterator_cf(db.inner, readopts.inner, cf_handle);
@ -236,7 +244,10 @@ impl<'a> Snapshot<'a> {
DBIterator::new(self.db, &readopts, mode) DBIterator::new(self.db, &readopts, mode)
} }
pub fn iterator_cf(&self, cf_handle: *mut ffi::rocksdb_column_family_handle_t, mode: IteratorMode) -> Result<DBIterator, Error> { pub fn iterator_cf(&self,
cf_handle: *mut ffi::rocksdb_column_family_handle_t,
mode: IteratorMode)
-> Result<DBIterator, Error> {
let mut readopts = ReadOptions::default(); let mut readopts = ReadOptions::default();
readopts.set_snapshot(self); readopts.set_snapshot(self);
DBIterator::new_cf(self.db, cf_handle, &readopts, mode) DBIterator::new_cf(self.db, cf_handle, &readopts, mode)
@ -248,7 +259,10 @@ impl<'a> Snapshot<'a> {
self.db.get_opt(key, &readopts) self.db.get_opt(key, &readopts)
} }
pub fn get_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8]) -> Result<Option<DBVector>, Error> { pub fn get_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8])
-> Result<Option<DBVector>, Error> {
let mut readopts = ReadOptions::default(); let mut readopts = ReadOptions::default();
readopts.set_snapshot(self); readopts.set_snapshot(self);
self.db.get_cf_opt(cf, key, &readopts) self.db.get_cf_opt(cf, key, &readopts)
@ -266,11 +280,22 @@ impl<'a> Drop for Snapshot<'a> {
// This is for the DB 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<(), Error>; fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error>;
fn put_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8]) -> Result<(), Error>; fn put_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8])
-> Result<(), Error>;
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error>; fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error>;
fn merge_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8]) -> Result<(), Error>; fn merge_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8])
-> Result<(), Error>;
fn delete(&self, key: &[u8]) -> Result<(), Error>; fn delete(&self, key: &[u8]) -> Result<(), Error>;
fn delete_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8]) -> Result<(), Error>; fn delete_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8])
-> Result<(), Error>;
} }
impl DB { impl DB {
@ -299,13 +324,17 @@ impl DB {
let cpath = match CString::new(path.to_string_lossy().as_bytes()) { let cpath = match CString::new(path.to_string_lossy().as_bytes()) {
Ok(c) => c, Ok(c) => c,
Err(_) => { Err(_) => {
return Err(Error::new("Failed to convert path to CString when opening rocksdb".to_owned())) return Err(Error::new("Failed to convert path to CString \
when opening rocksdb"
.to_owned()))
} }
}; };
let cpath_ptr = cpath.as_ptr(); let cpath_ptr = cpath.as_ptr();
if let Err(e) = fs::create_dir_all(&path) { if let Err(e) = fs::create_dir_all(&path) {
return Err(Error::new(format!("Failed to create rocksdb directory: {:?}", e))); return Err(Error::new(format!("Failed to create rocksdb \
directory: {:?}",
e)));
} }
let db: *mut ffi::rocksdb_t; let db: *mut ffi::rocksdb_t;
@ -322,8 +351,11 @@ impl DB {
cfs_v.push("default"); cfs_v.push("default");
} }
// We need to store our CStrings in an intermediate vector so that their pointers remain valid. // We need to store our CStrings in an intermediate vector
let c_cfs: Vec<CString> = cfs_v.iter().map(|cf| CString::new(cf.as_bytes()).unwrap()).collect(); // so that their pointers remain valid.
let c_cfs: Vec<CString> = cfs_v.iter()
.map(|cf| CString::new(cf.as_bytes()).unwrap())
.collect();
let cfnames: Vec<_> = c_cfs.iter().map(|cf| cf.as_ptr()).collect(); let cfnames: Vec<_> = c_cfs.iter().map(|cf| cf.as_ptr()).collect();
@ -331,15 +363,24 @@ impl DB {
let mut cfhandles: Vec<_> = cfs_v.iter().map(|_| ptr::null_mut()).collect(); let mut cfhandles: Vec<_> = cfs_v.iter().map(|_| ptr::null_mut()).collect();
// TODO(tyler) allow options to be passed in. // TODO(tyler) allow options to be passed in.
let cfopts: Vec<_> = cfs_v.iter().map(|_| unsafe { ffi::rocksdb_options_create() as *const _ }).collect(); let cfopts: Vec<_> = cfs_v.iter()
.map(|_| unsafe { ffi::rocksdb_options_create() as *const _ })
.collect();
unsafe { unsafe {
db = ffi_try!(ffi::rocksdb_open_column_families(opts.inner, cpath_ptr as *const _, cfs_v.len() as c_int, cfnames.as_ptr() as *const _, cfopts.as_ptr(), cfhandles.as_mut_ptr())); db = ffi_try!(ffi::rocksdb_open_column_families(opts.inner,
cpath_ptr as *const _,
cfs_v.len() as c_int,
cfnames.as_ptr() as *const _,
cfopts.as_ptr(),
cfhandles.as_mut_ptr()));
} }
for handle in &cfhandles { for handle in &cfhandles {
if handle.is_null() { if handle.is_null() {
return Err(Error::new("Received null column family handle from DB.".to_owned())); return Err(Error::new("Received null column family \
handle from DB."
.to_owned()));
} }
} }
@ -398,12 +439,21 @@ impl DB {
pub fn get_opt(&self, key: &[u8], readopts: &ReadOptions) -> Result<Option<DBVector>, Error> { pub fn get_opt(&self, key: &[u8], readopts: &ReadOptions) -> Result<Option<DBVector>, Error> {
if readopts.inner.is_null() { if readopts.inner.is_null() {
return Err(Error::new("Unable to create rocksdb read options. This is a fairly trivial call, and its failure may be indicative of a mis-compiled or mis-loaded rocksdb library.".to_owned())); return Err(Error::new("Unable to create rocksdb read options. \
This is a fairly trivial call, and its \
failure may be indicative of a \
mis-compiled or mis-loaded rocksdb \
library."
.to_owned()));
} }
unsafe { unsafe {
let mut val_len: size_t = 0; let mut val_len: size_t = 0;
let val = ffi_try!(ffi::rocksdb_get(self.inner, readopts.inner, key.as_ptr() as *const c_char, key.len() as size_t, &mut val_len)) as *mut u8; let val = ffi_try!(ffi::rocksdb_get(self.inner,
readopts.inner,
key.as_ptr() as *const c_char,
key.len() as size_t,
&mut val_len)) as *mut u8;
if val.is_null() { if val.is_null() {
Ok(None) Ok(None)
} else { } else {
@ -417,14 +467,28 @@ impl DB {
self.get_opt(key, &ReadOptions::default()) self.get_opt(key, &ReadOptions::default())
} }
pub fn get_cf_opt(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], readopts: &ReadOptions) -> Result<Option<DBVector>, Error> { pub fn get_cf_opt(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
readopts: &ReadOptions)
-> Result<Option<DBVector>, Error> {
if readopts.inner.is_null() { if readopts.inner.is_null() {
return Err(Error::new("Unable to create rocksdb read options. This is a fairly trivial call, and its failure may be indicative of a mis-compiled or mis-loaded rocksdb library.".to_owned())); return Err(Error::new("Unable to create rocksdb read options. \
This is a fairly trivial call, and its \
failure may be indicative of a \
mis-compiled or mis-loaded rocksdb \
library."
.to_owned()));
} }
unsafe { unsafe {
let mut val_len: size_t = 0; let mut val_len: size_t = 0;
let val = ffi_try!(ffi::rocksdb_get_cf(self.inner, readopts.inner, cf, key.as_ptr() as *const c_char, key.len() as size_t, &mut val_len)) as *mut u8; let val = ffi_try!(ffi::rocksdb_get_cf(self.inner,
readopts.inner,
cf,
key.as_ptr() as *const c_char,
key.len() as size_t,
&mut val_len)) as *mut u8;
if val.is_null() { if val.is_null() {
Ok(None) Ok(None)
} else { } else {
@ -433,19 +497,28 @@ impl DB {
} }
} }
pub fn get_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8]) -> Result<Option<DBVector>, Error> { pub fn get_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8])
-> Result<Option<DBVector>, Error> {
self.get_cf_opt(cf, key, &ReadOptions::default()) self.get_cf_opt(cf, key, &ReadOptions::default())
} }
pub fn create_cf(&mut self, name: &str, opts: &Options) -> Result<*mut ffi::rocksdb_column_family_handle_t, Error> { pub fn create_cf(&mut self,
name: &str,
opts: &Options)
-> Result<*mut ffi::rocksdb_column_family_handle_t, Error> {
let cname = match CString::new(name.as_bytes()) { let cname = match CString::new(name.as_bytes()) {
Ok(c) => c, Ok(c) => c,
Err(_) => { Err(_) => {
return Err(Error::new("Failed to convert path to CString when opening rocksdb".to_owned())) return Err(Error::new("Failed to convert path to CString \
when opening rocksdb"
.to_owned()))
} }
}; };
let cf_handler = unsafe { let cf_handler = unsafe {
let cf_handler = ffi_try!(ffi::rocksdb_create_column_family(self.inner, opts.inner, cname.as_ptr())); let cf_handler =
ffi_try!(ffi::rocksdb_create_column_family(self.inner, opts.inner, cname.as_ptr()));
self.cfs.insert(name.to_string(), cf_handler); self.cfs.insert(name.to_string(), cf_handler);
cf_handler cf_handler
}; };
@ -473,7 +546,10 @@ impl DB {
DBIterator::new(self, &opts, mode) DBIterator::new(self, &opts, mode)
} }
pub fn iterator_cf(&self, cf_handle: *mut ffi::rocksdb_column_family_handle_t, mode: IteratorMode) -> Result<DBIterator, Error> { pub fn iterator_cf(&self,
cf_handle: *mut ffi::rocksdb_column_family_handle_t,
mode: IteratorMode)
-> Result<DBIterator, Error> {
let opts = ReadOptions::default(); let opts = ReadOptions::default();
DBIterator::new_cf(self, cf_handle, &opts, mode) DBIterator::new_cf(self, cf_handle, &opts, mode)
} }
@ -484,42 +560,89 @@ impl DB {
pub fn put_opt(&self, key: &[u8], value: &[u8], writeopts: &WriteOptions) -> Result<(), Error> { pub fn put_opt(&self, key: &[u8], value: &[u8], writeopts: &WriteOptions) -> Result<(), Error> {
unsafe { unsafe {
ffi_try!(ffi::rocksdb_put(self.inner, writeopts.inner, key.as_ptr() as *const c_char, key.len() as size_t, value.as_ptr() as *const c_char, value.len() as size_t)); ffi_try!(ffi::rocksdb_put(self.inner,
writeopts.inner,
key.as_ptr() as *const c_char,
key.len() as size_t,
value.as_ptr() as *const c_char,
value.len() as size_t));
Ok(()) Ok(())
} }
} }
pub fn put_cf_opt(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8], writeopts: &WriteOptions) -> Result<(), Error> { pub fn put_cf_opt(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8],
writeopts: &WriteOptions)
-> Result<(), Error> {
unsafe { unsafe {
ffi_try!(ffi::rocksdb_put_cf(self.inner, writeopts.inner, cf, key.as_ptr() as *const c_char, key.len() as size_t, value.as_ptr() as *const c_char, value.len() as size_t)); ffi_try!(ffi::rocksdb_put_cf(self.inner,
writeopts.inner,
cf,
key.as_ptr() as *const c_char,
key.len() as size_t,
value.as_ptr() as *const c_char,
value.len() as size_t));
Ok(()) Ok(())
} }
} }
pub fn merge_opt(&self, key: &[u8], value: &[u8], writeopts: &WriteOptions) -> Result<(), Error> { pub fn merge_opt(&self,
key: &[u8],
value: &[u8],
writeopts: &WriteOptions)
-> Result<(), Error> {
unsafe { unsafe {
ffi_try!(ffi::rocksdb_merge(self.inner, writeopts.inner, key.as_ptr() as *const c_char, key.len() as size_t, value.as_ptr() as *const c_char, value.len() as size_t)); ffi_try!(ffi::rocksdb_merge(self.inner,
writeopts.inner,
key.as_ptr() as *const c_char,
key.len() as size_t,
value.as_ptr() as *const c_char,
value.len() as size_t));
Ok(()) Ok(())
} }
} }
fn merge_cf_opt(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8], writeopts: &WriteOptions) -> Result<(), Error> { fn merge_cf_opt(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8],
writeopts: &WriteOptions)
-> Result<(), Error> {
unsafe { unsafe {
ffi_try!(ffi::rocksdb_merge_cf(self.inner, writeopts.inner, cf, key.as_ptr() as *const i8, key.len() as size_t, value.as_ptr() as *const i8, value.len() as size_t)); ffi_try!(ffi::rocksdb_merge_cf(self.inner,
writeopts.inner,
cf,
key.as_ptr() as *const i8,
key.len() as size_t,
value.as_ptr() as *const i8,
value.len() as size_t));
Ok(()) Ok(())
} }
} }
fn delete_opt(&self, key: &[u8], writeopts: &WriteOptions) -> Result<(), Error> { fn delete_opt(&self, key: &[u8], writeopts: &WriteOptions) -> Result<(), Error> {
unsafe { unsafe {
ffi_try!(ffi::rocksdb_delete(self.inner, writeopts.inner, key.as_ptr() as *const c_char, key.len() as size_t)); ffi_try!(ffi::rocksdb_delete(self.inner,
writeopts.inner,
key.as_ptr() as *const c_char,
key.len() as size_t));
Ok(()) Ok(())
} }
} }
fn delete_cf_opt(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], writeopts: &WriteOptions) -> Result<(), Error> { fn delete_cf_opt(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
writeopts: &WriteOptions)
-> Result<(), Error> {
unsafe { unsafe {
ffi_try!(ffi::rocksdb_delete_cf(self.inner, writeopts.inner, cf, key.as_ptr() as *const c_char, key.len() as size_t)); ffi_try!(ffi::rocksdb_delete_cf(self.inner,
writeopts.inner,
cf,
key.as_ptr() as *const c_char,
key.len() as size_t));
Ok(()) Ok(())
} }
} }
@ -530,7 +653,11 @@ impl Writable for DB {
self.put_opt(key, value, &WriteOptions::default()) self.put_opt(key, value, &WriteOptions::default())
} }
fn put_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8]) -> Result<(), Error> { fn put_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8])
-> Result<(), Error> {
self.put_cf_opt(cf, key, value, &WriteOptions::default()) self.put_cf_opt(cf, key, value, &WriteOptions::default())
} }
@ -538,7 +665,11 @@ impl Writable for DB {
self.merge_opt(key, value, &WriteOptions::default()) self.merge_opt(key, value, &WriteOptions::default())
} }
fn merge_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8]) -> Result<(), Error> { fn merge_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8])
-> Result<(), Error> {
self.merge_cf_opt(cf, key, value, &WriteOptions::default()) self.merge_cf_opt(cf, key, value, &WriteOptions::default())
} }
@ -546,7 +677,10 @@ impl Writable for DB {
self.delete_opt(key, &WriteOptions::default()) self.delete_opt(key, &WriteOptions::default())
} }
fn delete_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8]) -> Result<(), Error> { fn delete_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8])
-> Result<(), Error> {
self.delete_cf_opt(cf, key, &WriteOptions::default()) self.delete_cf_opt(cf, key, &WriteOptions::default())
} }
} }
@ -563,9 +697,7 @@ impl WriteBatch {
impl Default for WriteBatch { impl Default for WriteBatch {
fn default() -> WriteBatch { fn default() -> WriteBatch {
WriteBatch { WriteBatch { inner: unsafe { ffi::rocksdb_writebatch_create() } }
inner: unsafe { ffi::rocksdb_writebatch_create() },
}
} }
} }
@ -596,28 +728,54 @@ impl Writable for WriteBatch {
/// Insert a value into the database under the given key. /// Insert a value into the database under the given key.
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
unsafe { unsafe {
ffi::rocksdb_writebatch_put(self.inner, key.as_ptr() as *const i8, key.len() as size_t, value.as_ptr() as *const i8, value.len() as size_t); ffi::rocksdb_writebatch_put(self.inner,
key.as_ptr() as *const i8,
key.len() as size_t,
value.as_ptr() as *const i8,
value.len() as size_t);
Ok(()) Ok(())
} }
} }
fn put_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8]) -> Result<(), Error> { fn put_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8])
-> Result<(), Error> {
unsafe { unsafe {
ffi::rocksdb_writebatch_put_cf(self.inner, cf, key.as_ptr() as *const i8, key.len() as size_t, value.as_ptr() as *const i8, value.len() as size_t); ffi::rocksdb_writebatch_put_cf(self.inner,
cf,
key.as_ptr() as *const i8,
key.len() as size_t,
value.as_ptr() as *const i8,
value.len() as size_t);
Ok(()) Ok(())
} }
} }
fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { fn merge(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
unsafe { unsafe {
ffi::rocksdb_writebatch_merge(self.inner, key.as_ptr() as *const i8, key.len() as size_t, value.as_ptr() as *const i8, value.len() as size_t); ffi::rocksdb_writebatch_merge(self.inner,
key.as_ptr() as *const i8,
key.len() as size_t,
value.as_ptr() as *const i8,
value.len() as size_t);
Ok(()) Ok(())
} }
} }
fn merge_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8], value: &[u8]) -> Result<(), Error> { fn merge_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8],
value: &[u8])
-> Result<(), Error> {
unsafe { unsafe {
ffi::rocksdb_writebatch_merge_cf(self.inner, cf, key.as_ptr() as *const i8, key.len() as size_t, value.as_ptr() as *const i8, value.len() as size_t); ffi::rocksdb_writebatch_merge_cf(self.inner,
cf,
key.as_ptr() as *const i8,
key.len() as size_t,
value.as_ptr() as *const i8,
value.len() as size_t);
Ok(()) Ok(())
} }
} }
@ -627,14 +785,22 @@ impl Writable for WriteBatch {
/// Returns Err if the key was not found /// Returns Err if the key was not found
fn delete(&self, key: &[u8]) -> Result<(), Error> { fn delete(&self, key: &[u8]) -> Result<(), Error> {
unsafe { unsafe {
ffi::rocksdb_writebatch_delete(self.inner, key.as_ptr() as *const i8, key.len() as size_t); ffi::rocksdb_writebatch_delete(self.inner,
key.as_ptr() as *const i8,
key.len() as size_t);
Ok(()) Ok(())
} }
} }
fn delete_cf(&self, cf: *mut ffi::rocksdb_column_family_handle_t, key: &[u8]) -> Result<(), Error> { fn delete_cf(&self,
cf: *mut ffi::rocksdb_column_family_handle_t,
key: &[u8])
-> Result<(), Error> {
unsafe { unsafe {
ffi::rocksdb_writebatch_delete_cf(self.inner, cf, key.as_ptr() as *const i8, key.len() as size_t); ffi::rocksdb_writebatch_delete_cf(self.inner,
cf,
key.as_ptr() as *const i8,
key.len() as size_t);
Ok(()) Ok(())
} }
} }
@ -665,16 +831,16 @@ impl ReadOptions {
pub fn set_iterate_upper_bound(&mut self, key: &[u8]) { pub fn set_iterate_upper_bound(&mut self, key: &[u8]) {
unsafe { unsafe {
ffi::rocksdb_readoptions_set_iterate_upper_bound(self.inner, key.as_ptr() as *const i8, key.len() as size_t); ffi::rocksdb_readoptions_set_iterate_upper_bound(self.inner,
key.as_ptr() as *const i8,
key.len() as size_t);
} }
} }
} }
impl Default for ReadOptions { impl Default for ReadOptions {
fn default() -> ReadOptions { fn default() -> ReadOptions {
unsafe { unsafe { ReadOptions { inner: ffi::rocksdb_readoptions_create() } }
ReadOptions { inner: ffi::rocksdb_readoptions_create() }
}
} }
} }
@ -738,7 +904,10 @@ fn errors_do_stuff() {
// The DB will still be open when we try to destroy it and the lock should fail. // The DB will still be open when we try to destroy it and the lock should fail.
match DB::destroy(&opts, path) { match DB::destroy(&opts, path) {
Err(s) => { Err(s) => {
assert!(s == Error::new("IO error: lock _rust_rocksdb_error/LOCK: No locks available".to_owned())) assert!(s ==
Error::new("IO error: lock _rust_rocksdb_error/LOCK: No \
locks available"
.to_owned()))
} }
Ok(_) => panic!("should fail"), Ok(_) => panic!("should fail"),
} }
@ -792,7 +961,9 @@ fn iterator_test() {
assert!(p.is_ok()); assert!(p.is_ok());
let iter = db.iterator(IteratorMode::Start); let iter = db.iterator(IteratorMode::Start);
for (k, v) in iter { for (k, v) in iter {
println!("Hello {}: {}", str::from_utf8(&*k).unwrap(), str::from_utf8(&*v).unwrap()); println!("Hello {}: {}",
str::from_utf8(&*k).unwrap(),
str::from_utf8(&*v).unwrap());
} }
} }
let opts = Options::default(); let opts = Options::default();

@ -16,13 +16,14 @@
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::mem; use std::mem;
use libc::{self, c_int, c_uint, c_uchar, c_void, size_t, uint64_t}; use libc::{self, c_int, c_uchar, c_uint, c_void, size_t, uint64_t};
use {Options, WriteOptions, BlockBasedOptions}; use {BlockBasedOptions, Options, WriteOptions};
use comparator::{self, ComparatorCallback}; use comparator::{self, ComparatorCallback};
use ffi; use ffi;
use merge_operator::{self, MergeFn, MergeOperatorCallback, full_merge_callback, partial_merge_callback}; use merge_operator::{self, MergeFn, MergeOperatorCallback, full_merge_callback,
use rocksdb::{DBCompressionType, DBCompactionStyle, DBRecoveryMode, new_cache}; partial_merge_callback};
use rocksdb::{DBCompactionStyle, DBCompressionType, DBRecoveryMode, new_cache};
impl Drop for Options { impl Drop for Options {
fn drop(&mut self) { fn drop(&mut self) {
@ -58,7 +59,8 @@ impl BlockBasedOptions {
pub fn set_lru_cache(&mut self, size: size_t) { pub fn set_lru_cache(&mut self, size: size_t) {
let cache = new_cache(size); let cache = new_cache(size);
unsafe { unsafe {
// Since cache is wrapped in shared_ptr, we don't need to call rocksdb_cache_destroy explicitly. // Since cache is wrapped in shared_ptr, we don't need to
// call rocksdb_cache_destroy explicitly.
ffi::rocksdb_block_based_options_set_block_cache(self.inner, cache); ffi::rocksdb_block_based_options_set_block_cache(self.inner, cache);
} }
} }
@ -84,9 +86,7 @@ impl BlockBasedOptions {
impl Default for BlockBasedOptions { impl Default for BlockBasedOptions {
fn default() -> BlockBasedOptions { fn default() -> BlockBasedOptions {
let block_opts = unsafe { let block_opts = unsafe { ffi::rocksdb_block_based_options_create() };
ffi::rocksdb_block_based_options_create()
};
if block_opts.is_null() { if block_opts.is_null() {
panic!("Could not create rocksdb block based options".to_owned()); panic!("Could not create rocksdb block based options".to_owned());
} }
@ -117,7 +117,9 @@ impl Options {
pub fn optimize_level_style_compaction(&mut self, memtable_memory_budget: usize) { pub fn optimize_level_style_compaction(&mut self, memtable_memory_budget: usize) {
unsafe { unsafe {
ffi::rocksdb_options_optimize_level_style_compaction(self.inner, memtable_memory_budget as uint64_t); ffi::rocksdb_options_optimize_level_style_compaction(
self.inner,
memtable_memory_budget as uint64_t);
} }
} }
@ -184,7 +186,9 @@ impl Options {
pub fn compression_per_level(&mut self, level_types: &[DBCompressionType]) { pub fn compression_per_level(&mut self, level_types: &[DBCompressionType]) {
unsafe { unsafe {
let level_types: Vec<_> = level_types.iter().map(|&t| t as c_int).collect(); let level_types: Vec<_> = level_types.iter().map(|&t| t as c_int).collect();
ffi::rocksdb_options_set_compression_per_level(self.inner, level_types.as_ptr(), level_types.len() as size_t) ffi::rocksdb_options_set_compression_per_level(self.inner,
level_types.as_ptr(),
level_types.len() as size_t)
} }
} }
@ -195,7 +199,12 @@ impl Options {
}); });
unsafe { unsafe {
let mo = ffi::rocksdb_mergeoperator_create(mem::transmute(cb), Some(merge_operator::destructor_callback), Some(full_merge_callback), Some(partial_merge_callback), None, Some(merge_operator::name_callback)); let mo = ffi::rocksdb_mergeoperator_create(mem::transmute(cb),
Some(merge_operator::destructor_callback),
Some(full_merge_callback),
Some(partial_merge_callback),
None,
Some(merge_operator::name_callback));
ffi::rocksdb_options_set_merge_operator(self.inner, mo); ffi::rocksdb_options_set_merge_operator(self.inner, mo);
} }
} }
@ -208,7 +217,9 @@ impl Options {
/// Sets the comparator used to define the order of keys in the table. /// Sets the comparator used to define the order of keys in the table.
/// Default: a comparator that uses lexicographic byte-wise ordering /// Default: a comparator that uses lexicographic byte-wise ordering
/// ///
/// The client must ensure that the comparator supplied here has the same name and orders keys *exactly* the same as the comparator provided to previous open calls on the same DB. /// The client must ensure that the comparator supplied here has the same
/// name and orders keys *exactly* the same as the comparator provided to
/// previous open calls on the same DB.
pub fn set_comparator(&mut self, name: &str, compare_fn: fn(&[u8], &[u8]) -> i32) { pub fn set_comparator(&mut self, name: &str, compare_fn: fn(&[u8], &[u8]) -> i32) {
let cb = Box::new(ComparatorCallback { let cb = Box::new(ComparatorCallback {
name: CString::new(name.as_bytes()).unwrap(), name: CString::new(name.as_bytes()).unwrap(),
@ -216,7 +227,10 @@ impl Options {
}); });
unsafe { unsafe {
let cmp = ffi::rocksdb_comparator_create(mem::transmute(cb), Some(comparator::destructor_callback), Some(comparator::compare_callback), Some(comparator::name_callback)); let cmp = ffi::rocksdb_comparator_create(mem::transmute(cb),
Some(comparator::destructor_callback),
Some(comparator::compare_callback),
Some(comparator::name_callback));
ffi::rocksdb_options_set_comparator(self.inner, cmp); ffi::rocksdb_options_set_comparator(self.inner, cmp);
} }
} }
@ -270,9 +284,7 @@ impl Options {
/// opts.set_use_fsync(true); /// opts.set_use_fsync(true);
/// ``` /// ```
pub fn set_use_fsync(&mut self, useit: bool) { pub fn set_use_fsync(&mut self, useit: bool) {
unsafe { unsafe { ffi::rocksdb_options_set_use_fsync(self.inner, useit as c_int) }
ffi::rocksdb_options_set_use_fsync(self.inner, useit as c_int)
}
} }
/// Allows OS to incrementally sync files to disk while they are being /// Allows OS to incrementally sync files to disk while they are being
@ -304,9 +316,7 @@ impl Options {
} }
pub fn set_disable_data_sync(&mut self, disable: bool) { pub fn set_disable_data_sync(&mut self, disable: bool) {
unsafe { unsafe { ffi::rocksdb_options_set_disable_data_sync(self.inner, disable as c_int) }
ffi::rocksdb_options_set_disable_data_sync(self.inner, disable as c_int)
}
} }
/// Hints to the OS that it should not buffer disk I/O. Enabling this /// Hints to the OS that it should not buffer disk I/O. Enabling this
@ -722,9 +732,7 @@ impl Options {
/// opts.set_disable_auto_compactions(true); /// opts.set_disable_auto_compactions(true);
/// ``` /// ```
pub fn set_disable_auto_compactions(&mut self, disable: bool) { pub fn set_disable_auto_compactions(&mut self, disable: bool) {
unsafe { unsafe { ffi::rocksdb_options_set_disable_auto_compactions(self.inner, disable as c_int) }
ffi::rocksdb_options_set_disable_auto_compactions(self.inner, disable as c_int)
}
} }
pub fn set_block_based_table_factory(&mut self, factory: &BlockBasedOptions) { pub fn set_block_based_table_factory(&mut self, factory: &BlockBasedOptions) {

@ -45,8 +45,9 @@ pub fn test_column_family() {
families") families")
} }
Err(e) => { Err(e) => {
assert!(e.to_string().starts_with("Invalid argument: You have to open \ assert!(e.to_string()
all column families.")) .starts_with("Invalid argument: You have to open all \
column families."))
} }
} }
} }

@ -114,39 +114,48 @@ pub fn test_iterator() {
assert_eq!(iterator1.collect::<Vec<_>>(), expected2); assert_eq!(iterator1.collect::<Vec<_>>(), expected2);
} }
{ {
let iterator1 = db.iterator(IteratorMode::From(b"k2", let iterator1 =
Direction::Forward)); db.iterator(IteratorMode::From(b"k2", Direction::Forward));
let expected = vec![(cba(&k2), cba(&v2)), let expected = vec![(cba(&k2), cba(&v2)),
(cba(&k3), cba(&v3)), (cba(&k3), cba(&v3)),
(cba(&k4), cba(&v4))]; (cba(&k4), cba(&v4))];
assert_eq!(iterator1.collect::<Vec<_>>(), expected); assert_eq!(iterator1.collect::<Vec<_>>(), expected);
} }
{ {
let iterator1 = db.iterator(IteratorMode::From(b"k2", let iterator1 =
Direction::Reverse)); db.iterator(IteratorMode::From(b"k2", Direction::Reverse));
let expected = vec![(cba(&k2), cba(&v2)), (cba(&k1), cba(&v1))]; let expected = vec![(cba(&k2), cba(&v2)), (cba(&k1), cba(&v1))];
assert_eq!(iterator1.collect::<Vec<_>>(), expected); assert_eq!(iterator1.collect::<Vec<_>>(), expected);
} }
{ {
let iterator1 = db.iterator(IteratorMode::From(b"k0", Direction::Forward)); let iterator1 =
db.iterator(IteratorMode::From(b"k0", Direction::Forward));
assert!(iterator1.valid()); assert!(iterator1.valid());
let iterator2 = db.iterator(IteratorMode::From(b"k1", Direction::Forward)); let iterator2 =
db.iterator(IteratorMode::From(b"k1", Direction::Forward));
assert!(iterator2.valid()); assert!(iterator2.valid());
let iterator3 = db.iterator(IteratorMode::From(b"k11", Direction::Forward)); let iterator3 =
db.iterator(IteratorMode::From(b"k11", Direction::Forward));
assert!(iterator3.valid()); assert!(iterator3.valid());
let iterator4 = db.iterator(IteratorMode::From(b"k5", Direction::Forward)); let iterator4 =
db.iterator(IteratorMode::From(b"k5", Direction::Forward));
assert!(!iterator4.valid()); assert!(!iterator4.valid());
let iterator5 = db.iterator(IteratorMode::From(b"k0", Direction::Reverse)); let iterator5 =
db.iterator(IteratorMode::From(b"k0", Direction::Reverse));
assert!(iterator5.valid()); assert!(iterator5.valid());
let iterator6 = db.iterator(IteratorMode::From(b"k1", Direction::Reverse)); let iterator6 =
db.iterator(IteratorMode::From(b"k1", Direction::Reverse));
assert!(iterator6.valid()); assert!(iterator6.valid());
let iterator7 = db.iterator(IteratorMode::From(b"k11", Direction::Reverse)); let iterator7 =
db.iterator(IteratorMode::From(b"k11", Direction::Reverse));
assert!(iterator7.valid()); assert!(iterator7.valid());
let iterator8 = db.iterator(IteratorMode::From(b"k5", Direction::Reverse)); let iterator8 =
db.iterator(IteratorMode::From(b"k5", Direction::Reverse));
assert!(!iterator8.valid()); assert!(!iterator8.valid());
} }
{ {
let mut iterator1 = db.iterator(IteratorMode::From(b"k4", Direction::Forward)); let mut iterator1 =
db.iterator(IteratorMode::From(b"k4", Direction::Forward));
iterator1.next(); iterator1.next();
assert!(iterator1.valid()); assert!(iterator1.valid());
iterator1.next(); iterator1.next();

Loading…
Cancel
Save