From 64e318bf02261303abacd94a62812ef9da42d5b0 Mon Sep 17 00:00:00 2001 From: Chung Quan Tin Date: Thu, 26 Jan 2023 21:22:17 -0500 Subject: [PATCH 1/9] Add: Rust bindings generate using bindgen Generate bindings code using bindgen. Implement two simple methods to open / close database using the following ukv_database_init() and ukv_database_Free() --- .gitignore | 1 + .vscode/c_cpp_properties.json | 6 +- rust/.clippy.toml | 6 + rust/.editorconfig | 20 + rust/CHANGELOG.md | 25 + rust/Cargo.lock | 263 +++++++ rust/Cargo.toml | 19 + rust/README.md | 10 +- rust/build.rs | 23 + rust/rustfmt.toml | 17 + rust/src/error.rs | 7 + rust/src/lib.rs | 47 ++ rust/src/ukv/bindings.rs | 1216 +++++++++++++++++++++++++++++++++ rust/src/ukv/mod.rs | 1 + rust/wrapper.h | 1 + 15 files changed, 1657 insertions(+), 5 deletions(-) create mode 100644 rust/.clippy.toml create mode 100644 rust/.editorconfig create mode 100644 rust/CHANGELOG.md create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/build.rs create mode 100644 rust/rustfmt.toml create mode 100644 rust/src/error.rs create mode 100644 rust/src/lib.rs create mode 100644 rust/src/ukv/bindings.rs create mode 100644 rust/src/ukv/mod.rs create mode 100644 rust/wrapper.h diff --git a/.gitignore b/.gitignore index 5b6371403..ab4ac3694 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ CMakeCache.txt cmake_install.cmake CMakeFiles build/ +target/ build_debug/ build_release/ tmp/ diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index cdea37608..505884c2b 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,7 +2,11 @@ "configurations": [ { "name": "Linux", - "configurationProvider": "ms-vscode.cmake-tools" + "configurationProvider": "ms-vscode.cmake-tools", + "includePath": [ + "${default}", + "${workspaceFolder}/include" + ] } ], "version": 4 diff --git a/rust/.clippy.toml b/rust/.clippy.toml new file mode 100644 index 000000000..991769fde --- /dev/null +++ b/rust/.clippy.toml @@ -0,0 +1,6 @@ +# Right now we just use the defaults. This file exists should we +# want to change that, and to indicate to contributors that they +# might want to run clippy. +# +# See https://rust-lang.github.io/rust-clippy/master/index.html for +# the complete list of lints. \ No newline at end of file diff --git a/rust/.editorconfig b/rust/.editorconfig new file mode 100644 index 000000000..476dd162b --- /dev/null +++ b/rust/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig coding styles definitions. For more information about the +# properties used in this file, please see the EditorConfig documentation: +# http://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +end_of_line = LF +indent_size = 4 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{yml,json}] +indent_size = 2 +indent_style = space + +[*.{md,diff}] +trim_trailing_whitespace = false diff --git a/rust/CHANGELOG.md b/rust/CHANGELOG.md new file mode 100644 index 000000000..17b1dff65 --- /dev/null +++ b/rust/CHANGELOG.md @@ -0,0 +1,25 @@ +# CHANGELOG + +## 26-01-2023 + +### Contributors + +- chungquantin + +### Added + +- Database structure + +```rs +struct Database { + db: UkvDatabaseInitType +} +``` + +- Build bindings to `cpp` header file in `include/ukv`. To generate bindings code stored, use `cargo build`. `build.rs` includes code to build bindings using `bindgen` +- Support two APIs: `ukv_database_init` and `ukv_database_free` +- Add clippy, rust-fmt and editor config file for formatting and linting + +### Issues + +- Can't generate bindings on file with linked source header. For example, generate on file `blobs.h` which includes `ukv/db.h` would throw error `No header file found`. diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 000000000..7dde2479b --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,263 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bindgen" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "proc-macro2" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ukv" +version = "0.0.1" +dependencies = [ + "bindgen", + "thiserror", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 000000000..831f29c43 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "ukv" +version = "0.0.1" +publish = true +edition = "2021" +readme = "CARGO.md" +homepage = "https://github.com/unum-cloud/ukv" +documentation = "https://unum.cloud/ukv/rust/index.html" +repository = "https://github.com/unum-cloud/ukv" +build = "build.rs" + +[build-dependencies] +bindgen = "0.63.0" + +[lib] +name = "ukv" + +[dependencies] +thiserror = "1.0.38" diff --git a/rust/README.md b/rust/README.md index 99655bf5d..18833eead 100644 --- a/rust/README.md +++ b/rust/README.md @@ -2,10 +2,12 @@ Rust implementation is designed to support: -* Named Collections -* ACID Transactions -* Single & Batch Operations -* [Apache DataFusion](https://arrow.apache.org/datafusion/) `TableProvider` for SQL +- Named Collections +- ACID Transactions +- Single & Batch Operations +- [Apache DataFusion](https://arrow.apache.org/datafusion/) `TableProvider` for SQL +- Tabular operation with [Polars](https://www.pola.rs/) and integration with [`Apache Arrow`](https://pola-rs.github.io/polars-book/user-guide/howcani/interop/arrow.html) +- NetworkX compatibility using [RustworkX](https://github.com/Qiskit/rustworkx) Using it should be, again, familiar, as it mimics [`std::collections`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html): diff --git a/rust/build.rs b/rust/build.rs new file mode 100644 index 000000000..a5ffb27fe --- /dev/null +++ b/rust/build.rs @@ -0,0 +1,23 @@ +extern crate bindgen; + +use std::path::PathBuf; + +fn main() { + // Tell cargo to invalidate the built crate whenever the wrapper changes + println!("cargo:rerun-if-changed=wrapper.h"); + // Tell cargo to look for shared libraries in the specified directory + println!("cargo:rustc-link-search=../include/ukv"); + + let bindings = bindgen::Builder::default() + // .header("../include/ukv/db.h") + // .header("../include/ukv/blobs.h") + .header("./wrapper.h") + .detect_include_paths(true) + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + let out_path = PathBuf::from("./src/ukv"); + bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings!"); +} diff --git a/rust/rustfmt.toml b/rust/rustfmt.toml new file mode 100644 index 000000000..dc2e24ce3 --- /dev/null +++ b/rust/rustfmt.toml @@ -0,0 +1,17 @@ +edition = "2021" +hard_tabs = true +merge_derives = true +reorder_imports = true +reorder_modules = true +use_field_init_shorthand = true +use_small_heuristics = "Off" + +# ----------------------------------- +# Unstable options we would like to use in future +# ----------------------------------- + +#blank_lines_lower_bound = 1 +#indent_style = "Block" +#match_arm_blocks = true +#reorder_impl_items = true +#wrap_comments = true \ No newline at end of file diff --git a/rust/src/error.rs b/rust/src/error.rs new file mode 100644 index 000000000..37a741acc --- /dev/null +++ b/rust/src/error.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum DataStoreError { + #[error("unknown data store error")] + Unknown, +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 000000000..93a132cce --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,47 @@ +mod error; +mod ukv; + +use std::ffi::CString; + +include!("../src/ukv/bindings.rs"); + +type UkvDatabaseInitType = ukv_database_init_t; + +pub struct Database { + db: UkvDatabaseInitType, +} + +impl Database { + /// Open a new database using ukv_database_init() + pub fn new() -> Result { + let c_str = CString::default(); + let config: *const std::ffi::c_char = c_str.as_ptr(); + let error: *mut *const std::ffi::c_char = &mut c_str.as_ptr(); + let mut void_fn = &mut () as *mut _ as *mut std::ffi::c_void; + let db_ptr = &mut void_fn; + let mut database = UkvDatabaseInitType { + config, + db: db_ptr, + error, + }; + // Calling C++ function generated from bindgen + unsafe { + ukv_database_init(&mut database); + }; + + Ok(Self { + db: database, + }) + } + + pub fn contains_key() {} + + // Close a database using ukv_database_free() + pub fn close() -> Result<(), error::DataStoreError> { + let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; + unsafe { + ukv_database_free(void_fn); + }; + Ok(()) + } +} diff --git a/rust/src/ukv/bindings.rs b/rust/src/ukv/bindings.rs new file mode 100644 index 000000000..c317670ac --- /dev/null +++ b/rust/src/ukv/bindings.rs @@ -0,0 +1,1216 @@ +/* automatically generated by rust-bindgen 0.63.0 */ + +pub const __GNUC_VA_LIST: u32 = 1; +pub const true_: u32 = 1; +pub const false_: u32 = 0; +pub const __bool_true_false_are_defined: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const __DARWIN_ONLY_VERS_1050: u32 = 1; +pub const __DARWIN_UNIX03: u32 = 1; +pub const __DARWIN_64_BIT_INO_T: u32 = 1; +pub const __DARWIN_VERS_1050: u32 = 1; +pub const __DARWIN_NON_CANCELABLE: u32 = 0; +pub const __DARWIN_SUF_EXTSN: &[u8; 14usize] = b"$DARWIN_EXTSN\0"; +pub const __DARWIN_C_ANSI: u32 = 4096; +pub const __DARWIN_C_FULL: u32 = 900000; +pub const __DARWIN_C_LEVEL: u32 = 900000; +pub const __STDC_WANT_LIB_EXT1__: u32 = 1; +pub const __DARWIN_NO_LONG_LONG: u32 = 0; +pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; +pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; +pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; +pub const __PTHREAD_SIZE__: u32 = 8176; +pub const __PTHREAD_ATTR_SIZE__: u32 = 56; +pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; +pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; +pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; +pub const __PTHREAD_COND_SIZE__: u32 = 40; +pub const __PTHREAD_ONCE_SIZE__: u32 = 8; +pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; +pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const INT64_MAX: u64 = 9223372036854775807; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT64_MIN: i64 = -9223372036854775808; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const UINT64_MAX: i32 = -1; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST64_MIN: i64 = -9223372036854775808; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const INT_LEAST64_MAX: u64 = 9223372036854775807; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const UINT_LEAST64_MAX: i32 = -1; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i32 = -32768; +pub const INT_FAST32_MIN: i32 = -2147483648; +pub const INT_FAST64_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u32 = 32767; +pub const INT_FAST32_MAX: u32 = 2147483647; +pub const INT_FAST64_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: u32 = 65535; +pub const UINT_FAST32_MAX: u32 = 4294967295; +pub const UINT_FAST64_MAX: i32 = -1; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const UINTPTR_MAX: i32 = -1; +pub const SIZE_MAX: i32 = -1; +pub const RSIZE_MAX: i32 = -1; +pub const WINT_MIN: i32 = -2147483648; +pub const WINT_MAX: u32 = 2147483647; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub type va_list = __builtin_va_list; +pub type __gnuc_va_list = __builtin_va_list; +pub type wchar_t = ::std::os::raw::c_int; +pub type max_align_t = f64; +pub type int_least8_t = i8; +pub type int_least16_t = i16; +pub type int_least32_t = i32; +pub type int_least64_t = i64; +pub type uint_least8_t = u8; +pub type uint_least16_t = u16; +pub type uint_least32_t = u32; +pub type uint_least64_t = u64; +pub type int_fast8_t = i8; +pub type int_fast16_t = i16; +pub type int_fast32_t = i32; +pub type int_fast64_t = i64; +pub type uint_fast8_t = u8; +pub type uint_fast16_t = u16; +pub type uint_fast32_t = u32; +pub type uint_fast64_t = u64; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_longlong; +pub type __uint64_t = ::std::os::raw::c_ulonglong; +pub type __darwin_intptr_t = ::std::os::raw::c_long; +pub type __darwin_natural_t = ::std::os::raw::c_uint; +pub type __darwin_ct_rune_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Copy, Clone)] +pub union __mbstate_t { + pub __mbstate8: [::std::os::raw::c_char; 128usize], + pub _mbstateL: ::std::os::raw::c_longlong, +} +#[test] +fn bindgen_test_layout___mbstate_t() { + const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__mbstate_t>(), + 128usize, + concat!("Size of: ", stringify!(__mbstate_t)) + ); + assert_eq!( + ::std::mem::align_of::<__mbstate_t>(), + 8usize, + concat!("Alignment of ", stringify!(__mbstate_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__mbstate8) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(__mbstate_t), "::", stringify!(__mbstate8)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr)._mbstateL) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(__mbstate_t), "::", stringify!(_mbstateL)) + ); +} +pub type __darwin_mbstate_t = __mbstate_t; +pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; +pub type __darwin_size_t = ::std::os::raw::c_ulong; +pub type __darwin_va_list = __builtin_va_list; +pub type __darwin_wchar_t = ::std::os::raw::c_int; +pub type __darwin_rune_t = __darwin_wchar_t; +pub type __darwin_wint_t = ::std::os::raw::c_int; +pub type __darwin_clock_t = ::std::os::raw::c_ulong; +pub type __darwin_socklen_t = __uint32_t; +pub type __darwin_ssize_t = ::std::os::raw::c_long; +pub type __darwin_time_t = ::std::os::raw::c_long; +pub type __darwin_blkcnt_t = __int64_t; +pub type __darwin_blksize_t = __int32_t; +pub type __darwin_dev_t = __int32_t; +pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; +pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; +pub type __darwin_gid_t = __uint32_t; +pub type __darwin_id_t = __uint32_t; +pub type __darwin_ino64_t = __uint64_t; +pub type __darwin_ino_t = __darwin_ino64_t; +pub type __darwin_mach_port_name_t = __darwin_natural_t; +pub type __darwin_mach_port_t = __darwin_mach_port_name_t; +pub type __darwin_mode_t = __uint16_t; +pub type __darwin_off_t = __int64_t; +pub type __darwin_pid_t = __int32_t; +pub type __darwin_sigset_t = __uint32_t; +pub type __darwin_suseconds_t = __int32_t; +pub type __darwin_uid_t = __uint32_t; +pub type __darwin_useconds_t = __uint32_t; +pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; +pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __darwin_pthread_handler_rec { + pub __routine: ::std::option::Option, + pub __arg: *mut ::std::os::raw::c_void, + pub __next: *mut __darwin_pthread_handler_rec, +} +#[test] +fn bindgen_test_layout___darwin_pthread_handler_rec() { + const UNINIT: ::std::mem::MaybeUninit<__darwin_pthread_handler_rec> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__darwin_pthread_handler_rec>(), + 24usize, + concat!("Size of: ", stringify!(__darwin_pthread_handler_rec)) + ); + assert_eq!( + ::std::mem::align_of::<__darwin_pthread_handler_rec>(), + 8usize, + concat!("Alignment of ", stringify!(__darwin_pthread_handler_rec)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__routine) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__darwin_pthread_handler_rec), + "::", + stringify!(__routine) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__arg) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(__darwin_pthread_handler_rec), + "::", + stringify!(__arg) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__next) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(__darwin_pthread_handler_rec), + "::", + stringify!(__next) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_attr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_attr_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_attr_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_attr_t>(), + 64usize, + concat!("Size of: ", stringify!(_opaque_pthread_attr_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_attr_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_attr_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_attr_t), "::", stringify!(__sig)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_attr_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_cond_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 40usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_cond_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_cond_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_cond_t>(), + 48usize, + concat!("Size of: ", stringify!(_opaque_pthread_cond_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_cond_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_cond_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_cond_t), "::", stringify!(__sig)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_cond_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_condattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_condattr_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_condattr_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_condattr_t>(), + 16usize, + concat!("Size of: ", stringify!(_opaque_pthread_condattr_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_condattr_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_condattr_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_condattr_t), + "::", + stringify!(__sig) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_condattr_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_mutex_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 56usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_mutex_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_mutex_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_mutex_t>(), + 64usize, + concat!("Size of: ", stringify!(_opaque_pthread_mutex_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_mutex_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_mutex_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_mutex_t), "::", stringify!(__sig)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_mutex_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_mutexattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_mutexattr_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_mutexattr_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_mutexattr_t>(), + 16usize, + concat!("Size of: ", stringify!(_opaque_pthread_mutexattr_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_mutexattr_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_mutexattr_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_mutexattr_t), + "::", + stringify!(__sig) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_mutexattr_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_once_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 8usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_once_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_once_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_once_t>(), + 16usize, + concat!("Size of: ", stringify!(_opaque_pthread_once_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_once_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_once_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_once_t), "::", stringify!(__sig)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_once_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_rwlock_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 192usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_rwlock_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_rwlock_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_rwlock_t>(), + 200usize, + concat!("Size of: ", stringify!(_opaque_pthread_rwlock_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_rwlock_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_rwlock_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_rwlock_t), "::", stringify!(__sig)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_rwlock_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_rwlockattr_t { + pub __sig: ::std::os::raw::c_long, + pub __opaque: [::std::os::raw::c_char; 16usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_rwlockattr_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_rwlockattr_t> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_rwlockattr_t>(), + 24usize, + concat!("Size of: ", stringify!(_opaque_pthread_rwlockattr_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_rwlockattr_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_rwlockattr_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_rwlockattr_t), + "::", + stringify!(__sig) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_rwlockattr_t), + "::", + stringify!(__opaque) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _opaque_pthread_t { + pub __sig: ::std::os::raw::c_long, + pub __cleanup_stack: *mut __darwin_pthread_handler_rec, + pub __opaque: [::std::os::raw::c_char; 8176usize], +} +#[test] +fn bindgen_test_layout__opaque_pthread_t() { + const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_opaque_pthread_t>(), + 8192usize, + concat!("Size of: ", stringify!(_opaque_pthread_t)) + ); + assert_eq!( + ::std::mem::align_of::<_opaque_pthread_t>(), + 8usize, + concat!("Alignment of ", stringify!(_opaque_pthread_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_t), "::", stringify!(__sig)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__cleanup_stack) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(_opaque_pthread_t), + "::", + stringify!(__cleanup_stack) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(_opaque_pthread_t), "::", stringify!(__opaque)) + ); +} +pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; +pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; +pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; +pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; +pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; +pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; +pub type __darwin_pthread_once_t = _opaque_pthread_once_t; +pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; +pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; +pub type __darwin_pthread_t = *mut _opaque_pthread_t; +pub type u_int8_t = ::std::os::raw::c_uchar; +pub type u_int16_t = ::std::os::raw::c_ushort; +pub type u_int32_t = ::std::os::raw::c_uint; +pub type u_int64_t = ::std::os::raw::c_ulonglong; +pub type register_t = i64; +pub type user_addr_t = u_int64_t; +pub type user_size_t = u_int64_t; +pub type user_ssize_t = i64; +pub type user_long_t = i64; +pub type user_ulong_t = u_int64_t; +pub type user_time_t = i64; +pub type user_off_t = i64; +pub type syscall_arg_t = u_int64_t; +pub type intmax_t = ::std::os::raw::c_long; +pub type uintmax_t = ::std::os::raw::c_ulong; +#[doc = " @brief Opaque multi-modal Database handle.\n @see `ukv_database_free()`.\n\n Properties:\n - Thread safety: Safe to use across threads after open and before free.\n - Lifetime: Must live longer than all the transactions.\n\n ## Concurrency\n\n In embedded setup this handle manages the lifetime of the database.\n In that case user must guarantee, that concurrent processes won't be\n opening the same database (generally same directory).\n\n In standalone \"client-server\" setup, manages the lifetime of the \"client\".\n Many concurrent clients can be connecting to the same server from the same\n process.\n\n ## Collections\n\n Every database always has at least one collection - the `::ukv_collection_main_k`.\n That one has no name and can't be deleted. Others are referenced by names.\n The same database can have many collections, of different modalities:\n - Binary Large Objects or BLOBs.\n - Hierarchical documents, like JSONs, BSONs, MessagePacks.\n - Discrete labeled and potentially directed Graphs.\n - Paths or collections of string keys.\n\n ## Choosing the Engine\n\n Dynamic dispatch of engines isn't yet supported.\n\n ## CAP Theorem\n\n Distributed engines are not yet supported."] +pub type ukv_database_t = *mut ::std::os::raw::c_void; +#[doc = " @brief Opaque Transaction handle.\n @see `ukv_transaction_free()`.\n @see https://unum.cloud/ukv/c#transactions\n\n Allows ACID-ly grouping operations across different collections and even modalities.\n This means, that the same transaction might be:\n - inserting a blob of media data into a collection of images.\n - updating users metadata in a documents collection to reference new avatar.\n - introducing links between the user and other in a graph collection...\n and all of the operations here either succeed or fail together. DBMS will\n do the synchronization heavy-lifting, so you don't have to.\n\n Properties:\n - Thread safety: None.\n - Lifetime: Must be freed before the @c ukv_database_t is closed.\n - Concurrency Control: Optimistic."] +pub type ukv_transaction_t = *mut ::std::os::raw::c_void; +#[doc = " @brief Some unique integer identifier of a collection.\n A @c ukv_database_t database can have many of those,\n but never with repeating names or identifiers.\n Those identifiers are not guaranteed to remain the same\n between DBMS restarts."] +pub type ukv_collection_t = u64; +#[doc = " @brief The unique identifier of any value within a single collection."] +pub type ukv_key_t = i64; +#[doc = " @brief The elementary binary piece of any value."] +pub type ukv_byte_t = u8; +#[doc = " @brief Single-precisions floating-point number."] +pub type ukv_float_t = f32; +#[doc = " @brief The elementary piece of any string, like collection name."] +pub type ukv_char_t = ::std::os::raw::c_char; +#[doc = " @brief The length of any value in the DB."] +pub type ukv_length_t = u32; +#[doc = " @brief Pointer-sized integer type."] +pub type ukv_size_t = u64; +#[doc = " @brief The smallest possible \"bitset\" type, storing eight zeros or ones."] +pub type ukv_octet_t = u8; +#[doc = " @brief Monotonically increasing unique identifier that reflects the order of applied transactions"] +pub type ukv_sequence_number_t = u64; +#[doc = " @brief Owning error message string.\n If not null, must be deallocated via `ukv_error_free()`."] +pub type ukv_error_t = *const ::std::os::raw::c_char; +#[doc = " @brief Non-owning string reference.\n Always provided by user and we don't participate\n in its lifetime management in any way."] +pub type ukv_str_view_t = *const ::std::os::raw::c_char; +pub type ukv_str_span_t = *mut ::std::os::raw::c_char; +#[doc = " @brief Temporary memory handle, used mostly for read requests.\n It's allocated, resized and deallocated only by UKV itself.\n Once done, must be deallocated with `ukv_arena_free()`.\n @see `ukv_arena_free()`."] +pub type ukv_arena_t = *mut ::std::os::raw::c_void; +pub type ukv_bytes_ptr_t = *mut u8; +pub type ukv_bytes_cptr_t = *const u8; +pub type ukv_callback_payload_t = *mut ::std::os::raw::c_void; +pub type ukv_callback_t = ::std::option::Option; +pub const ukv_options_t_ukv_options_default_k: ukv_options_t = 0; +#[doc = " @brief Forces absolute consistency on the write operations\n flushing all the data to disk after each write. It's usage\n may cause severe performance degradation in some implementations.\n Yet the users must be warned, that modern IO drivers still often\n can't guarantee that everything will reach the disk."] +pub const ukv_options_t_ukv_option_write_flush_k: ukv_options_t = 2; +#[doc = " @brief When reading from a transaction, we track the requested keys.\n If the requested key was updated since the read, the transaction\n will fail on commit or prior to that. This option disables collision\n detection on separate parts of transactional reads and writes."] +pub const ukv_options_t_ukv_option_transaction_dont_watch_k: ukv_options_t = 4; +#[doc = " @brief On every API call, the arena is cleared for reuse.\n If the arguments of the function are results of another UKV call,\n you can use this flag to avoid discarding the memory."] +pub const ukv_options_t_ukv_option_dont_discard_memory_k: ukv_options_t = 16; +#[doc = " @brief Will output data into shared memory, not the one privately\n to do further transformations without any copies.\n Is relevant for standalone distributions used with drivers supporting\n Apache Arrow buffers or standardized Tensor representations."] +pub const ukv_options_t_ukv_option_read_shared_memory_k: ukv_options_t = 32; +#[doc = " @brief When set, the underlying engine may avoid strict keys ordering\n and may include irrelevant (deleted & duplicate) keys in order to maximize\n throughput. The purpose is not accelerating the `ukv_scan()`, but the\n following `ukv_read()`. Generally used for Machine Learning applications."] +pub const ukv_options_t_ukv_option_scan_bulk_k: ukv_options_t = 0; +pub type ukv_options_t = ::std::os::raw::c_uint; +#[doc = " @brief Remove the handle and all of the contents."] +pub const ukv_drop_mode_t_ukv_drop_keys_vals_handle_k: ukv_drop_mode_t = 0; +#[doc = " @brief Remove keys and values, but keep the collection."] +pub const ukv_drop_mode_t_ukv_drop_keys_vals_k: ukv_drop_mode_t = 1; +#[doc = " @brief Clear the values, but keep the keys."] +pub const ukv_drop_mode_t_ukv_drop_vals_k: ukv_drop_mode_t = 2; +#[doc = " @brief The \"mode\" of collection removal."] +pub type ukv_drop_mode_t = ::std::os::raw::c_uint; +extern "C" { + #[doc = " @brief The handle to the default nameless collection.\n It exists from start, doesn't have to be created and can't be fully dropped.\n Only `::ukv_drop_keys_vals_k` and `::ukv_drop_vals_k` apply to it."] + pub static ukv_collection_main_k: ukv_collection_t; +} +extern "C" { + pub static ukv_length_missing_k: ukv_length_t; +} +extern "C" { + pub static ukv_key_unknown_k: ukv_key_t; +} +extern "C" { + pub static ukv_supports_transactions_k: bool; +} +extern "C" { + pub static ukv_supports_named_collections_k: bool; +} +extern "C" { + pub static ukv_supports_snapshots_k: bool; +} +#[doc = " @brief Opens the underlying Key-Value Store.\n @see `ukv_database_init()`.\n\n Depending on the selected distribution can be any of:\n\n - embedded persistent transactional KVS\n - embedded in-memory transactional KVS\n - remote persistent transactional KVS\n - remote in-memory transactional KVS"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_database_init_t { + #[doc = " @brief Configuration parameter for the DBMS.\n\n For embedded distributions should be the root directory,\n under which the DBMS and it's files will be organized.\n\n Recommendations:\n - UMem: empty or `/var/lib/ukv/umem/` for eventually persistent.\n - RocksDB: `/var/lib/ukv/rocksdb/` optionally storing `config_rocksdb.ini`.\n - LevelDB: `/var/lib/ukv/leveldb/` optionally storing `config_leveldb.json`.\n - Flight API Client: `grpc://0.0.0.0:38709`."] + pub config: ukv_str_view_t, + #[doc = " @brief A pointer to the opened KVS, unless `error` is filled."] + pub db: *mut ukv_database_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, +} +#[test] +fn bindgen_test_layout_ukv_database_init_t() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(ukv_database_init_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_database_init_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).config) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_database_init_t), "::", stringify!(config)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_database_init_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(ukv_database_init_t), "::", stringify!(error)) + ); +} +extern "C" { + #[doc = " @brief Opens the underlying Key-Value Store.\n @see `ukv_database_init()`."] + pub fn ukv_database_init(arg1: *mut ukv_database_init_t); +} +#[doc = " @brief Lists all named collections in the DB.\n @see `ukv_collection_list()`.\n\n Retrieves a list of collection IDs & names in a NULL-delimited form.\n The default nameless collection won't be described in any form, as its always\n present. This is the only collection-management operation that can be performed\n on a DB state snapshot, and not just on the HEAD state."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_collection_list_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Pointer to exported error message.\n If not NULL, must be deallocated with `ukv_error_free()`."] + pub error: *mut ukv_error_t, + #[doc = " @brief The snapshot in which the retrieval will be conducted.\n @see `ukv_transaction_init()`, `ukv_transaction_commit()`, `ukv_transaction_free()`."] + pub transaction: ukv_transaction_t, + #[doc = " @brief Reusable memory handle.\n @see `ukv_arena_free()`."] + pub arena: *mut ukv_arena_t, + #[doc = " @brief Listing options.\n\n Possible values:\n - `::ukv_option_dont_discard_memory_k`: Won't reset the `arena` before the operation begins."] + pub options: ukv_options_t, + #[doc = " @brief Number of present collections."] + pub count: *mut ukv_size_t, + #[doc = " @brief Handles of all the collections in same order as `names`."] + pub ids: *mut *mut ukv_collection_t, + #[doc = " @brief Offsets of separate strings in the `names` tape."] + pub offsets: *mut *mut ukv_length_t, + #[doc = " @brief NULL-terminated collection names tape in same order as `ids`."] + pub names: *mut *mut ukv_char_t, +} +#[test] +fn bindgen_test_layout_ukv_collection_list_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 72usize, + concat!("Size of: ", stringify!(ukv_collection_list_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_collection_list_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(ukv_collection_list_t), + "::", + stringify!(transaction) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).arena) as usize - ptr as usize }, + 24usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(arena)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, + 32usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(options)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).count) as usize - ptr as usize }, + 40usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(count)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).ids) as usize - ptr as usize }, + 48usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(ids)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).offsets) as usize - ptr as usize }, + 56usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(offsets)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).names) as usize - ptr as usize }, + 64usize, + concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(names)) + ); +} +extern "C" { + #[doc = " @brief Lists all named collections in the DB.\n @see `ukv_collection_list_t`."] + pub fn ukv_collection_list(arg1: *mut ukv_collection_list_t); +} +#[doc = " @brief Creates a new uniquely named collection in the DB.\n @see `ukv_collection_create()`.\n\n This function may never be called, as the default nameless collection\n always exists and can be addressed via `::ukv_collection_main_k`.\n You can \"re-create\" an empty collection with a new config."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_collection_create_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, + #[doc = " @brief Unique name for the new collection."] + pub name: ukv_str_view_t, + #[doc = " @brief Optional configuration JSON string."] + pub config: ukv_str_view_t, + #[doc = " @brief Output for the collection handle."] + pub id: *mut ukv_collection_t, +} +#[test] +fn bindgen_test_layout_ukv_collection_create_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(ukv_collection_create_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_collection_create_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(name)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).config) as usize - ptr as usize }, + 24usize, + concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(config)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, + 32usize, + concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(id)) + ); +} +extern "C" { + #[doc = " @brief Creates a new uniquely named collection in the DB.\n @see `ukv_collection_create_t`."] + pub fn ukv_collection_create(arg1: *mut ukv_collection_create_t); +} +#[doc = " @brief Removes or clears an existing collection.\n @see `ukv_collection_drop()`.\n\n Removes a collection or its contents depending on `mode`.\n The default nameless collection can't be removed, only cleared."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_collection_drop_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, + #[doc = " @brief Existing collection handle."] + pub id: ukv_collection_t, + #[doc = " @brief Controls if values, pairs or the whole collection must be dropped."] + pub mode: ukv_drop_mode_t, +} +#[test] +fn bindgen_test_layout_ukv_collection_drop_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(ukv_collection_drop_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_collection_drop_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(id)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).mode) as usize - ptr as usize }, + 24usize, + concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(mode)) + ); +} +extern "C" { + #[doc = " @brief Removes or clears an existing collection.\n @see `ukv_collection_drop_t`."] + pub fn ukv_collection_drop(arg1: *mut ukv_collection_drop_t); +} +#[doc = " @brief Free-form communication tunnel with the underlying engine.\n @see `ukv_database_control()`.\n\n Performs free-form queries on the DB, that may not necessarily\n have a stable API and a fixed format output. Generally, those requests\n are very expensive and shouldn't be executed in most applications.\n This is the \"kitchen-sink\" of UKV interface, similar to `fcntl` & `ioctl`.\n\n ## Possible Commands\n - \"clear\": Removes all the data from DB, while keeping collection names.\n - \"reset\": Removes all the data from DB, including collection names.\n - \"compact\": Flushes and compacts all the data in LSM-tree implementations.\n - \"info\": Metadata about the current software version, used for debugging.\n - \"usage\": Metadata about approximate collection sizes, RAM and disk usage."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_database_control_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Reusable memory handle."] + pub arena: *mut ukv_arena_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, + #[doc = " @brief The input command as a NULL-terminated string."] + pub request: ukv_str_view_t, + #[doc = " @brief The output response as a NULL-terminated string."] + pub response: *mut ukv_str_view_t, +} +#[test] +fn bindgen_test_layout_ukv_database_control_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(ukv_database_control_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_database_control_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).arena) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(arena)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).request) as usize - ptr as usize }, + 24usize, + concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(request)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).response) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(ukv_database_control_t), + "::", + stringify!(response) + ) + ); +} +extern "C" { + #[doc = " @brief Free-form communication tunnel with the underlying engine.\n @see `ukv_database_control()`."] + pub fn ukv_database_control(arg1: *mut ukv_database_control_t); +} +#[doc = " @brief Begins a new ACID transaction or resets an existing one.\n @see `ukv_transaction_init()`."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_transaction_init_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, + #[doc = " @brief Transaction options.\n\n Possible values:\n - `::ukv_option_dont_discard_memory_k`: Won't reset the `arena` before the operation begins."] + pub options: ukv_options_t, + #[doc = " @brief In-out transaction handle."] + pub transaction: *mut ukv_transaction_t, +} +#[test] +fn bindgen_test_layout_ukv_transaction_init_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(ukv_transaction_init_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_transaction_init_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_transaction_init_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_transaction_init_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, + 16usize, + concat!("Offset of field: ", stringify!(ukv_transaction_init_t), "::", stringify!(options)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_init_t), + "::", + stringify!(transaction) + ) + ); +} +extern "C" { + #[doc = " @brief Begins a new ACID transaction or resets an existing one.\n @see `ukv_transaction_init_t`."] + pub fn ukv_transaction_init(arg1: *mut ukv_transaction_init_t); +} +#[doc = " @brief Stages an ACID transaction for Two Phase Commits.\n @see `ukv_transaction_stage()`.\n\n Regardless of result, the content is preserved to allow further\n logging, serialization or retries. The underlying memory can be\n cleaned and reused by consecutive `ukv_transaction_init()` call."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_transaction_stage_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, + #[doc = " @brief Initialized transaction handle."] + pub transaction: ukv_transaction_t, + #[doc = " @brief Staging options."] + pub options: ukv_options_t, + #[doc = " @brief Optional output for the transaction stage sequence number."] + pub sequence_number: *mut ukv_sequence_number_t, +} +#[test] +fn bindgen_test_layout_ukv_transaction_stage_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(ukv_transaction_stage_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_transaction_stage_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_transaction_stage_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_transaction_stage_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_stage_t), + "::", + stringify!(transaction) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_stage_t), + "::", + stringify!(options) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sequence_number) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_stage_t), + "::", + stringify!(sequence_number) + ) + ); +} +extern "C" { + #[doc = " @brief Stages an ACID transaction for Two Phase Commits.\n @see `ukv_transaction_stage_t`."] + pub fn ukv_transaction_stage(arg1: *mut ukv_transaction_stage_t); +} +#[doc = " @brief Commits an ACID transaction.\n @see `ukv_transaction_commit()`.\n\n Regardless of result, the content is preserved to allow further\n logging, serialization or retries. The underlying memory can be\n cleaned and reused by consecutive `ukv_transaction_init()` call."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ukv_transaction_commit_t { + #[doc = " @brief Already open database instance."] + pub db: ukv_database_t, + #[doc = " @brief Pointer to exported error message."] + pub error: *mut ukv_error_t, + #[doc = " @brief Initialized transaction handle."] + pub transaction: ukv_transaction_t, + #[doc = " @brief Staging options."] + pub options: ukv_options_t, + #[doc = " @brief Optional output for the transaction commit sequence number."] + pub sequence_number: *mut ukv_sequence_number_t, +} +#[test] +fn bindgen_test_layout_ukv_transaction_commit_t() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 40usize, + concat!("Size of: ", stringify!(ukv_transaction_commit_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(ukv_transaction_commit_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(ukv_transaction_commit_t), "::", stringify!(db)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, + 8usize, + concat!("Offset of field: ", stringify!(ukv_transaction_commit_t), "::", stringify!(error)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_commit_t), + "::", + stringify!(transaction) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_commit_t), + "::", + stringify!(options) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).sequence_number) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(ukv_transaction_commit_t), + "::", + stringify!(sequence_number) + ) + ); +} +extern "C" { + #[doc = " @brief Commits an ACID transaction.\n @see `ukv_transaction_commit_t`."] + pub fn ukv_transaction_commit(arg1: *mut ukv_transaction_commit_t); +} +extern "C" { + #[doc = " @brief Deallocates reusable memory arenas.\n Passing NULLs is safe."] + pub fn ukv_arena_free(arg1: ukv_arena_t); +} +extern "C" { + #[doc = " @brief Resets the transaction and deallocates the underlying memory.\n Passing NULLs is safe."] + pub fn ukv_transaction_free(arg1: ukv_transaction_t); +} +extern "C" { + #[doc = " @brief Closes the DB and deallocates used memory.\n The database would still persist on disk.\n Passing NULLs is safe."] + pub fn ukv_database_free(arg1: ukv_database_t); +} +extern "C" { + #[doc = " @brief Deallocates error messages.\n Passing NULLs is safe."] + pub fn ukv_error_free(arg1: ukv_error_t); +} +pub type __builtin_va_list = *mut ::std::os::raw::c_char; diff --git a/rust/src/ukv/mod.rs b/rust/src/ukv/mod.rs new file mode 100644 index 000000000..90c70dcc2 --- /dev/null +++ b/rust/src/ukv/mod.rs @@ -0,0 +1 @@ +pub mod bindings; diff --git a/rust/wrapper.h b/rust/wrapper.h new file mode 100644 index 000000000..04cc4450d --- /dev/null +++ b/rust/wrapper.h @@ -0,0 +1 @@ +#include "../include/ukv/db.h" \ No newline at end of file From f7778fe7e10d9be39be8970bcd02ede7b9bf7e5b Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Fri, 27 Jan 2023 09:40:19 +0400 Subject: [PATCH 2/9] Update: Cargo build script and struct impls - Implemented std::default::Default for Database and cleaned up the implementation of Database::new. - Updated Cargo build script. The bindings will be generated on the fly and will be put in `OUT_DIR`. Bindings will be linked directly to the crate, without the need to keep them tracked in git. --- rust/build.rs | 11 +- rust/src/lib.rs | 65 +- rust/src/ukv/bindings.rs | 1216 -------------------------------------- rust/src/ukv/mod.rs | 1 - 4 files changed, 46 insertions(+), 1247 deletions(-) delete mode 100644 rust/src/ukv/bindings.rs delete mode 100644 rust/src/ukv/mod.rs diff --git a/rust/build.rs b/rust/build.rs index a5ffb27fe..06917f867 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -1,8 +1,9 @@ extern crate bindgen; +use std::env::var; use std::path::PathBuf; -fn main() { +fn main() -> Result<(), Box> { // Tell cargo to invalidate the built crate whenever the wrapper changes println!("cargo:rerun-if-changed=wrapper.h"); // Tell cargo to look for shared libraries in the specified directory @@ -14,10 +15,10 @@ fn main() { .header("./wrapper.h") .detect_include_paths(true) .parse_callbacks(Box::new(bindgen::CargoCallbacks)) - .generate() - .expect("Unable to generate bindings"); + .generate()?; // Write the bindings to the $OUT_DIR/bindings.rs file. - let out_path = PathBuf::from("./src/ukv"); - bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings!"); + let out_path = PathBuf::from(var("OUT_DIR")?); + bindings.write_to_file(out_path.join("bindings.rs"))?; + Ok(()) } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 93a132cce..802baf5f8 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,37 +1,53 @@ -mod error; -mod ukv; +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] -use std::ffi::CString; +mod error; -include!("../src/ukv/bindings.rs"); +pub mod bindings { + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +} -type UkvDatabaseInitType = ukv_database_init_t; +type UkvDatabaseInitType = bindings::ukv_database_init_t; pub struct Database { - db: UkvDatabaseInitType, + pub db: UkvDatabaseInitType, +} + +impl Default for Database { + fn default() -> Self { + let config: *const _ = std::ffi::CString::default().as_ptr(); + let error: *mut _ = &mut CString::default().as_ptr(); + let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; + let mut db = UkvDatabaseInitType { + error, + config, + db: void_fn as _, + }; + + unsafe { bindings::ukv_database_init(&mut db) }; + Self { + db, + } + } } impl Database { /// Open a new database using ukv_database_init() - pub fn new() -> Result { - let c_str = CString::default(); - let config: *const std::ffi::c_char = c_str.as_ptr(); - let error: *mut *const std::ffi::c_char = &mut c_str.as_ptr(); - let mut void_fn = &mut () as *mut _ as *mut std::ffi::c_void; - let db_ptr = &mut void_fn; - let mut database = UkvDatabaseInitType { - config, - db: db_ptr, + pub fn new() -> Self { + let config: *const _ = std::ffi::CString::default().as_ptr(); + let error: *mut _ = &mut CString::default().as_ptr(); + let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; + let mut db = UkvDatabaseInitType { error, - }; - // Calling C++ function generated from bindgen - unsafe { - ukv_database_init(&mut database); + config, + db: void_fn as _, }; - Ok(Self { - db: database, - }) + unsafe { bindings::ukv_database_init(&mut db) }; + Self { + db, + } } pub fn contains_key() {} @@ -39,9 +55,8 @@ impl Database { // Close a database using ukv_database_free() pub fn close() -> Result<(), error::DataStoreError> { let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; - unsafe { - ukv_database_free(void_fn); - }; + unsafe { bindings::ukv_database_free(void_fn) }; + Ok(()) } } diff --git a/rust/src/ukv/bindings.rs b/rust/src/ukv/bindings.rs deleted file mode 100644 index c317670ac..000000000 --- a/rust/src/ukv/bindings.rs +++ /dev/null @@ -1,1216 +0,0 @@ -/* automatically generated by rust-bindgen 0.63.0 */ - -pub const __GNUC_VA_LIST: u32 = 1; -pub const true_: u32 = 1; -pub const false_: u32 = 0; -pub const __bool_true_false_are_defined: u32 = 1; -pub const __WORDSIZE: u32 = 64; -pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1; -pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; -pub const __DARWIN_ONLY_VERS_1050: u32 = 1; -pub const __DARWIN_UNIX03: u32 = 1; -pub const __DARWIN_64_BIT_INO_T: u32 = 1; -pub const __DARWIN_VERS_1050: u32 = 1; -pub const __DARWIN_NON_CANCELABLE: u32 = 0; -pub const __DARWIN_SUF_EXTSN: &[u8; 14usize] = b"$DARWIN_EXTSN\0"; -pub const __DARWIN_C_ANSI: u32 = 4096; -pub const __DARWIN_C_FULL: u32 = 900000; -pub const __DARWIN_C_LEVEL: u32 = 900000; -pub const __STDC_WANT_LIB_EXT1__: u32 = 1; -pub const __DARWIN_NO_LONG_LONG: u32 = 0; -pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1; -pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1; -pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3; -pub const __PTHREAD_SIZE__: u32 = 8176; -pub const __PTHREAD_ATTR_SIZE__: u32 = 56; -pub const __PTHREAD_MUTEXATTR_SIZE__: u32 = 8; -pub const __PTHREAD_MUTEX_SIZE__: u32 = 56; -pub const __PTHREAD_CONDATTR_SIZE__: u32 = 8; -pub const __PTHREAD_COND_SIZE__: u32 = 40; -pub const __PTHREAD_ONCE_SIZE__: u32 = 8; -pub const __PTHREAD_RWLOCK_SIZE__: u32 = 192; -pub const __PTHREAD_RWLOCKATTR_SIZE__: u32 = 16; -pub const INT8_MAX: u32 = 127; -pub const INT16_MAX: u32 = 32767; -pub const INT32_MAX: u32 = 2147483647; -pub const INT64_MAX: u64 = 9223372036854775807; -pub const INT8_MIN: i32 = -128; -pub const INT16_MIN: i32 = -32768; -pub const INT32_MIN: i32 = -2147483648; -pub const INT64_MIN: i64 = -9223372036854775808; -pub const UINT8_MAX: u32 = 255; -pub const UINT16_MAX: u32 = 65535; -pub const UINT32_MAX: u32 = 4294967295; -pub const UINT64_MAX: i32 = -1; -pub const INT_LEAST8_MIN: i32 = -128; -pub const INT_LEAST16_MIN: i32 = -32768; -pub const INT_LEAST32_MIN: i32 = -2147483648; -pub const INT_LEAST64_MIN: i64 = -9223372036854775808; -pub const INT_LEAST8_MAX: u32 = 127; -pub const INT_LEAST16_MAX: u32 = 32767; -pub const INT_LEAST32_MAX: u32 = 2147483647; -pub const INT_LEAST64_MAX: u64 = 9223372036854775807; -pub const UINT_LEAST8_MAX: u32 = 255; -pub const UINT_LEAST16_MAX: u32 = 65535; -pub const UINT_LEAST32_MAX: u32 = 4294967295; -pub const UINT_LEAST64_MAX: i32 = -1; -pub const INT_FAST8_MIN: i32 = -128; -pub const INT_FAST16_MIN: i32 = -32768; -pub const INT_FAST32_MIN: i32 = -2147483648; -pub const INT_FAST64_MIN: i64 = -9223372036854775808; -pub const INT_FAST8_MAX: u32 = 127; -pub const INT_FAST16_MAX: u32 = 32767; -pub const INT_FAST32_MAX: u32 = 2147483647; -pub const INT_FAST64_MAX: u64 = 9223372036854775807; -pub const UINT_FAST8_MAX: u32 = 255; -pub const UINT_FAST16_MAX: u32 = 65535; -pub const UINT_FAST32_MAX: u32 = 4294967295; -pub const UINT_FAST64_MAX: i32 = -1; -pub const INTPTR_MAX: u64 = 9223372036854775807; -pub const INTPTR_MIN: i64 = -9223372036854775808; -pub const UINTPTR_MAX: i32 = -1; -pub const SIZE_MAX: i32 = -1; -pub const RSIZE_MAX: i32 = -1; -pub const WINT_MIN: i32 = -2147483648; -pub const WINT_MAX: u32 = 2147483647; -pub const SIG_ATOMIC_MIN: i32 = -2147483648; -pub const SIG_ATOMIC_MAX: u32 = 2147483647; -pub type va_list = __builtin_va_list; -pub type __gnuc_va_list = __builtin_va_list; -pub type wchar_t = ::std::os::raw::c_int; -pub type max_align_t = f64; -pub type int_least8_t = i8; -pub type int_least16_t = i16; -pub type int_least32_t = i32; -pub type int_least64_t = i64; -pub type uint_least8_t = u8; -pub type uint_least16_t = u16; -pub type uint_least32_t = u32; -pub type uint_least64_t = u64; -pub type int_fast8_t = i8; -pub type int_fast16_t = i16; -pub type int_fast32_t = i32; -pub type int_fast64_t = i64; -pub type uint_fast8_t = u8; -pub type uint_fast16_t = u16; -pub type uint_fast32_t = u32; -pub type uint_fast64_t = u64; -pub type __int8_t = ::std::os::raw::c_schar; -pub type __uint8_t = ::std::os::raw::c_uchar; -pub type __int16_t = ::std::os::raw::c_short; -pub type __uint16_t = ::std::os::raw::c_ushort; -pub type __int32_t = ::std::os::raw::c_int; -pub type __uint32_t = ::std::os::raw::c_uint; -pub type __int64_t = ::std::os::raw::c_longlong; -pub type __uint64_t = ::std::os::raw::c_ulonglong; -pub type __darwin_intptr_t = ::std::os::raw::c_long; -pub type __darwin_natural_t = ::std::os::raw::c_uint; -pub type __darwin_ct_rune_t = ::std::os::raw::c_int; -#[repr(C)] -#[derive(Copy, Clone)] -pub union __mbstate_t { - pub __mbstate8: [::std::os::raw::c_char; 128usize], - pub _mbstateL: ::std::os::raw::c_longlong, -} -#[test] -fn bindgen_test_layout___mbstate_t() { - const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<__mbstate_t>(), - 128usize, - concat!("Size of: ", stringify!(__mbstate_t)) - ); - assert_eq!( - ::std::mem::align_of::<__mbstate_t>(), - 8usize, - concat!("Alignment of ", stringify!(__mbstate_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__mbstate8) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(__mbstate_t), "::", stringify!(__mbstate8)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr)._mbstateL) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(__mbstate_t), "::", stringify!(_mbstateL)) - ); -} -pub type __darwin_mbstate_t = __mbstate_t; -pub type __darwin_ptrdiff_t = ::std::os::raw::c_long; -pub type __darwin_size_t = ::std::os::raw::c_ulong; -pub type __darwin_va_list = __builtin_va_list; -pub type __darwin_wchar_t = ::std::os::raw::c_int; -pub type __darwin_rune_t = __darwin_wchar_t; -pub type __darwin_wint_t = ::std::os::raw::c_int; -pub type __darwin_clock_t = ::std::os::raw::c_ulong; -pub type __darwin_socklen_t = __uint32_t; -pub type __darwin_ssize_t = ::std::os::raw::c_long; -pub type __darwin_time_t = ::std::os::raw::c_long; -pub type __darwin_blkcnt_t = __int64_t; -pub type __darwin_blksize_t = __int32_t; -pub type __darwin_dev_t = __int32_t; -pub type __darwin_fsblkcnt_t = ::std::os::raw::c_uint; -pub type __darwin_fsfilcnt_t = ::std::os::raw::c_uint; -pub type __darwin_gid_t = __uint32_t; -pub type __darwin_id_t = __uint32_t; -pub type __darwin_ino64_t = __uint64_t; -pub type __darwin_ino_t = __darwin_ino64_t; -pub type __darwin_mach_port_name_t = __darwin_natural_t; -pub type __darwin_mach_port_t = __darwin_mach_port_name_t; -pub type __darwin_mode_t = __uint16_t; -pub type __darwin_off_t = __int64_t; -pub type __darwin_pid_t = __int32_t; -pub type __darwin_sigset_t = __uint32_t; -pub type __darwin_suseconds_t = __int32_t; -pub type __darwin_uid_t = __uint32_t; -pub type __darwin_useconds_t = __uint32_t; -pub type __darwin_uuid_t = [::std::os::raw::c_uchar; 16usize]; -pub type __darwin_uuid_string_t = [::std::os::raw::c_char; 37usize]; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __darwin_pthread_handler_rec { - pub __routine: ::std::option::Option, - pub __arg: *mut ::std::os::raw::c_void, - pub __next: *mut __darwin_pthread_handler_rec, -} -#[test] -fn bindgen_test_layout___darwin_pthread_handler_rec() { - const UNINIT: ::std::mem::MaybeUninit<__darwin_pthread_handler_rec> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<__darwin_pthread_handler_rec>(), - 24usize, - concat!("Size of: ", stringify!(__darwin_pthread_handler_rec)) - ); - assert_eq!( - ::std::mem::align_of::<__darwin_pthread_handler_rec>(), - 8usize, - concat!("Alignment of ", stringify!(__darwin_pthread_handler_rec)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__routine) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(__darwin_pthread_handler_rec), - "::", - stringify!(__routine) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__arg) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(__darwin_pthread_handler_rec), - "::", - stringify!(__arg) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__next) as usize - ptr as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(__darwin_pthread_handler_rec), - "::", - stringify!(__next) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_attr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 56usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_attr_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_attr_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_attr_t>(), - 64usize, - concat!("Size of: ", stringify!(_opaque_pthread_attr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_attr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_attr_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_attr_t), "::", stringify!(__sig)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_attr_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_cond_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 40usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_cond_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_cond_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_cond_t>(), - 48usize, - concat!("Size of: ", stringify!(_opaque_pthread_cond_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_cond_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_cond_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_cond_t), "::", stringify!(__sig)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_cond_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_condattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_condattr_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_condattr_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_condattr_t>(), - 16usize, - concat!("Size of: ", stringify!(_opaque_pthread_condattr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_condattr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_condattr_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_condattr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_condattr_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_mutex_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 56usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_mutex_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_mutex_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_mutex_t>(), - 64usize, - concat!("Size of: ", stringify!(_opaque_pthread_mutex_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_mutex_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_mutex_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_mutex_t), "::", stringify!(__sig)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutex_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_mutexattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_mutexattr_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_mutexattr_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_mutexattr_t>(), - 16usize, - concat!("Size of: ", stringify!(_opaque_pthread_mutexattr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_mutexattr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_mutexattr_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutexattr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_mutexattr_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_once_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 8usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_once_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_once_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_once_t>(), - 16usize, - concat!("Size of: ", stringify!(_opaque_pthread_once_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_once_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_once_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_once_t), "::", stringify!(__sig)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_once_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_rwlock_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 192usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_rwlock_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_rwlock_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_rwlock_t>(), - 200usize, - concat!("Size of: ", stringify!(_opaque_pthread_rwlock_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_rwlock_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_rwlock_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_rwlock_t), "::", stringify!(__sig)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlock_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_rwlockattr_t { - pub __sig: ::std::os::raw::c_long, - pub __opaque: [::std::os::raw::c_char; 16usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_rwlockattr_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_rwlockattr_t> = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_rwlockattr_t>(), - 24usize, - concat!("Size of: ", stringify!(_opaque_pthread_rwlockattr_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_rwlockattr_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_rwlockattr_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlockattr_t), - "::", - stringify!(__sig) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_rwlockattr_t), - "::", - stringify!(__opaque) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _opaque_pthread_t { - pub __sig: ::std::os::raw::c_long, - pub __cleanup_stack: *mut __darwin_pthread_handler_rec, - pub __opaque: [::std::os::raw::c_char; 8176usize], -} -#[test] -fn bindgen_test_layout__opaque_pthread_t() { - const UNINIT: ::std::mem::MaybeUninit<_opaque_pthread_t> = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::<_opaque_pthread_t>(), - 8192usize, - concat!("Size of: ", stringify!(_opaque_pthread_t)) - ); - assert_eq!( - ::std::mem::align_of::<_opaque_pthread_t>(), - 8usize, - concat!("Alignment of ", stringify!(_opaque_pthread_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__sig) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_t), "::", stringify!(__sig)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__cleanup_stack) as usize - ptr as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_opaque_pthread_t), - "::", - stringify!(__cleanup_stack) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).__opaque) as usize - ptr as usize }, - 16usize, - concat!("Offset of field: ", stringify!(_opaque_pthread_t), "::", stringify!(__opaque)) - ); -} -pub type __darwin_pthread_attr_t = _opaque_pthread_attr_t; -pub type __darwin_pthread_cond_t = _opaque_pthread_cond_t; -pub type __darwin_pthread_condattr_t = _opaque_pthread_condattr_t; -pub type __darwin_pthread_key_t = ::std::os::raw::c_ulong; -pub type __darwin_pthread_mutex_t = _opaque_pthread_mutex_t; -pub type __darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t; -pub type __darwin_pthread_once_t = _opaque_pthread_once_t; -pub type __darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t; -pub type __darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t; -pub type __darwin_pthread_t = *mut _opaque_pthread_t; -pub type u_int8_t = ::std::os::raw::c_uchar; -pub type u_int16_t = ::std::os::raw::c_ushort; -pub type u_int32_t = ::std::os::raw::c_uint; -pub type u_int64_t = ::std::os::raw::c_ulonglong; -pub type register_t = i64; -pub type user_addr_t = u_int64_t; -pub type user_size_t = u_int64_t; -pub type user_ssize_t = i64; -pub type user_long_t = i64; -pub type user_ulong_t = u_int64_t; -pub type user_time_t = i64; -pub type user_off_t = i64; -pub type syscall_arg_t = u_int64_t; -pub type intmax_t = ::std::os::raw::c_long; -pub type uintmax_t = ::std::os::raw::c_ulong; -#[doc = " @brief Opaque multi-modal Database handle.\n @see `ukv_database_free()`.\n\n Properties:\n - Thread safety: Safe to use across threads after open and before free.\n - Lifetime: Must live longer than all the transactions.\n\n ## Concurrency\n\n In embedded setup this handle manages the lifetime of the database.\n In that case user must guarantee, that concurrent processes won't be\n opening the same database (generally same directory).\n\n In standalone \"client-server\" setup, manages the lifetime of the \"client\".\n Many concurrent clients can be connecting to the same server from the same\n process.\n\n ## Collections\n\n Every database always has at least one collection - the `::ukv_collection_main_k`.\n That one has no name and can't be deleted. Others are referenced by names.\n The same database can have many collections, of different modalities:\n - Binary Large Objects or BLOBs.\n - Hierarchical documents, like JSONs, BSONs, MessagePacks.\n - Discrete labeled and potentially directed Graphs.\n - Paths or collections of string keys.\n\n ## Choosing the Engine\n\n Dynamic dispatch of engines isn't yet supported.\n\n ## CAP Theorem\n\n Distributed engines are not yet supported."] -pub type ukv_database_t = *mut ::std::os::raw::c_void; -#[doc = " @brief Opaque Transaction handle.\n @see `ukv_transaction_free()`.\n @see https://unum.cloud/ukv/c#transactions\n\n Allows ACID-ly grouping operations across different collections and even modalities.\n This means, that the same transaction might be:\n - inserting a blob of media data into a collection of images.\n - updating users metadata in a documents collection to reference new avatar.\n - introducing links between the user and other in a graph collection...\n and all of the operations here either succeed or fail together. DBMS will\n do the synchronization heavy-lifting, so you don't have to.\n\n Properties:\n - Thread safety: None.\n - Lifetime: Must be freed before the @c ukv_database_t is closed.\n - Concurrency Control: Optimistic."] -pub type ukv_transaction_t = *mut ::std::os::raw::c_void; -#[doc = " @brief Some unique integer identifier of a collection.\n A @c ukv_database_t database can have many of those,\n but never with repeating names or identifiers.\n Those identifiers are not guaranteed to remain the same\n between DBMS restarts."] -pub type ukv_collection_t = u64; -#[doc = " @brief The unique identifier of any value within a single collection."] -pub type ukv_key_t = i64; -#[doc = " @brief The elementary binary piece of any value."] -pub type ukv_byte_t = u8; -#[doc = " @brief Single-precisions floating-point number."] -pub type ukv_float_t = f32; -#[doc = " @brief The elementary piece of any string, like collection name."] -pub type ukv_char_t = ::std::os::raw::c_char; -#[doc = " @brief The length of any value in the DB."] -pub type ukv_length_t = u32; -#[doc = " @brief Pointer-sized integer type."] -pub type ukv_size_t = u64; -#[doc = " @brief The smallest possible \"bitset\" type, storing eight zeros or ones."] -pub type ukv_octet_t = u8; -#[doc = " @brief Monotonically increasing unique identifier that reflects the order of applied transactions"] -pub type ukv_sequence_number_t = u64; -#[doc = " @brief Owning error message string.\n If not null, must be deallocated via `ukv_error_free()`."] -pub type ukv_error_t = *const ::std::os::raw::c_char; -#[doc = " @brief Non-owning string reference.\n Always provided by user and we don't participate\n in its lifetime management in any way."] -pub type ukv_str_view_t = *const ::std::os::raw::c_char; -pub type ukv_str_span_t = *mut ::std::os::raw::c_char; -#[doc = " @brief Temporary memory handle, used mostly for read requests.\n It's allocated, resized and deallocated only by UKV itself.\n Once done, must be deallocated with `ukv_arena_free()`.\n @see `ukv_arena_free()`."] -pub type ukv_arena_t = *mut ::std::os::raw::c_void; -pub type ukv_bytes_ptr_t = *mut u8; -pub type ukv_bytes_cptr_t = *const u8; -pub type ukv_callback_payload_t = *mut ::std::os::raw::c_void; -pub type ukv_callback_t = ::std::option::Option; -pub const ukv_options_t_ukv_options_default_k: ukv_options_t = 0; -#[doc = " @brief Forces absolute consistency on the write operations\n flushing all the data to disk after each write. It's usage\n may cause severe performance degradation in some implementations.\n Yet the users must be warned, that modern IO drivers still often\n can't guarantee that everything will reach the disk."] -pub const ukv_options_t_ukv_option_write_flush_k: ukv_options_t = 2; -#[doc = " @brief When reading from a transaction, we track the requested keys.\n If the requested key was updated since the read, the transaction\n will fail on commit or prior to that. This option disables collision\n detection on separate parts of transactional reads and writes."] -pub const ukv_options_t_ukv_option_transaction_dont_watch_k: ukv_options_t = 4; -#[doc = " @brief On every API call, the arena is cleared for reuse.\n If the arguments of the function are results of another UKV call,\n you can use this flag to avoid discarding the memory."] -pub const ukv_options_t_ukv_option_dont_discard_memory_k: ukv_options_t = 16; -#[doc = " @brief Will output data into shared memory, not the one privately\n to do further transformations without any copies.\n Is relevant for standalone distributions used with drivers supporting\n Apache Arrow buffers or standardized Tensor representations."] -pub const ukv_options_t_ukv_option_read_shared_memory_k: ukv_options_t = 32; -#[doc = " @brief When set, the underlying engine may avoid strict keys ordering\n and may include irrelevant (deleted & duplicate) keys in order to maximize\n throughput. The purpose is not accelerating the `ukv_scan()`, but the\n following `ukv_read()`. Generally used for Machine Learning applications."] -pub const ukv_options_t_ukv_option_scan_bulk_k: ukv_options_t = 0; -pub type ukv_options_t = ::std::os::raw::c_uint; -#[doc = " @brief Remove the handle and all of the contents."] -pub const ukv_drop_mode_t_ukv_drop_keys_vals_handle_k: ukv_drop_mode_t = 0; -#[doc = " @brief Remove keys and values, but keep the collection."] -pub const ukv_drop_mode_t_ukv_drop_keys_vals_k: ukv_drop_mode_t = 1; -#[doc = " @brief Clear the values, but keep the keys."] -pub const ukv_drop_mode_t_ukv_drop_vals_k: ukv_drop_mode_t = 2; -#[doc = " @brief The \"mode\" of collection removal."] -pub type ukv_drop_mode_t = ::std::os::raw::c_uint; -extern "C" { - #[doc = " @brief The handle to the default nameless collection.\n It exists from start, doesn't have to be created and can't be fully dropped.\n Only `::ukv_drop_keys_vals_k` and `::ukv_drop_vals_k` apply to it."] - pub static ukv_collection_main_k: ukv_collection_t; -} -extern "C" { - pub static ukv_length_missing_k: ukv_length_t; -} -extern "C" { - pub static ukv_key_unknown_k: ukv_key_t; -} -extern "C" { - pub static ukv_supports_transactions_k: bool; -} -extern "C" { - pub static ukv_supports_named_collections_k: bool; -} -extern "C" { - pub static ukv_supports_snapshots_k: bool; -} -#[doc = " @brief Opens the underlying Key-Value Store.\n @see `ukv_database_init()`.\n\n Depending on the selected distribution can be any of:\n\n - embedded persistent transactional KVS\n - embedded in-memory transactional KVS\n - remote persistent transactional KVS\n - remote in-memory transactional KVS"] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_database_init_t { - #[doc = " @brief Configuration parameter for the DBMS.\n\n For embedded distributions should be the root directory,\n under which the DBMS and it's files will be organized.\n\n Recommendations:\n - UMem: empty or `/var/lib/ukv/umem/` for eventually persistent.\n - RocksDB: `/var/lib/ukv/rocksdb/` optionally storing `config_rocksdb.ini`.\n - LevelDB: `/var/lib/ukv/leveldb/` optionally storing `config_leveldb.json`.\n - Flight API Client: `grpc://0.0.0.0:38709`."] - pub config: ukv_str_view_t, - #[doc = " @brief A pointer to the opened KVS, unless `error` is filled."] - pub db: *mut ukv_database_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, -} -#[test] -fn bindgen_test_layout_ukv_database_init_t() { - const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(ukv_database_init_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_database_init_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).config) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_database_init_t), "::", stringify!(config)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_database_init_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 16usize, - concat!("Offset of field: ", stringify!(ukv_database_init_t), "::", stringify!(error)) - ); -} -extern "C" { - #[doc = " @brief Opens the underlying Key-Value Store.\n @see `ukv_database_init()`."] - pub fn ukv_database_init(arg1: *mut ukv_database_init_t); -} -#[doc = " @brief Lists all named collections in the DB.\n @see `ukv_collection_list()`.\n\n Retrieves a list of collection IDs & names in a NULL-delimited form.\n The default nameless collection won't be described in any form, as its always\n present. This is the only collection-management operation that can be performed\n on a DB state snapshot, and not just on the HEAD state."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_collection_list_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Pointer to exported error message.\n If not NULL, must be deallocated with `ukv_error_free()`."] - pub error: *mut ukv_error_t, - #[doc = " @brief The snapshot in which the retrieval will be conducted.\n @see `ukv_transaction_init()`, `ukv_transaction_commit()`, `ukv_transaction_free()`."] - pub transaction: ukv_transaction_t, - #[doc = " @brief Reusable memory handle.\n @see `ukv_arena_free()`."] - pub arena: *mut ukv_arena_t, - #[doc = " @brief Listing options.\n\n Possible values:\n - `::ukv_option_dont_discard_memory_k`: Won't reset the `arena` before the operation begins."] - pub options: ukv_options_t, - #[doc = " @brief Number of present collections."] - pub count: *mut ukv_size_t, - #[doc = " @brief Handles of all the collections in same order as `names`."] - pub ids: *mut *mut ukv_collection_t, - #[doc = " @brief Offsets of separate strings in the `names` tape."] - pub offsets: *mut *mut ukv_length_t, - #[doc = " @brief NULL-terminated collection names tape in same order as `ids`."] - pub names: *mut *mut ukv_char_t, -} -#[test] -fn bindgen_test_layout_ukv_collection_list_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 72usize, - concat!("Size of: ", stringify!(ukv_collection_list_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_collection_list_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(ukv_collection_list_t), - "::", - stringify!(transaction) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).arena) as usize - ptr as usize }, - 24usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(arena)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, - 32usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(options)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).count) as usize - ptr as usize }, - 40usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(count)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).ids) as usize - ptr as usize }, - 48usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(ids)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).offsets) as usize - ptr as usize }, - 56usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(offsets)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).names) as usize - ptr as usize }, - 64usize, - concat!("Offset of field: ", stringify!(ukv_collection_list_t), "::", stringify!(names)) - ); -} -extern "C" { - #[doc = " @brief Lists all named collections in the DB.\n @see `ukv_collection_list_t`."] - pub fn ukv_collection_list(arg1: *mut ukv_collection_list_t); -} -#[doc = " @brief Creates a new uniquely named collection in the DB.\n @see `ukv_collection_create()`.\n\n This function may never be called, as the default nameless collection\n always exists and can be addressed via `::ukv_collection_main_k`.\n You can \"re-create\" an empty collection with a new config."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_collection_create_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, - #[doc = " @brief Unique name for the new collection."] - pub name: ukv_str_view_t, - #[doc = " @brief Optional configuration JSON string."] - pub config: ukv_str_view_t, - #[doc = " @brief Output for the collection handle."] - pub id: *mut ukv_collection_t, -} -#[test] -fn bindgen_test_layout_ukv_collection_create_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(ukv_collection_create_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_collection_create_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize }, - 16usize, - concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(name)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).config) as usize - ptr as usize }, - 24usize, - concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(config)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, - 32usize, - concat!("Offset of field: ", stringify!(ukv_collection_create_t), "::", stringify!(id)) - ); -} -extern "C" { - #[doc = " @brief Creates a new uniquely named collection in the DB.\n @see `ukv_collection_create_t`."] - pub fn ukv_collection_create(arg1: *mut ukv_collection_create_t); -} -#[doc = " @brief Removes or clears an existing collection.\n @see `ukv_collection_drop()`.\n\n Removes a collection or its contents depending on `mode`.\n The default nameless collection can't be removed, only cleared."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_collection_drop_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, - #[doc = " @brief Existing collection handle."] - pub id: ukv_collection_t, - #[doc = " @brief Controls if values, pairs or the whole collection must be dropped."] - pub mode: ukv_drop_mode_t, -} -#[test] -fn bindgen_test_layout_ukv_collection_drop_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(ukv_collection_drop_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_collection_drop_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, - 16usize, - concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(id)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).mode) as usize - ptr as usize }, - 24usize, - concat!("Offset of field: ", stringify!(ukv_collection_drop_t), "::", stringify!(mode)) - ); -} -extern "C" { - #[doc = " @brief Removes or clears an existing collection.\n @see `ukv_collection_drop_t`."] - pub fn ukv_collection_drop(arg1: *mut ukv_collection_drop_t); -} -#[doc = " @brief Free-form communication tunnel with the underlying engine.\n @see `ukv_database_control()`.\n\n Performs free-form queries on the DB, that may not necessarily\n have a stable API and a fixed format output. Generally, those requests\n are very expensive and shouldn't be executed in most applications.\n This is the \"kitchen-sink\" of UKV interface, similar to `fcntl` & `ioctl`.\n\n ## Possible Commands\n - \"clear\": Removes all the data from DB, while keeping collection names.\n - \"reset\": Removes all the data from DB, including collection names.\n - \"compact\": Flushes and compacts all the data in LSM-tree implementations.\n - \"info\": Metadata about the current software version, used for debugging.\n - \"usage\": Metadata about approximate collection sizes, RAM and disk usage."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_database_control_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Reusable memory handle."] - pub arena: *mut ukv_arena_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, - #[doc = " @brief The input command as a NULL-terminated string."] - pub request: ukv_str_view_t, - #[doc = " @brief The output response as a NULL-terminated string."] - pub response: *mut ukv_str_view_t, -} -#[test] -fn bindgen_test_layout_ukv_database_control_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(ukv_database_control_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_database_control_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).arena) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(arena)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 16usize, - concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).request) as usize - ptr as usize }, - 24usize, - concat!("Offset of field: ", stringify!(ukv_database_control_t), "::", stringify!(request)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).response) as usize - ptr as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ukv_database_control_t), - "::", - stringify!(response) - ) - ); -} -extern "C" { - #[doc = " @brief Free-form communication tunnel with the underlying engine.\n @see `ukv_database_control()`."] - pub fn ukv_database_control(arg1: *mut ukv_database_control_t); -} -#[doc = " @brief Begins a new ACID transaction or resets an existing one.\n @see `ukv_transaction_init()`."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_transaction_init_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, - #[doc = " @brief Transaction options.\n\n Possible values:\n - `::ukv_option_dont_discard_memory_k`: Won't reset the `arena` before the operation begins."] - pub options: ukv_options_t, - #[doc = " @brief In-out transaction handle."] - pub transaction: *mut ukv_transaction_t, -} -#[test] -fn bindgen_test_layout_ukv_transaction_init_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(ukv_transaction_init_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_transaction_init_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_transaction_init_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_transaction_init_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, - 16usize, - concat!("Offset of field: ", stringify!(ukv_transaction_init_t), "::", stringify!(options)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_init_t), - "::", - stringify!(transaction) - ) - ); -} -extern "C" { - #[doc = " @brief Begins a new ACID transaction or resets an existing one.\n @see `ukv_transaction_init_t`."] - pub fn ukv_transaction_init(arg1: *mut ukv_transaction_init_t); -} -#[doc = " @brief Stages an ACID transaction for Two Phase Commits.\n @see `ukv_transaction_stage()`.\n\n Regardless of result, the content is preserved to allow further\n logging, serialization or retries. The underlying memory can be\n cleaned and reused by consecutive `ukv_transaction_init()` call."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_transaction_stage_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, - #[doc = " @brief Initialized transaction handle."] - pub transaction: ukv_transaction_t, - #[doc = " @brief Staging options."] - pub options: ukv_options_t, - #[doc = " @brief Optional output for the transaction stage sequence number."] - pub sequence_number: *mut ukv_sequence_number_t, -} -#[test] -fn bindgen_test_layout_ukv_transaction_stage_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(ukv_transaction_stage_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_transaction_stage_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_transaction_stage_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_transaction_stage_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_stage_t), - "::", - stringify!(transaction) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_stage_t), - "::", - stringify!(options) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sequence_number) as usize - ptr as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_stage_t), - "::", - stringify!(sequence_number) - ) - ); -} -extern "C" { - #[doc = " @brief Stages an ACID transaction for Two Phase Commits.\n @see `ukv_transaction_stage_t`."] - pub fn ukv_transaction_stage(arg1: *mut ukv_transaction_stage_t); -} -#[doc = " @brief Commits an ACID transaction.\n @see `ukv_transaction_commit()`.\n\n Regardless of result, the content is preserved to allow further\n logging, serialization or retries. The underlying memory can be\n cleaned and reused by consecutive `ukv_transaction_init()` call."] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct ukv_transaction_commit_t { - #[doc = " @brief Already open database instance."] - pub db: ukv_database_t, - #[doc = " @brief Pointer to exported error message."] - pub error: *mut ukv_error_t, - #[doc = " @brief Initialized transaction handle."] - pub transaction: ukv_transaction_t, - #[doc = " @brief Staging options."] - pub options: ukv_options_t, - #[doc = " @brief Optional output for the transaction commit sequence number."] - pub sequence_number: *mut ukv_sequence_number_t, -} -#[test] -fn bindgen_test_layout_ukv_transaction_commit_t() { - const UNINIT: ::std::mem::MaybeUninit = - ::std::mem::MaybeUninit::uninit(); - let ptr = UNINIT.as_ptr(); - assert_eq!( - ::std::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(ukv_transaction_commit_t)) - ); - assert_eq!( - ::std::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(ukv_transaction_commit_t)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).db) as usize - ptr as usize }, - 0usize, - concat!("Offset of field: ", stringify!(ukv_transaction_commit_t), "::", stringify!(db)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).error) as usize - ptr as usize }, - 8usize, - concat!("Offset of field: ", stringify!(ukv_transaction_commit_t), "::", stringify!(error)) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).transaction) as usize - ptr as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_commit_t), - "::", - stringify!(transaction) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).options) as usize - ptr as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_commit_t), - "::", - stringify!(options) - ) - ); - assert_eq!( - unsafe { ::std::ptr::addr_of!((*ptr).sequence_number) as usize - ptr as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(ukv_transaction_commit_t), - "::", - stringify!(sequence_number) - ) - ); -} -extern "C" { - #[doc = " @brief Commits an ACID transaction.\n @see `ukv_transaction_commit_t`."] - pub fn ukv_transaction_commit(arg1: *mut ukv_transaction_commit_t); -} -extern "C" { - #[doc = " @brief Deallocates reusable memory arenas.\n Passing NULLs is safe."] - pub fn ukv_arena_free(arg1: ukv_arena_t); -} -extern "C" { - #[doc = " @brief Resets the transaction and deallocates the underlying memory.\n Passing NULLs is safe."] - pub fn ukv_transaction_free(arg1: ukv_transaction_t); -} -extern "C" { - #[doc = " @brief Closes the DB and deallocates used memory.\n The database would still persist on disk.\n Passing NULLs is safe."] - pub fn ukv_database_free(arg1: ukv_database_t); -} -extern "C" { - #[doc = " @brief Deallocates error messages.\n Passing NULLs is safe."] - pub fn ukv_error_free(arg1: ukv_error_t); -} -pub type __builtin_va_list = *mut ::std::os::raw::c_char; diff --git a/rust/src/ukv/mod.rs b/rust/src/ukv/mod.rs deleted file mode 100644 index 90c70dcc2..000000000 --- a/rust/src/ukv/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod bindings; From 84b293a3f4ddd361a1cc64811888ac999256db77 Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:02:28 +0400 Subject: [PATCH 3/9] Fix: Patched a bug and fixed the build script - https://github.com/unum-cloud/ukv/issues/238#issuecomment-1405940184 - https://github.com/unum-cloud/ukv/issues/238#issuecomment-1406050340 --- rust/build.rs | 1 + rust/src/lib.rs | 4 ++-- rust/wrapper.h | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/rust/build.rs b/rust/build.rs index 06917f867..36a27ef81 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -13,6 +13,7 @@ fn main() -> Result<(), Box> { // .header("../include/ukv/db.h") // .header("../include/ukv/blobs.h") .header("./wrapper.h") + .clang_args(&["-I../include", "-I../include/ukv"]) .detect_include_paths(true) .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate()?; diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 802baf5f8..6ef8c3dd0 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -17,7 +17,7 @@ pub struct Database { impl Default for Database { fn default() -> Self { let config: *const _ = std::ffi::CString::default().as_ptr(); - let error: *mut _ = &mut CString::default().as_ptr(); + let error: *mut _ = &mut std::ffi::CString::default().as_ptr(); let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; let mut db = UkvDatabaseInitType { error, @@ -36,7 +36,7 @@ impl Database { /// Open a new database using ukv_database_init() pub fn new() -> Self { let config: *const _ = std::ffi::CString::default().as_ptr(); - let error: *mut _ = &mut CString::default().as_ptr(); + let error: *mut _ = &mut std::ffi::CString::default().as_ptr(); let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; let mut db = UkvDatabaseInitType { error, diff --git a/rust/wrapper.h b/rust/wrapper.h index 04cc4450d..f84eed92d 100644 --- a/rust/wrapper.h +++ b/rust/wrapper.h @@ -1 +1,2 @@ -#include "../include/ukv/db.h" \ No newline at end of file +#include "../include/ukv/db.h" +#include "../include/ukv/ukv.h" From ee7b17fcbbc482f608823ed3e0e380bcc64c6403 Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:08:03 +0400 Subject: [PATCH 4/9] . --- rust/build.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rust/build.rs b/rust/build.rs index 36a27ef81..c632f3075 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -10,8 +10,6 @@ fn main() -> Result<(), Box> { println!("cargo:rustc-link-search=../include/ukv"); let bindings = bindgen::Builder::default() - // .header("../include/ukv/db.h") - // .header("../include/ukv/blobs.h") .header("./wrapper.h") .clang_args(&["-I../include", "-I../include/ukv"]) .detect_include_paths(true) From 248df056a9646b2b38577061f1b6f3cbd8f713d9 Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Fri, 27 Jan 2023 10:30:26 +0400 Subject: [PATCH 5/9] . --- rust/build.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rust/build.rs b/rust/build.rs index c632f3075..872463069 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -4,10 +4,8 @@ use std::env::var; use std::path::PathBuf; fn main() -> Result<(), Box> { - // Tell cargo to invalidate the built crate whenever the wrapper changes println!("cargo:rerun-if-changed=wrapper.h"); - // Tell cargo to look for shared libraries in the specified directory - println!("cargo:rustc-link-search=../include/ukv"); + // println!("cargo:rustc-link-search=../include"); let bindings = bindgen::Builder::default() .header("./wrapper.h") @@ -16,7 +14,6 @@ fn main() -> Result<(), Box> { .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate()?; - // Write the bindings to the $OUT_DIR/bindings.rs file. let out_path = PathBuf::from(var("OUT_DIR")?); bindings.write_to_file(out_path.join("bindings.rs"))?; Ok(()) From b7499f0f22be59b2f15cb141559d3b27a2d8a5d0 Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Fri, 27 Jan 2023 11:45:01 +0400 Subject: [PATCH 6/9] Minor patch in Cargo.toml --- rust/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 831f29c43..340b8dc6a 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -5,9 +5,8 @@ publish = true edition = "2021" readme = "CARGO.md" homepage = "https://github.com/unum-cloud/ukv" -documentation = "https://unum.cloud/ukv/rust/index.html" repository = "https://github.com/unum-cloud/ukv" -build = "build.rs" +documentation = "https://unum.cloud/ukv/rust/index.html" [build-dependencies] bindgen = "0.63.0" From 496debc81417159789104e98257a332dc2d5fded Mon Sep 17 00:00:00 2001 From: Ashot Vardanian <1983160+ashvardanian@users.noreply.github.com> Date: Tue, 7 Feb 2023 12:16:40 +0400 Subject: [PATCH 7/9] Make: Refreshed Go version --- go-ukv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-ukv b/go-ukv index d0791fee0..5fd7bf06b 160000 --- a/go-ukv +++ b/go-ukv @@ -1 +1 @@ -Subproject commit d0791fee0f153e85b5be17433f44bf90cec4f236 +Subproject commit 5fd7bf06bc8e6de982f08966a12b56338911772b From 18eba87579d2a5ed49197c382ca6fc5b1a69f574 Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Tue, 7 Feb 2023 13:13:48 +0400 Subject: [PATCH 8/9] Update: SDK and cargo build script --- rust/Cargo.lock | 64 ++++++++++++++++-------- rust/Cargo.toml | 19 +++++++- rust/build.rs | 126 +++++++++++++++++++++++++++++++++++++++++++----- rust/src/lib.rs | 99 ++++++++++++++++++++++++------------- rust/wrapper.h | 10 +++- 5 files changed, 249 insertions(+), 69 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 7dde2479b..dc736d1ef 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -30,6 +30,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cc" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" + [[package]] name = "cexpr" version = "0.6.0" @@ -56,18 +62,42 @@ dependencies = [ "libloading", ] +[[package]] +name = "cmake" +version = "0.1.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +dependencies = [ + "cc", +] + [[package]] name = "either" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "fs_extra" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -127,6 +157,16 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.17.0" @@ -195,32 +235,14 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "thiserror" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "ukv" version = "0.0.1" dependencies = [ "bindgen", - "thiserror", + "cmake", + "fs_extra", + "num_cpus", ] [[package]] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 340b8dc6a..82dda4a07 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -10,9 +10,24 @@ documentation = "https://unum.cloud/ukv/rust/index.html" [build-dependencies] bindgen = "0.63.0" +cmake = "0.1.49" +fs_extra = "1.2.0" +num_cpus = "1.15.0" [lib] name = "ukv" -[dependencies] -thiserror = "1.0.38" +[features] +# Features for different backend implementations +# Library filenames: +# - libukv_embedded_umem +# - libukv_embedded_leveldb +# - libukv_embedded_rocksdb +# - libukv_flight_client +umem = [] +leveldb = [] +rocksdb = [] +flight-server = [] +flight-client = [] +default = ["umem"] + diff --git a/rust/build.rs b/rust/build.rs index 872463069..e7d8d8a0f 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -1,20 +1,124 @@ extern crate bindgen; +extern crate cmake; +extern crate num_cpus; -use std::env::var; use std::path::PathBuf; -fn main() -> Result<(), Box> { - println!("cargo:rerun-if-changed=wrapper.h"); - // println!("cargo:rustc-link-search=../include"); +/// Gets the absolute path of the parent directory. This will be used for +/// specifying the cmake directory and linking the library files from there. +fn get_parent_dir() -> std::io::Result { + let path = std::env::current_dir().unwrap(); + let path = format!("{}/../", path.as_os_str().to_string_lossy()); + let path = PathBuf::from(path); + let path = path.canonicalize().unwrap(); + let path = path.as_os_str(); + Ok(format!("{}", path.to_string_lossy())) +} + +const ENABLED: &'static str = "1"; +const DISABLED: &'static str = "0"; + +fn main() { + let makeflags = format!("-j{}", num_cpus::get()); + std::env::set_var("CARGO_MAKEFLAGS", &makeflags); + std::env::set_var("MAKEFLAGS", makeflags); + + let parent_dir = get_parent_dir().unwrap(); + let dst = cmake::Config::new(&parent_dir) + .define( + "UKV_BUILD_ENGINE_UMEM", + if cfg!(feature = "umem") { + ENABLED + } else { + DISABLED + }, + ) + .define( + "UKV_BUILD_ENGINE_LEVELDB", + if cfg!(feature = "leveldb") { + ENABLED + } else { + DISABLED + }, + ) + .define( + "UKV_BUILD_ENGINE_ROCKSDB", + if cfg!(feature = "rocksdb") { + ENABLED + } else { + DISABLED + }, + ) + .define( + "UKV_BUILD_API_FLIGHT_CLIENT", + if cfg!(feature = "flight-client") { + ENABLED + } else { + DISABLED + }, + ) + .define( + "UKV_BUILD_API_FLIGHT_SERVER", + if cfg!(feature = "flight-server") { + ENABLED + } else { + DISABLED + }, + ) + .define( + "CMAKE_BUILD_TYPE", + if std::env::var("PROFILE").unwrap() == "release" { + "Release" + } else { + "Debug" + }, + ) + .define("UKV_BUILD_TESTS", DISABLED) + .define("UKV_BUILD_BENCHMARKS", DISABLED) + .build(); + + println!("cargo:rustc-link-search=native={}", dst.display()); + + #[cfg(feature = "umem")] + println!("cargo:rustc-link-lib=ukv_embedded_umem"); + + #[cfg(feature = "rocksdb")] + println!("cargo:rustc-link-lib=ukv_embedded_rocksdb"); + + #[cfg(feature = "leveldb")] + println!("cargo:rustc-link-lib=ukv_embedded_leveldb"); + + #[cfg(feature = "flight-client")] + println!("cargo:rustc-link-lib=ukv_flight_client"); + + #[cfg(feature = "flight-server")] + println!("cargo:rustc-link-lib=ukv_flight_server"); + + let output = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + fs_extra::copy_items( + &[format!("{}/include", parent_dir).as_str()], + output.display().to_string().as_str(), + &fs_extra::dir::CopyOptions { + depth: 0, // unlimited + overwrite: true, + skip_exist: true, + copy_inside: false, + content_only: false, + buffer_size: 64_000, + }, + ) + .unwrap(); + drop(parent_dir); let bindings = bindgen::Builder::default() - .header("./wrapper.h") - .clang_args(&["-I../include", "-I../include/ukv"]) + .header("wrapper.h") + .size_t_is_usize(true) .detect_include_paths(true) .parse_callbacks(Box::new(bindgen::CargoCallbacks)) - .generate()?; - - let out_path = PathBuf::from(var("OUT_DIR")?); - bindings.write_to_file(out_path.join("bindings.rs"))?; - Ok(()) + .clang_arg(format!("-I{}/include/", dst.display())) + .clang_arg(format!("-I{}/include/ukv", dst.display())) + .generate() + .unwrap(); + bindings.write_to_file(output.join("bindings.rs")).unwrap(); + eprintln!("{}", output.display()); // printing in the end for debugging purposes } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 6ef8c3dd0..b5229e388 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -2,61 +2,94 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] -mod error; +/// Aliased type for any errors related to ukv. Since the type +/// of [bindings::ukv_error_t] is a raw [std::ffi::c_char] pointer, +/// there is no specific way to track the errors more efficiently. +pub type Error<'a> = std::borrow::Cow<'a, str>; +/// Bindings generated by bindgen for the ukv library. Only use this +/// module directly if you know what you are doing. pub mod bindings { include!(concat!(env!("OUT_DIR"), "/bindings.rs")); } -type UkvDatabaseInitType = bindings::ukv_database_init_t; - +/// Provides a safe interface for working with [bindings::ukv_database_init_t]. +#[derive(Debug)] pub struct Database { - pub db: UkvDatabaseInitType, + /// Internal object will be used for safely interfacing with the + /// C/C++ bindings via a Rust-defined interface. + inner: bindings::ukv_database_init_t, } +/// Provides a _fallible_ initialization interface for [Database]. Prefer +/// using [Database::new] for error-safe initialization. You should always +/// check for errors after initialization by calling [Database::error] in +/// case something fails. impl Default for Database { fn default() -> Self { - let config: *const _ = std::ffi::CString::default().as_ptr(); - let error: *mut _ = &mut std::ffi::CString::default().as_ptr(); - let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; - let mut db = UkvDatabaseInitType { - error, - config, - db: void_fn as _, + let mut inner = bindings::ukv_database_init_t { + db: &mut () as *mut _ as *mut std::ffi::c_void as _, + config: std::ffi::CString::default().as_ptr() as *const _, + error: &mut std::ffi::CString::default().as_ptr() as *mut _, }; - unsafe { bindings::ukv_database_init(&mut db) }; + unsafe { bindings::ukv_database_init(&mut inner) }; Self { - db, + inner, } } } -impl Database { - /// Open a new database using ukv_database_init() - pub fn new() -> Self { - let config: *const _ = std::ffi::CString::default().as_ptr(); - let error: *mut _ = &mut std::ffi::CString::default().as_ptr(); - let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; - let mut db = UkvDatabaseInitType { - error, - config, - db: void_fn as _, - }; +impl<'a> Database { + /// Creates a new [Database] instance. In case of errors, the + /// function will return [Error]. + pub fn new() -> Result> { + let initialized: Database = Default::default(); + initialized.error()?; + Ok(initialized) + } - unsafe { bindings::ukv_database_init(&mut db) }; - Self { - db, + /// Checks whether there are any errors created by the database, + /// and returns the pointer to the error. + pub fn error(&self) -> Result<(), Error<'a>> { + if !self.inner.error.is_null() { + // We know that `error` is going to be a valid pointer, pointing to a + // std::ffi::CString, thus, dereferencing the pointer here is safe. + let message = unsafe { std::ffi::CStr::from_ptr(*self.inner.error) }; + return Err(String::from_utf8_lossy(message.to_bytes())); } + + Ok(()) } - pub fn contains_key() {} + /// Closes a [Database] instance. In case of errors, the function + /// will return [Error]. + #[inline] + pub fn close(self) -> Result<(), Error<'a>> { + // We know that `self.inner.db` is going to point to a valid address + // in memory, thus, dereferencing the pointer here is safe. + unsafe { bindings::ukv_database_free(*self.inner.db) }; + Ok(self.error()?) + } +} - // Close a database using ukv_database_free() - pub fn close() -> Result<(), error::DataStoreError> { - let void_fn = &mut () as *mut _ as *mut std::ffi::c_void; - unsafe { bindings::ukv_database_free(void_fn) }; +#[cfg(test)] +mod tests { + use super::*; - Ok(()) + #[test] + fn test_Database_new() { + assert!(Database::new().is_ok()); + } + + #[test] + fn test_Database_default() { + assert!(Database::default().error().is_ok()) + } + + #[test] + fn test_Database_close() { + let database = Database::new().expect("Cannot initialize the database"); + assert!(database.close().is_ok()) } } diff --git a/rust/wrapper.h b/rust/wrapper.h index f84eed92d..c6ac8f456 100644 --- a/rust/wrapper.h +++ b/rust/wrapper.h @@ -1,2 +1,8 @@ -#include "../include/ukv/db.h" -#include "../include/ukv/ukv.h" +#include +#include +#include +#include +#include +#include +#include +#include From 36592b3cbcc867558e220bdf064ce7c2aed26cf0 Mon Sep 17 00:00:00 2001 From: michaelgrigoryan25 <56165400+michaelgrigoryan25@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:19:24 +0400 Subject: [PATCH 9/9] Patch: Cargo build script --- rust/build.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/build.rs b/rust/build.rs index e7d8d8a0f..57be72841 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -97,7 +97,8 @@ fn main() { let output = PathBuf::from(std::env::var("OUT_DIR").unwrap()); fs_extra::copy_items( &[format!("{}/include", parent_dir).as_str()], - output.display().to_string().as_str(), + output.display().to_string().as_str(), // no need to include `include/`, since the whole + // directory is going to be copied. &fs_extra::dir::CopyOptions { depth: 0, // unlimited overwrite: true,