diff --git a/cozo-rocks/include/cozorocks.h b/cozo-rocks/include/cozorocks.h index d6d96ac7..a5af1ac2 100644 --- a/cozo-rocks/include/cozorocks.h +++ b/cozo-rocks/include/cozorocks.h @@ -25,6 +25,14 @@ std::unique_ptr new_db(); struct ReadOptionsBridge { mutable RDB::ReadOptions inner; + + inline void set_verify_checksums(bool v) const { + inner.verify_checksums = v; + } + + inline void set_total_order_seek(bool v) const { + inner.total_order_seek = v; + } }; struct WriteOptionsBridge { @@ -116,6 +124,15 @@ struct PinnableSliceBridge { } }; +struct SliceBridge { + RDB::Slice inner; + SliceBridge(RDB::Slice&& s) : inner(s) {} + + inline rust::Slice as_bytes() const { + return rust::Slice(reinterpret_cast(inner.data()), inner.size()); + } +}; + void write_status_impl(Status &status, StatusCode code, StatusSubCode subcode, StatusSeverity severity); inline void write_status(RDB::Status &&rstatus, Status &status) { @@ -125,6 +142,53 @@ inline void write_status(RDB::Status &&rstatus, Status &status) { } } +struct WriteBatchBridge { + mutable RDB::WriteBatch inner; + std::vector *handles; +}; + +struct IteratorBridge { + mutable std::unique_ptr inner; + + IteratorBridge(RDB::Iterator *it) : inner(it) {} + + inline void seek_to_first() const { + inner->SeekToFirst(); + } + + inline void seek_to_last() const { + inner->SeekToLast(); + } + + inline void next() const { + inner->Next(); + } + + inline bool is_valid() const { + return inner->Valid(); + } + + inline void seek(rust::Slice key) const { + auto k = RDB::Slice(reinterpret_cast(key.data()), key.size()); + inner->Seek(k); + } + + inline void seek_for_prev(rust::Slice key) const { + auto k = RDB::Slice(reinterpret_cast(key.data()), key.size()); + inner->SeekForPrev(k); + } + + inline std::unique_ptr key() const { + return std::make_unique(inner->key()); + } + + inline std::unique_ptr value() const { + return std::make_unique(inner->value()); + } + + Status status() const; +}; + struct DBBridge { mutable std::unique_ptr inner; @@ -132,14 +196,20 @@ struct DBBridge { DBBridge(RDB::DB *inner_) : inner(inner_) {} - inline std::unique_ptr> cf_names() const { - auto ret = std::make_unique>(); - for (auto h : handles) { + inline std::unique_ptr > cf_names() const { + auto ret = std::make_unique < std::vector < std::string >> (); + for (auto h: handles) { ret->push_back(h->GetName()); } return ret; } + inline std::unique_ptr write_batch() const { + auto wb = std::make_unique(); + wb->handles = &handles; + return wb; + } + inline void put( const WriteOptionsBridge &options, std::size_t cf_id, @@ -172,6 +242,10 @@ struct DBBridge { ); return pinnable_val; } + + inline std::unique_ptr iterator(const ReadOptionsBridge &options, std::size_t cf_id) const { + return std::make_unique(inner->NewIterator(options.inner, handles[cf_id])); + } }; inline std::unique_ptr > list_column_families(const OptionsBridge &options, diff --git a/cozo-rocks/src/cozorocks.cc b/cozo-rocks/src/cozorocks.cc index c07b3931..eefeac6b 100644 --- a/cozo-rocks/src/cozorocks.cc +++ b/cozo-rocks/src/cozorocks.cc @@ -9,4 +9,10 @@ void write_status_impl(Status &status, StatusCode code, StatusSubCode subcode, S status.code = code; status.subcode = subcode; status.severity = severity; +} + +Status IteratorBridge::status() const { + Status s; + write_status(inner->status(), s); + return s; } \ No newline at end of file diff --git a/cozo-rocks/src/lib.rs b/cozo-rocks/src/lib.rs index 2eab9222..9a3fa123 100644 --- a/cozo-rocks/src/lib.rs +++ b/cozo-rocks/src/lib.rs @@ -68,8 +68,13 @@ mod ffi { type PinnableSliceBridge; fn as_bytes(self: &PinnableSliceBridge) -> &[u8]; + type SliceBridge; + fn as_bytes(self: &SliceBridge) -> &[u8]; + type ReadOptionsBridge; fn new_read_options() -> UniquePtr; + fn set_verify_checksums(self: &ReadOptionsBridge, v: bool); + fn set_total_order_seek(self: &ReadOptionsBridge, v: bool); type WriteOptionsBridge; fn new_write_options() -> UniquePtr; @@ -89,6 +94,21 @@ mod ffi { fn cf_names(self: &DBBridge) -> UniquePtr>; fn put(self: &DBBridge, options: &WriteOptionsBridge, cf_id: usize, key: &[u8], val: &[u8], status: &mut Status); fn get(self: &DBBridge, options: &ReadOptionsBridge, cf_id: usize, key: &[u8], status: &mut Status) -> UniquePtr; + fn write_batch(self: &DBBridge) -> UniquePtr; + fn iterator(self: &DBBridge, options: &ReadOptionsBridge, cf_id: usize) -> UniquePtr; + + type WriteBatchBridge; + + type IteratorBridge; + fn seek_to_first(self: &IteratorBridge); + fn seek_to_last(self: &IteratorBridge); + fn next(self: &IteratorBridge); + fn is_valid(self: &IteratorBridge) -> bool; + fn seek(self: &IteratorBridge, key: &[u8]); + fn seek_for_prev(self: &IteratorBridge, key: &[u8]); + fn key(self: &IteratorBridge) -> UniquePtr; + fn value(self: &IteratorBridge) -> UniquePtr; + fn status(self: &IteratorBridge) -> Status; } } @@ -140,18 +160,19 @@ impl Default for Options { } } -pub struct PinnableSlice { - bridge: UniquePtr, +pub struct ReadOptions { + bridge: UniquePtr, } -impl PinnableSlice { - pub fn as_bytes(&self) -> &[u8] { - self.bridge.as_bytes() +impl ReadOptions { + pub fn set_total_order_seek(self, v: bool) -> Self { + self.bridge.set_total_order_seek(v); + self + } + pub fn set_verify_checksums(self, v: bool) -> Self { + self.bridge.set_total_order_seek(v); + self } -} - -pub struct ReadOptions { - bridge: UniquePtr, } impl Default for ReadOptions { @@ -177,12 +198,16 @@ impl Default for WriteOptions { } } +pub type PinnableSlice = UniquePtr; +pub type Slice = UniquePtr; +pub type Iterator = UniquePtr; + pub struct DB { bridge: UniquePtr, pub options: Options, pub default_read_options: ReadOptions, pub default_write_options: WriteOptions, - pub column_families: BTreeMap + pub column_families: BTreeMap, } fn get_path_bytes(path: &std::path::Path) -> &[u8] { @@ -209,7 +234,7 @@ impl DB { let bridge = open_db( &options.bridge, get_path_bytes(path.as_ref()), - &mut status + &mut status, ); if status.code == StatusCode::kOk { @@ -219,13 +244,11 @@ impl DB { default_read_options: ReadOptions::default(), default_write_options: WriteOptions::default(), options, - column_families + column_families, }) } else { Err(status) } - - } #[inline] @@ -248,11 +271,16 @@ impl DB { &options.unwrap_or(&self.default_read_options).bridge, cf, key.as_ref(), &mut status); match status.code { - StatusCode::kOk => Ok(Some(PinnableSlice { bridge: slice })), + StatusCode::kOk => Ok(Some(slice)), StatusCode::kNotFound => Ok(None), _ => Err(status) } } + + #[inline] + pub fn iterator(&self, cf: usize, options: Option<&ReadOptions>) -> Iterator { + self.bridge.iterator(&options.unwrap_or(&self.default_read_options).bridge, cf) + } } impl Default for Status {