diff --git a/cozorocks/src/bridge.h b/cozorocks/src/bridge.h index 34e81a15..80f6c029 100644 --- a/cozorocks/src/bridge.h +++ b/cozorocks/src/bridge.h @@ -9,67 +9,220 @@ #include "rocksdb/utilities/transaction.h" #include "rocksdb/utilities/transaction_db.h" #include "rocksdb/utilities/optimistic_transaction_db.h" +#include "rocksdb/table.h" +#include "rocksdb/filter_policy.h" +#include "rocksdb/slice_transform.h" namespace rocksdb_additions { + using namespace std; using namespace rocksdb; // for write options - void set_w_opts_sync(WriteOptions &opts, bool v) { + inline void set_w_opts_sync(WriteOptions &opts, bool v) { Status s; opts.sync = v; } - void set_w_opts_disable_wal(WriteOptions &opts, bool v) { + inline void set_w_opts_disable_wal(WriteOptions &opts, bool v) { opts.disableWAL = v; } - void set_w_opts_low_pri(WriteOptions &opts, bool v) { + inline void set_w_opts_low_pri(WriteOptions &opts, bool v) { opts.low_pri = v; } // for read options - void set_iterate_lower_bound(ReadOptions &opts, const Slice &lower_bound) { + inline void set_iterate_lower_bound(ReadOptions &opts, const Slice &lower_bound) { opts.iterate_lower_bound = &lower_bound; } - void set_iterate_upper_bound(ReadOptions &opts, const Slice &lower_bound) { + inline void set_iterate_upper_bound(ReadOptions &opts, const Slice &lower_bound) { opts.iterate_upper_bound = &lower_bound; } - void set_snapshot(ReadOptions &opts, const Snapshot &snapshot) { + inline void set_snapshot(ReadOptions &opts, const Snapshot &snapshot) { opts.snapshot = &snapshot; } - void set_r_opts_total_order_seek(ReadOptions &opts, bool total_order_seek) { + inline void set_r_opts_total_order_seek(ReadOptions &opts, bool total_order_seek) { opts.total_order_seek = total_order_seek; } - void set_r_opts_auto_prefix_mode(ReadOptions &opts, bool auto_prefix_mode) { + inline void set_r_opts_auto_prefix_mode(ReadOptions &opts, bool auto_prefix_mode) { opts.auto_prefix_mode = auto_prefix_mode; } - void set_r_opts_prefix_same_as_start(ReadOptions &opts, bool prefix_same_as_start) { + inline void set_r_opts_prefix_same_as_start(ReadOptions &opts, bool prefix_same_as_start) { opts.prefix_same_as_start = prefix_same_as_start; } - void set_r_opts_tailing(ReadOptions &opts, bool tailing) { + inline void set_r_opts_tailing(ReadOptions &opts, bool tailing) { opts.tailing = tailing; } - void set_r_opts_pin_data(ReadOptions &opts, bool pin_data) { + inline void set_r_opts_pin_data(ReadOptions &opts, bool pin_data) { opts.pin_data = pin_data; } - void set_r_opts_verify_checksums(ReadOptions &opts, bool verify_checksums) { + inline void set_r_opts_verify_checksums(ReadOptions &opts, bool verify_checksums) { opts.verify_checksums = verify_checksums; } - void set_r_opts_fill_cache(ReadOptions &opts, bool fill_cache) { + inline void set_r_opts_fill_cache(ReadOptions &opts, bool fill_cache) { opts.fill_cache = fill_cache; } + + // for options + + inline void set_opts_create_if_mission(Options &opts, bool v) { + opts.create_if_missing = v; + } + + inline void set_opts_error_if_exists(Options &opts, bool v) { + opts.error_if_exists = v; + } + + inline void set_opts_create_missing_column_families(Options &opts, bool v) { + opts.create_missing_column_families = v; + } + + inline void set_opts_paranoid_checks(Options &opts, bool v) { + opts.paranoid_checks = v; + } + + inline void set_opts_flush_verify_memtable_count(Options &opts, bool v) { + opts.flush_verify_memtable_count = v; + } + + inline void set_opts_track_and_verify_wals_in_manifest(Options &opts, bool v) { + opts.track_and_verify_wals_in_manifest = v; + } + + inline void set_opts_verify_sst_unique_id_in_manifest(Options &opts, bool v) { + opts.verify_sst_unique_id_in_manifest = v; + } + + inline void set_opts_bloom_filter(Options &options, const double bits_per_key, const bool whole_key_filtering) { + BlockBasedTableOptions table_options; + table_options.filter_policy.reset(NewBloomFilterPolicy(bits_per_key, false)); + table_options.whole_key_filtering = whole_key_filtering; + options.table_factory.reset( + NewBlockBasedTableFactory( + table_options)); + } + + inline void set_opts_capped_prefix_extractor(Options &options, const size_t cap_len) { + options.prefix_extractor.reset(NewCappedPrefixTransform(cap_len)); + } + + + inline void set_opts_comparator(Options &inner, const Comparator &cmp_obj) { + inner.comparator = &cmp_obj; + } + + inline void set_opts_enable_blob_files(Options &inner, bool v) { + inner.enable_blob_files = v; + } + + inline void set_opts_min_blob_size(Options &inner, uint64_t size) { + inner.min_blob_size = size; + } + + inline void set_opts_blob_file_size(Options &inner, uint64_t size) { + inner.blob_file_size = size; + } + + inline void set_opts_enable_blob_garbage_collection(Options &inner, bool v) { + inner.enable_blob_garbage_collection = v; + } + + // otopts + + inline void set_otopts_comparator(OptimisticTransactionOptions &opts, Comparator &cmp) { + opts.cmp = &cmp; + } + + // opening + + inline shared_ptr + open_db_raw(const Options &options, const string &path, Status &status) { + DB *db = nullptr; + + status = DB::Open(options, path, &db); + return shared_ptr(db); + } + + inline shared_ptr + open_tdb_raw(const Options &options, + const TransactionDBOptions &txn_db_options, + const string &path, + Status &status) { + TransactionDB *txn_db = nullptr; + + status = TransactionDB::Open(options, txn_db_options, path, &txn_db); + + return shared_ptr(txn_db); + } + + + inline shared_ptr + open_odb_raw(const Options &options, const string &path, Status &status) { + OptimisticTransactionDB *txn_db = nullptr; + + status = OptimisticTransactionDB::Open(options, + path, + &txn_db); + + return shared_ptr(txn_db); + } + + + // comparator + + typedef int(*CmpFn)(const rocksdb::Slice &a, const rocksdb::Slice &b); + + class RustComparator : public Comparator { + public: + inline RustComparator(string name_, bool can_different_bytes_be_equal_, void const *const f) : + name(name_), + can_different_bytes_be_equal(can_different_bytes_be_equal_) { + CmpFn f_ = CmpFn(f); + ext_cmp = f_; + } + + inline int Compare(const rocksdb::Slice &a, const rocksdb::Slice &b) const { + return ext_cmp(a, b); + } + + inline const char *Name() const { + return name.c_str(); + } + + inline virtual bool CanKeysWithDifferentByteContentsBeEqual() const { + return can_different_bytes_be_equal; + } + + inline void FindShortestSeparator(std::string *, const rocksdb::Slice &) const {} + + inline void FindShortSuccessor(std::string *) const {} + + std::string name; + CmpFn ext_cmp; + bool can_different_bytes_be_equal; + }; + + inline unique_ptr + new_rust_comparator( + string name_, + bool can_different_bytes_be_equal_, + void const *const f + ) { + return make_unique(name_, can_different_bytes_be_equal_, f); + } + } #endif //COZOROCKS_ADDITIONS_H diff --git a/cozorocks/src/lib.rs b/cozorocks/src/lib.rs index 085ee685..e909b849 100644 --- a/cozorocks/src/lib.rs +++ b/cozorocks/src/lib.rs @@ -1,5 +1,3 @@ -extern crate core; - use autocxx::prelude::*; use std::os::raw::c_char; use std::pin::Pin; @@ -30,20 +28,13 @@ include_cpp! { generate_ns!("rocksdb_additions") } -pub use ffi::rocksdb::Options; -pub use ffi::rocksdb::PinnableSlice; -pub use ffi::rocksdb::ReadOptions; -pub use ffi::rocksdb::Slice; -pub use ffi::rocksdb::Snapshot; -pub use ffi::rocksdb::Status; +pub use autocxx::{c_int, c_void}; +pub use cxx::{CxxString, CxxVector, SharedPtr, UniquePtr}; pub use ffi::rocksdb::Status_Code as StatusCode; pub use ffi::rocksdb::Status_Severity as StatusSeverity; pub use ffi::rocksdb::Status_SubCode as StatusSubCode; -pub use ffi::rocksdb::WriteOptions; -pub use ffi::rocksdb::DB; -pub use ffi::rocksdb_additions::set_iterate_lower_bound; -pub use ffi::rocksdb_additions::set_iterate_upper_bound; -pub use ffi::rocksdb_additions::set_snapshot; +pub use ffi::rocksdb::*; +pub use ffi::rocksdb_additions::*; pub struct DbStatus { pub code: StatusCode, @@ -64,7 +55,7 @@ fn convert_status(status: &ffi::rocksdb::Status) -> DbStatus { } #[inline(always)] -fn convert_slice(src: &[u8]) -> Slice { +pub fn convert_slice(src: &[u8]) -> Slice { Slice { data_: src.as_ptr() as *const c_char, size_: src.len(), @@ -72,7 +63,7 @@ fn convert_slice(src: &[u8]) -> Slice { } #[inline(always)] -fn convert_slice_back(src: &Slice) -> &[u8] { +pub fn convert_slice_back(src: &Slice) -> &[u8] { unsafe { std::slice::from_raw_parts(src.data() as *const u8, src.size()) } } @@ -172,6 +163,15 @@ macro_rules! let_read_opts { }; } +unsafe impl Send for RustComparator {} +unsafe impl Sync for RustComparator {} + +impl ReadOptions { + pub fn x(&self) -> bool { + true + } +} + #[cfg(test)] mod tests { use super::ffi::rocksdb::{Options, ReadOptions, WriteOptions}; @@ -193,5 +193,25 @@ mod tests { let_write_opts!(w_opts = { disable_wal => true }); } dbg!(size_of::()); + // let cmp = RustComparator::new().within_unique_ptr(); + + #[no_mangle] + extern "C" fn rusty_cmp( + a: &ffi::rocksdb::Slice, + b: &ffi::rocksdb::Slice, + ) -> autocxx::c_int { + dbg!(convert_slice_back(a)); + dbg!(convert_slice_back(b)); + autocxx::c_int(0) + } + + let cmp = unsafe { + let f_ptr = rusty_cmp as *const autocxx::c_void; + new_rust_comparator("hello", false, f_ptr) + }; + + let a = convert_slice(&[1, 2, 3]); + let b = convert_slice(&[4, 5, 6, 7]); + cmp.Compare(&a, &b); } } diff --git a/src/lib.rs b/src/lib.rs index e69de29b..862452de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -0,0 +1,30 @@ +use cozorocks::DbStatus; +use lazy_static::lazy_static; + +#[no_mangle] +extern "C" fn rusty_cmp(a: &cozorocks::Slice, b: &cozorocks::Slice) -> cozorocks::c_int { + dbg!(cozorocks::convert_slice_back(a)); + dbg!(cozorocks::convert_slice_back(b)); + cozorocks::c_int(0) +} + +lazy_static! { + static ref RUSTY_COMPARATOR: cozorocks::UniquePtr = { + unsafe { + let f_ptr = rusty_cmp as *const cozorocks::c_void; + cozorocks::new_rust_comparator("hello", false, f_ptr) + } + }; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_it() { + let a = cozorocks::convert_slice(&[1, 2, 3, 4]); + let b = cozorocks::convert_slice(&[4, 5, 6, 7]); + assert_eq!(RUSTY_COMPARATOR.Compare(&a, &b), cozorocks::c_int(0)); + } +}