From 8ac5214fc6d210794f40b981afc98329c90d2a6c Mon Sep 17 00:00:00 2001 From: rakita Date: Tue, 25 Oct 2022 12:18:51 +0200 Subject: [PATCH] chore(libmbx): fmt, clippy and deny list updated (#134) * feat(db): Add mdbx-rs apache licenced code 55e234 * feat(db): replace mdbx with reth-mdbx, metadata changes * chore(db): bump mdbx-sys to 0.12.1 * remove libmdbx from cargo deny * cargo fmt * cargo clippy * one more clippy error --- crates/db/src/kv/cursor.rs | 2 +- crates/db/src/kv/mod.rs | 10 +- crates/db/src/kv/tx.rs | 2 +- crates/libmdbx-rs/benches/cursor.rs | 31 ++--- crates/libmdbx-rs/benches/transaction.rs | 35 +---- crates/libmdbx-rs/benches/utils.rs | 3 +- crates/libmdbx-rs/mdbx-sys/build.rs | 76 +++++------ crates/libmdbx-rs/src/codec.rs | 10 +- crates/libmdbx-rs/src/cursor.rs | 166 ++++++++--------------- crates/libmdbx-rs/src/database.rs | 18 +-- crates/libmdbx-rs/src/environment.rs | 75 +++------- crates/libmdbx-rs/src/error.rs | 7 +- crates/libmdbx-rs/src/flags.rs | 138 +++++++++++-------- crates/libmdbx-rs/src/transaction.rs | 101 +++++--------- crates/libmdbx-rs/tests/cursor.rs | 160 ++++------------------ crates/libmdbx-rs/tests/environment.rs | 45 ++---- crates/libmdbx-rs/tests/transaction.rs | 51 ++----- deny.toml | 4 - 18 files changed, 307 insertions(+), 627 deletions(-) diff --git a/crates/db/src/kv/cursor.rs b/crates/db/src/kv/cursor.rs index c8a037f62..f71261cad 100644 --- a/crates/db/src/kv/cursor.rs +++ b/crates/db/src/kv/cursor.rs @@ -3,11 +3,11 @@ use std::marker::PhantomData; use crate::utils::*; -use reth_libmdbx::{self, TransactionKind, WriteFlags, RO, RW}; use reth_interfaces::db::{ DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW, DupSort, DupWalker, Encode, Error, Table, Walker, }; +use reth_libmdbx::{self, TransactionKind, WriteFlags, RO, RW}; /// Alias type for a `(key, value)` result coming from a cursor. pub type PairResult = Result::Key, ::Value)>, Error>; diff --git a/crates/db/src/kv/mod.rs b/crates/db/src/kv/mod.rs index 0764d751c..af73e1547 100644 --- a/crates/db/src/kv/mod.rs +++ b/crates/db/src/kv/mod.rs @@ -1,14 +1,14 @@ //! Module that interacts with MDBX. use crate::utils::default_page_size; -use reth_libmdbx::{ - DatabaseFlags, Environment, EnvironmentFlags, EnvironmentKind, Geometry, Mode, PageSize, - SyncMode, RO, RW, -}; use reth_interfaces::db::{ tables::{TableType, TABLES}, Database, DatabaseGAT, Error, }; +use reth_libmdbx::{ + DatabaseFlags, Environment, EnvironmentFlags, EnvironmentKind, Geometry, Mode, PageSize, + SyncMode, RO, RW, +}; use std::{ops::Deref, path::Path}; pub mod cursor; @@ -134,11 +134,11 @@ pub mod test_utils { #[cfg(test)] mod tests { use super::{test_utils, Env, EnvKind}; - use reth_libmdbx::{NoWriteMap, WriteMap}; use reth_interfaces::db::{ tables::{Headers, PlainAccountState, PlainStorageState}, Database, DbCursorRO, DbDupCursorRO, DbTx, DbTxMut, }; + use reth_libmdbx::{NoWriteMap, WriteMap}; use reth_primitives::{Account, Address, Header, StorageEntry, H256, U256}; use std::str::FromStr; use tempfile::TempDir; diff --git a/crates/db/src/kv/tx.rs b/crates/db/src/kv/tx.rs index 9a401a1e0..d754d096d 100644 --- a/crates/db/src/kv/tx.rs +++ b/crates/db/src/kv/tx.rs @@ -1,8 +1,8 @@ //! Transaction wrapper for libmdbx-sys. use crate::{kv::cursor::Cursor, utils::decode_one}; -use reth_libmdbx::{EnvironmentKind, Transaction, TransactionKind, WriteFlags, RW}; use reth_interfaces::db::{DbTx, DbTxGAT, DbTxMut, DbTxMutGAT, DupSort, Encode, Error, Table}; +use reth_libmdbx::{EnvironmentKind, Transaction, TransactionKind, WriteFlags, RW}; use std::marker::PhantomData; /// Wrapper for the libmdbx transaction. diff --git a/crates/libmdbx-rs/benches/cursor.rs b/crates/libmdbx-rs/benches/cursor.rs index d316ea677..74d975b9c 100644 --- a/crates/libmdbx-rs/benches/cursor.rs +++ b/crates/libmdbx-rs/benches/cursor.rs @@ -19,16 +19,14 @@ fn bench_get_seq_iter(c: &mut Criterion) { let mut i = 0; let mut count = 0u32; - for (key_len, data_len) in cursor - .iter::() - .map(Result::unwrap) + for (key_len, data_len) in + cursor.iter::().map(Result::unwrap) { i = i + *key_len + *data_len; count += 1; } - for (key_len, data_len) in cursor - .iter::() - .filter_map(Result::ok) + for (key_len, data_len) in + cursor.iter::().filter_map(Result::ok) { i = i + *key_len + *data_len; count += 1; @@ -64,9 +62,7 @@ fn bench_get_seq_cursor(c: &mut Criterion) { .unwrap() .iter::() .map(Result::unwrap) - .fold((0, 0), |(i, count), (key, val)| { - (i + *key + *val, count + 1) - }); + .fold((0, 0), |(i, count), (key, val)| (i + *key + *val, count + 1)); black_box(i); assert_eq!(count, n); @@ -83,14 +79,8 @@ fn bench_get_seq_raw(c: &mut Criterion) { let _txn = env.begin_ro_txn().unwrap(); let txn = _txn.txn(); - let mut key = MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let mut data = MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; + let mut key = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let mut data = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; let mut cursor: *mut MDBX_cursor = ptr::null_mut(); c.bench_function("bench_get_seq_raw", |b| { @@ -111,10 +101,5 @@ fn bench_get_seq_raw(c: &mut Criterion) { }); } -criterion_group!( - benches, - bench_get_seq_iter, - bench_get_seq_cursor, - bench_get_seq_raw -); +criterion_group!(benches, bench_get_seq_iter, bench_get_seq_cursor, bench_get_seq_raw); criterion_main!(benches); diff --git a/crates/libmdbx-rs/benches/transaction.rs b/crates/libmdbx-rs/benches/transaction.rs index fd8761fb6..9e44c9bb2 100644 --- a/crates/libmdbx-rs/benches/transaction.rs +++ b/crates/libmdbx-rs/benches/transaction.rs @@ -3,9 +3,9 @@ mod utils; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use ffi::*; use libc::size_t; -use reth_libmdbx::{ObjectLength, WriteFlags}; use rand::{prelude::SliceRandom, SeedableRng}; use rand_xorshift::XorShiftRng; +use reth_libmdbx::{ObjectLength, WriteFlags}; use std::ptr; use utils::*; @@ -22,10 +22,7 @@ fn bench_get_rand(c: &mut Criterion) { b.iter(|| { let mut i = 0usize; for key in &keys { - i += *txn - .get::(&db, key.as_bytes()) - .unwrap() - .unwrap(); + i += *txn.get::(&db, key.as_bytes()).unwrap().unwrap(); } black_box(i); }) @@ -44,14 +41,8 @@ fn bench_get_rand_raw(c: &mut Criterion) { let dbi = db.dbi(); let txn = _txn.txn(); - let mut key_val: MDBX_val = MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let mut data_val: MDBX_val = MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; + let mut key_val: MDBX_val = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let mut data_val: MDBX_val = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; c.bench_function("bench_get_rand_raw", |b| { b.iter(|| unsafe { @@ -101,14 +92,8 @@ fn bench_put_rand_raw(c: &mut Criterion) { let dbi = _env.begin_ro_txn().unwrap().open_db(None).unwrap().dbi(); let env = _env.env(); - let mut key_val: MDBX_val = MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let mut data_val: MDBX_val = MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; + let mut key_val: MDBX_val = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let mut data_val: MDBX_val = MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; c.bench_function("bench_put_rand_raw", |b| { b.iter(|| unsafe { @@ -130,11 +115,5 @@ fn bench_put_rand_raw(c: &mut Criterion) { }); } -criterion_group!( - benches, - bench_get_rand, - bench_get_rand_raw, - bench_put_rand, - bench_put_rand_raw -); +criterion_group!(benches, bench_get_rand, bench_get_rand_raw, bench_put_rand, bench_put_rand_raw); criterion_main!(benches); diff --git a/crates/libmdbx-rs/benches/utils.rs b/crates/libmdbx-rs/benches/utils.rs index 18032e78c..780344de0 100644 --- a/crates/libmdbx-rs/benches/utils.rs +++ b/crates/libmdbx-rs/benches/utils.rs @@ -17,8 +17,7 @@ pub fn setup_bench_db(num_rows: u32) -> (TempDir, Environment) { let txn = env.begin_rw_txn().unwrap(); let db = txn.open_db(None).unwrap(); for i in 0..num_rows { - txn.put(&db, &get_key(i), &get_data(i), WriteFlags::empty()) - .unwrap(); + txn.put(&db, &get_key(i), &get_data(i), WriteFlags::empty()).unwrap(); } txn.commit().unwrap(); } diff --git a/crates/libmdbx-rs/mdbx-sys/build.rs b/crates/libmdbx-rs/mdbx-sys/build.rs index d162b97a0..1b14b58a6 100644 --- a/crates/libmdbx-rs/mdbx-sys/build.rs +++ b/crates/libmdbx-rs/mdbx-sys/build.rs @@ -7,42 +7,42 @@ struct Callbacks; impl ParseCallbacks for Callbacks { fn int_macro(&self, name: &str, _value: i64) -> Option { match name { - "MDBX_SUCCESS" - | "MDBX_KEYEXIST" - | "MDBX_NOTFOUND" - | "MDBX_PAGE_NOTFOUND" - | "MDBX_CORRUPTED" - | "MDBX_PANIC" - | "MDBX_VERSION_MISMATCH" - | "MDBX_INVALID" - | "MDBX_MAP_FULL" - | "MDBX_DBS_FULL" - | "MDBX_READERS_FULL" - | "MDBX_TLS_FULL" - | "MDBX_TXN_FULL" - | "MDBX_CURSOR_FULL" - | "MDBX_PAGE_FULL" - | "MDBX_MAP_RESIZED" - | "MDBX_INCOMPATIBLE" - | "MDBX_BAD_RSLOT" - | "MDBX_BAD_TXN" - | "MDBX_BAD_VALSIZE" - | "MDBX_BAD_DBI" - | "MDBX_LOG_DONTCHANGE" - | "MDBX_DBG_DONTCHANGE" - | "MDBX_RESULT_TRUE" - | "MDBX_UNABLE_EXTEND_MAPSIZE" - | "MDBX_PROBLEM" - | "MDBX_LAST_LMDB_ERRCODE" - | "MDBX_BUSY" - | "MDBX_EMULTIVAL" - | "MDBX_EBADSIGN" - | "MDBX_WANNA_RECOVERY" - | "MDBX_EKEYMISMATCH" - | "MDBX_TOO_LARGE" - | "MDBX_THREAD_MISMATCH" - | "MDBX_TXN_OVERLAPPING" - | "MDBX_LAST_ERRCODE" => Some(IntKind::Int), + "MDBX_SUCCESS" | + "MDBX_KEYEXIST" | + "MDBX_NOTFOUND" | + "MDBX_PAGE_NOTFOUND" | + "MDBX_CORRUPTED" | + "MDBX_PANIC" | + "MDBX_VERSION_MISMATCH" | + "MDBX_INVALID" | + "MDBX_MAP_FULL" | + "MDBX_DBS_FULL" | + "MDBX_READERS_FULL" | + "MDBX_TLS_FULL" | + "MDBX_TXN_FULL" | + "MDBX_CURSOR_FULL" | + "MDBX_PAGE_FULL" | + "MDBX_MAP_RESIZED" | + "MDBX_INCOMPATIBLE" | + "MDBX_BAD_RSLOT" | + "MDBX_BAD_TXN" | + "MDBX_BAD_VALSIZE" | + "MDBX_BAD_DBI" | + "MDBX_LOG_DONTCHANGE" | + "MDBX_DBG_DONTCHANGE" | + "MDBX_RESULT_TRUE" | + "MDBX_UNABLE_EXTEND_MAPSIZE" | + "MDBX_PROBLEM" | + "MDBX_LAST_LMDB_ERRCODE" | + "MDBX_BUSY" | + "MDBX_EMULTIVAL" | + "MDBX_EBADSIGN" | + "MDBX_WANNA_RECOVERY" | + "MDBX_EKEYMISMATCH" | + "MDBX_TOO_LARGE" | + "MDBX_THREAD_MISMATCH" | + "MDBX_TXN_OVERLAPPING" | + "MDBX_LAST_ERRCODE" => Some(IntKind::Int), _ => Some(IntKind::UInt), } } @@ -70,9 +70,7 @@ fn main() { .generate() .expect("Unable to generate bindings"); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); + bindings.write_to_file(out_path.join("bindings.rs")).expect("Couldn't write bindings!"); let mut mdbx = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()); mdbx.push("libmdbx"); diff --git a/crates/libmdbx-rs/src/codec.rs b/crates/libmdbx-rs/src/codec.rs index 21ecfa960..aaa33f194 100644 --- a/crates/libmdbx-rs/src/codec.rs +++ b/crates/libmdbx-rs/src/codec.rs @@ -37,11 +37,7 @@ impl<'tx> TableObject<'tx> for Cow<'tx, [u8]> { let s = slice::from_raw_parts(data_val.iov_base as *const u8, data_val.iov_len); - Ok(if is_dirty { - Cow::Owned(s.to_vec()) - } else { - Cow::Borrowed(s) - }) + Ok(if is_dirty { Cow::Owned(s.to_vec()) } else { Cow::Borrowed(s) }) } } @@ -106,9 +102,7 @@ impl<'tx, const LEN: usize> TableObject<'tx> for [u8; LEN] { } if data_val.len() != LEN { - return Err(Error::DecodeError(Box::new(InvalidSize:: { - got: data_val.len(), - }))); + return Err(Error::DecodeError(Box::new(InvalidSize:: { got: data_val.len() }))) } let mut a = [0; LEN]; a[..].copy_from_slice(data_val); diff --git a/crates/libmdbx-rs/src/cursor.rs b/crates/libmdbx-rs/src/cursor.rs index 11bd79d90..4e3e87972 100644 --- a/crates/libmdbx-rs/src/cursor.rs +++ b/crates/libmdbx-rs/src/cursor.rs @@ -38,15 +38,11 @@ where let txn = txn.txn_mutex(); unsafe { - mdbx_result(txn_execute(&*txn, |txn| { + mdbx_result(txn_execute(&txn, |txn| { ffi::mdbx_cursor_open(txn, db.dbi(), &mut cursor) }))?; } - Ok(Self { - txn, - cursor, - _marker: PhantomData, - }) + Ok(Self { txn, cursor, _marker: PhantomData }) } fn new_at_position(other: &Self) -> Result { @@ -55,11 +51,7 @@ where let res = ffi::mdbx_cursor_copy(other.cursor(), cursor); - let s = Self { - txn: other.txn.clone(), - cursor, - _marker: PhantomData, - }; + let s = Self { txn: other.txn.clone(), cursor, _marker: PhantomData }; mdbx_result(res)?; @@ -92,7 +84,7 @@ where let mut data_val = slice_to_val(data); let key_ptr = key_val.iov_base; let data_ptr = data_val.iov_base; - txn_execute(&*self.txn, |txn| { + txn_execute(&self.txn, |txn| { let v = mdbx_result(ffi::mdbx_cursor_get( self.cursor, &mut key_val, @@ -168,7 +160,8 @@ where self.get_value(Some(k), Some(v), MDBX_GET_BOTH) } - /// [DatabaseFlags::DUP_SORT]-only: Position at given key and at first data greater than or equal to specified data. + /// [DatabaseFlags::DUP_SORT]-only: Position at given key and at first data greater than or + /// equal to specified data. pub fn get_both_range(&mut self, k: &[u8], v: &[u8]) -> Result> where Value: TableObject<'txn>, @@ -230,7 +223,8 @@ where self.get_full(None, None, MDBX_NEXT_DUP) } - /// [DatabaseFlags::DUP_FIXED]-only: Return up to a page of duplicate data items from next cursor position. Move cursor to prepare for MDBX_NEXT_MULTIPLE. + /// [DatabaseFlags::DUP_FIXED]-only: Return up to a page of duplicate data items from next + /// cursor position. Move cursor to prepare for MDBX_NEXT_MULTIPLE. pub fn next_multiple(&mut self) -> Result> where Key: TableObject<'txn>, @@ -301,7 +295,8 @@ where self.get_full(Some(key), None, MDBX_SET_RANGE) } - /// [DatabaseFlags::DUP_FIXED]-only: Position at previous page and return up to a page of duplicate data items. + /// [DatabaseFlags::DUP_FIXED]-only: Position at previous page and return up to a page of + /// duplicate data items. pub fn prev_multiple(&mut self) -> Result> where Key: TableObject<'txn>, @@ -310,12 +305,15 @@ where self.get_full(None, None, MDBX_PREV_MULTIPLE) } - /// Position at first key-value pair greater than or equal to specified, return both key and data, and the return code depends on a exact match. + /// Position at first key-value pair greater than or equal to specified, return both key and + /// data, and the return code depends on a exact match. /// - /// For non DupSort-ed collections this works the same as [Self::set_range()], but returns [false] if key found exactly and [true] if greater key was found. + /// For non DupSort-ed collections this works the same as [Self::set_range()], but returns + /// [false] if key found exactly and [true] if greater key was found. /// - /// For DupSort-ed a data value is taken into account for duplicates, i.e. for a pairs/tuples of a key and an each data value of duplicates. - /// Returns [false] if key-value pair found exactly and [true] if the next pair was returned. + /// For DupSort-ed a data value is taken into account for duplicates, i.e. for a pairs/tuples of + /// a key and an each data value of duplicates. Returns [false] if key-value pair found + /// exactly and [true] if the next pair was returned. pub fn set_lowerbound(&mut self, key: &[u8]) -> Result> where Key: TableObject<'txn>, @@ -368,7 +366,7 @@ where { let res: Result> = self.set_range(key); if let Err(error) = res { - return Iter::Err(Some(error)); + return Iter::Err(Some(error)) }; Iter::new(self, ffi::MDBX_GET_CURRENT, ffi::MDBX_NEXT) } @@ -381,7 +379,7 @@ where Key: TableObject<'txn>, Value: TableObject<'txn>, { - IterDup::new(self, ffi::MDBX_NEXT as u32) + IterDup::new(self, ffi::MDBX_NEXT) } /// Iterate over duplicate database items starting from the beginning of the @@ -391,7 +389,7 @@ where Key: TableObject<'txn>, Value: TableObject<'txn>, { - IterDup::new(self, ffi::MDBX_FIRST as u32) + IterDup::new(self, ffi::MDBX_FIRST) } /// Iterate over duplicate items in the database starting from the given @@ -403,9 +401,9 @@ where { let res: Result> = self.set_range(key); if let Err(error) = res { - return IterDup::Err(Some(error)); + return IterDup::Err(Some(error)) }; - IterDup::new(self, ffi::MDBX_GET_CURRENT as u32) + IterDup::new(self, ffi::MDBX_GET_CURRENT) } /// Iterate over the duplicates of the item in the database with the given key. @@ -419,7 +417,7 @@ where Ok(Some(_)) => (), Ok(None) => { let _: Result> = self.last(); - return Iter::new(self, ffi::MDBX_NEXT, ffi::MDBX_NEXT); + return Iter::new(self, ffi::MDBX_NEXT, ffi::MDBX_NEXT) } Err(error) => return Iter::Err(Some(error)), }; @@ -431,16 +429,12 @@ impl<'txn> Cursor<'txn, RW> { /// Puts a key/data pair into the database. The cursor will be positioned at /// the new data item, or on failure usually near it. pub fn put(&mut self, key: &[u8], data: &[u8], flags: WriteFlags) -> Result<()> { - let key_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: key.len(), - iov_base: key.as_ptr() as *mut c_void, - }; - let mut data_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: data.len(), - iov_base: data.as_ptr() as *mut c_void, - }; + let key_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: key.len(), iov_base: key.as_ptr() as *mut c_void }; + let mut data_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: data.len(), iov_base: data.as_ptr() as *mut c_void }; mdbx_result(unsafe { - txn_execute(&*self.txn, |_| { + txn_execute(&self.txn, |_| { ffi::mdbx_cursor_put(self.cursor, &key_val, &mut data_val, flags.bits()) }) })?; @@ -456,9 +450,7 @@ impl<'txn> Cursor<'txn, RW> { /// current key, if the database was opened with [DatabaseFlags::DUP_SORT]. pub fn del(&mut self, flags: WriteFlags) -> Result<()> { mdbx_result(unsafe { - txn_execute(&*self.txn, |_| { - ffi::mdbx_cursor_del(self.cursor, flags.bits()) - }) + txn_execute(&self.txn, |_| ffi::mdbx_cursor_del(self.cursor, flags.bits())) })?; Ok(()) @@ -470,7 +462,7 @@ where K: TransactionKind, { fn clone(&self) -> Self { - txn_execute(&*self.txn, |_| Self::new_at_position(self).unwrap()) + txn_execute(&self.txn, |_| Self::new_at_position(self).unwrap()) } } @@ -488,22 +480,16 @@ where K: TransactionKind, { fn drop(&mut self) { - txn_execute(&*self.txn, |_| unsafe { - ffi::mdbx_cursor_close(self.cursor) - }) + txn_execute(&self.txn, |_| unsafe { ffi::mdbx_cursor_close(self.cursor) }) } } unsafe fn slice_to_val(slice: Option<&[u8]>) -> ffi::MDBX_val { match slice { - Some(slice) => ffi::MDBX_val { - iov_len: slice.len(), - iov_base: slice.as_ptr() as *mut c_void, - }, - None => ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }, + Some(slice) => { + ffi::MDBX_val { iov_len: slice.len(), iov_base: slice.as_ptr() as *mut c_void } + } + None => ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }, } } @@ -563,12 +549,7 @@ where { /// Creates a new iterator backed by the given cursor. fn new(cursor: Cursor<'txn, K>, op: ffi::MDBX_cursor_op, next_op: ffi::MDBX_cursor_op) -> Self { - IntoIter::Ok { - cursor, - op, - next_op, - _marker: PhantomData, - } + IntoIter::Ok { cursor, op, next_op, _marker: PhantomData } } } @@ -582,23 +563,12 @@ where fn next(&mut self) -> Option { match self { - Self::Ok { - cursor, - op, - next_op, - _marker, - } => { - let mut key = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let mut data = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; + Self::Ok { cursor, op, next_op, _marker } => { + let mut key = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let mut data = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; let op = mem::replace(op, *next_op); unsafe { - txn_execute(&*cursor.txn, |txn| { + txn_execute(&cursor.txn, |txn| { match ffi::mdbx_cursor_get(cursor.cursor(), &mut key, &mut data, op) { ffi::MDBX_SUCCESS => { let key = match Key::decode_val::(txn, &key) { @@ -611,8 +581,9 @@ where }; Some(Ok((key, data))) } - // MDBX_ENODATA can occur when the cursor was previously seeked to a non-existent value, - // e.g. iter_from with a key greater than all values in the database. + // MDBX_ENODATA can occur when the cursor was previously seeked to a + // non-existent value, e.g. iter_from with a + // key greater than all values in the database. ffi::MDBX_NOTFOUND | ffi::MDBX_ENODATA => None, error => Some(Err(Error::from_err_code(error))), } @@ -669,12 +640,7 @@ where op: ffi::MDBX_cursor_op, next_op: ffi::MDBX_cursor_op, ) -> Self { - Iter::Ok { - cursor, - op, - next_op, - _marker: PhantomData, - } + Iter::Ok { cursor, op, next_op, _marker: PhantomData } } } @@ -688,23 +654,12 @@ where fn next(&mut self) -> Option { match self { - Iter::Ok { - cursor, - op, - next_op, - .. - } => { - let mut key = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let mut data = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; + Iter::Ok { cursor, op, next_op, .. } => { + let mut key = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let mut data = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; let op = mem::replace(op, *next_op); unsafe { - txn_execute(&*cursor.txn, |txn| { + txn_execute(&cursor.txn, |txn| { match ffi::mdbx_cursor_get(cursor.cursor(), &mut key, &mut data, op) { ffi::MDBX_SUCCESS => { let key = match Key::decode_val::(txn, &key) { @@ -717,8 +672,9 @@ where }; Some(Ok((key, data))) } - // MDBX_NODATA can occur when the cursor was previously seeked to a non-existent value, - // e.g. iter_from with a key greater than all values in the database. + // MDBX_NODATA can occur when the cursor was previously seeked to a + // non-existent value, e.g. iter_from with a + // key greater than all values in the database. ffi::MDBX_NOTFOUND | ffi::MDBX_ENODATA => None, error => Some(Err(Error::from_err_code(error))), } @@ -770,11 +726,7 @@ where { /// Creates a new iterator backed by the given cursor. fn new(cursor: &'cur mut Cursor<'txn, K>, op: c_uint) -> Self { - IterDup::Ok { - cursor, - op, - _marker: PhantomData, - } + IterDup::Ok { cursor, op, _marker: PhantomData } } } @@ -800,17 +752,11 @@ where fn next(&mut self) -> Option { match self { IterDup::Ok { cursor, op, .. } => { - let mut key = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let mut data = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; - let op = mem::replace(op, ffi::MDBX_NEXT_NODUP as u32); + let mut key = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let mut data = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; + let op = mem::replace(op, ffi::MDBX_NEXT_NODUP); - txn_execute(&*cursor.txn, |_| { + txn_execute(&cursor.txn, |_| { let err_code = unsafe { ffi::mdbx_cursor_get(cursor.cursor(), &mut key, &mut data, op) }; diff --git a/crates/libmdbx-rs/src/database.rs b/crates/libmdbx-rs/src/database.rs index 227a26c92..fb198a4c4 100644 --- a/crates/libmdbx-rs/src/database.rs +++ b/crates/libmdbx-rs/src/database.rs @@ -27,30 +27,20 @@ impl<'txn> Database<'txn> { flags: c_uint, ) -> Result { let c_name = name.map(|n| CString::new(n).unwrap()); - let name_ptr = if let Some(c_name) = &c_name { - c_name.as_ptr() - } else { - ptr::null() - }; + let name_ptr = if let Some(c_name) = &c_name { c_name.as_ptr() } else { ptr::null() }; let mut dbi: ffi::MDBX_dbi = 0; - mdbx_result(txn_execute(&*txn.txn_mutex(), |txn| unsafe { + mdbx_result(txn_execute(&txn.txn_mutex(), |txn| unsafe { ffi::mdbx_dbi_open(txn, name_ptr, flags, &mut dbi) }))?; Ok(Self::new_from_ptr(dbi)) } pub(crate) fn new_from_ptr(dbi: ffi::MDBX_dbi) -> Self { - Self { - dbi, - _marker: PhantomData, - } + Self { dbi, _marker: PhantomData } } pub(crate) fn freelist_db() -> Self { - Database { - dbi: 0, - _marker: PhantomData, - } + Database { dbi: 0, _marker: PhantomData } } /// Returns the underlying MDBX database handle. diff --git a/crates/libmdbx-rs/src/environment.rs b/crates/libmdbx-rs/src/environment.rs index e76099454..4a98d3726 100644 --- a/crates/libmdbx-rs/src/environment.rs +++ b/crates/libmdbx-rs/src/environment.rs @@ -28,8 +28,8 @@ mod private { pub trait Sealed {} - impl<'env> Sealed for NoWriteMap {} - impl<'env> Sealed for WriteMap {} + impl Sealed for NoWriteMap {} + impl Sealed for WriteMap {} } pub trait EnvironmentKind: private::Sealed + Debug + 'static { @@ -59,19 +59,9 @@ unsafe impl Send for EnvPtr {} unsafe impl Sync for EnvPtr {} pub(crate) enum TxnManagerMessage { - Begin { - parent: TxnPtr, - flags: ffi::MDBX_txn_flags_t, - sender: SyncSender>, - }, - Abort { - tx: TxnPtr, - sender: SyncSender>, - }, - Commit { - tx: TxnPtr, - sender: SyncSender>, - }, + Begin { parent: TxnPtr, flags: ffi::MDBX_txn_flags_t, sender: SyncSender> }, + Abort { tx: TxnPtr, sender: SyncSender> }, + Commit { tx: TxnPtr, sender: SyncSender> }, } /// An environment supports multiple databases, all residing in the same shared-memory map. @@ -135,10 +125,10 @@ where let res = rx.recv().unwrap(); if let Err(Error::Busy) = &res { sleep(Duration::from_millis(250)); - continue; + continue } - break res; + break res }?; Ok(Transaction::new_from_ptr(self, txn.0)) } @@ -197,9 +187,9 @@ where /// /// Note: /// - /// * LMDB stores all the freelists in the designated database 0 in each environment, - /// and the freelist count is stored at the beginning of the value as `libc::size_t` - /// in the native byte order. + /// * LMDB stores all the freelists in the designated database 0 in each environment, and the + /// freelist count is stored at the beginning of the value as `libc::size_t` in the native + /// byte order. /// /// * It will create a read transaction to traverse the freelist database. pub fn freelist(&self) -> Result { @@ -211,7 +201,7 @@ where for result in cursor { let (_key, value) = result?; if value.len() < mem::size_of::() { - return Err(Error::Corrupted); + return Err(Error::Corrupted) } let s = &value[..mem::size_of::()]; @@ -376,12 +366,7 @@ pub struct Geometry { impl Default for Geometry { fn default() -> Self { - Self { - size: None, - growth_step: None, - shrink_threshold: None, - page_size: None, - } + Self { size: None, growth_step: None, shrink_threshold: None, page_size: None } } } @@ -461,14 +446,8 @@ where (ffi::MDBX_opt_loose_limit, self.loose_limit), (ffi::MDBX_opt_dp_reserve_limit, self.dp_reserve_limit), (ffi::MDBX_opt_txn_dp_limit, self.txn_dp_limit), - ( - ffi::MDBX_opt_spill_max_denominator, - self.spill_max_denominator, - ), - ( - ffi::MDBX_opt_spill_min_denominator, - self.spill_min_denominator, - ), + (ffi::MDBX_opt_spill_max_denominator, self.spill_max_denominator), + (ffi::MDBX_opt_spill_min_denominator, self.spill_min_denominator), ] { if let Some(v) = v { mdbx_result(ffi::mdbx_env_set_option(env, opt, v))?; @@ -490,15 +469,11 @@ where })() { ffi::mdbx_env_close_ex(env, false); - return Err(e); + return Err(e) } } - let mut env = Environment { - env, - txn_manager: None, - _marker: PhantomData, - }; + let mut env = Environment { env, txn_manager: None, _marker: PhantomData }; if let Mode::ReadWrite { .. } = self.flags.mode { let (tx, rx) = std::sync::mpsc::sync_channel(0); @@ -506,11 +481,7 @@ where std::thread::spawn(move || loop { match rx.recv() { Ok(msg) => match msg { - TxnManagerMessage::Begin { - parent, - flags, - sender, - } => { + TxnManagerMessage::Begin { parent, flags, sender } => { let e = e; let mut txn: *mut ffi::MDBX_txn = ptr::null_mut(); sender @@ -529,9 +500,7 @@ where .unwrap() } TxnManagerMessage::Abort { tx, sender } => { - sender - .send(mdbx_result(unsafe { ffi::mdbx_txn_abort(tx.0) })) - .unwrap(); + sender.send(mdbx_result(unsafe { ffi::mdbx_txn_abort(tx.0) })).unwrap(); } TxnManagerMessage::Commit { tx, sender } => { sender @@ -611,7 +580,8 @@ where self } - /// Set all size-related parameters of environment, including page size and the min/max size of the memory map. + /// Set all size-related parameters of environment, including page size and the min/max size of + /// the memory map. pub fn set_geometry>(&mut self, geometry: Geometry) -> &mut Self { let convert_bound = |bound: Bound<&usize>| match bound { Bound::Included(v) | Bound::Excluded(v) => Some(*v), @@ -619,10 +589,7 @@ where }; self.geometry = Some(Geometry { size: geometry.size.map(|range| { - ( - convert_bound(range.start_bound()), - convert_bound(range.end_bound()), - ) + (convert_bound(range.start_bound()), convert_bound(range.end_bound())) }), growth_step: geometry.growth_step, shrink_threshold: geometry.shrink_threshold, diff --git a/crates/libmdbx-rs/src/error.rs b/crates/libmdbx-rs/src/error.rs index 15e167f4b..ed8f42957 100644 --- a/crates/libmdbx-rs/src/error.rs +++ b/crates/libmdbx-rs/src/error.rs @@ -111,7 +111,7 @@ impl Error { impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match self { - Error::DecodeError(reason) => write!(fmt, "{}", reason), + Error::DecodeError(reason) => write!(fmt, "{reason}"), other => { write!(fmt, "{}", unsafe { let err = ffi::mdbx_strerror(other.to_err_code()); @@ -154,9 +154,6 @@ mod test { fn test_description() { assert_eq!("Permission denied", Error::from_err_code(13).to_string()); - assert_eq!( - "MDBX_INVALID: File is not an MDBX file", - Error::Invalid.to_string() - ); + assert_eq!("MDBX_INVALID: File is not an MDBX file", Error::Invalid.to_string()); } } diff --git a/crates/libmdbx-rs/src/flags.rs b/crates/libmdbx-rs/src/flags.rs index e10c19917..f0cefd859 100644 --- a/crates/libmdbx-rs/src/flags.rs +++ b/crates/libmdbx-rs/src/flags.rs @@ -6,65 +6,94 @@ use libc::c_uint; #[derive(Clone, Copy, Debug)] pub enum SyncMode { /// Default robust and durable sync mode. - /// Metadata is written and flushed to disk after a data is written and flushed, which guarantees the integrity of the database in the event of a crash at any time. + /// Metadata is written and flushed to disk after a data is written and flushed, which + /// guarantees the integrity of the database in the event of a crash at any time. Durable, /// Don't sync the meta-page after commit. /// /// Flush system buffers to disk only once per transaction commit, omit the metadata flush. - /// Defer that until the system flushes files to disk, or next non-read-only commit or [Environment::sync()](crate::Environment::sync). - /// Depending on the platform and hardware, with [SyncMode::NoMetaSync] you may get a doubling of write performance. + /// Defer that until the system flushes files to disk, or next non-read-only commit or + /// [Environment::sync()](crate::Environment::sync). Depending on the platform and + /// hardware, with [SyncMode::NoMetaSync] you may get a doubling of write performance. /// - /// This trade-off maintains database integrity, but a system crash may undo the last committed transaction. - /// I.e. it preserves the ACI (atomicity, consistency, isolation) but not D (durability) database property. + /// This trade-off maintains database integrity, but a system crash may undo the last committed + /// transaction. I.e. it preserves the ACI (atomicity, consistency, isolation) but not D + /// (durability) database property. NoMetaSync, /// Don't sync anything but keep previous steady commits. /// - /// [SyncMode::UtterlyNoSync] the [SyncMode::SafeNoSync] flag disable similarly flush system buffers to disk when committing a transaction. - /// But there is a huge difference in how are recycled the MVCC snapshots corresponding to previous "steady" transactions (see below). + /// [SyncMode::UtterlyNoSync] the [SyncMode::SafeNoSync] flag disable similarly flush system + /// buffers to disk when committing a transaction. But there is a huge difference in how + /// are recycled the MVCC snapshots corresponding to previous "steady" transactions (see + /// below). /// - /// With [crate::WriteMap] the [SyncMode::SafeNoSync] instructs MDBX to use asynchronous mmap-flushes to disk. - /// Asynchronous mmap-flushes means that actually all writes will scheduled and performed by operation system on it own manner, i.e. unordered. - /// MDBX itself just notify operating system that it would be nice to write data to disk, but no more. + /// With [crate::WriteMap] the [SyncMode::SafeNoSync] instructs MDBX to use asynchronous + /// mmap-flushes to disk. Asynchronous mmap-flushes means that actually all writes will + /// scheduled and performed by operation system on it own manner, i.e. unordered. + /// MDBX itself just notify operating system that it would be nice to write data to disk, but + /// no more. /// - /// Depending on the platform and hardware, with [SyncMode::SafeNoSync] you may get a multiple increase of write performance, even 10 times or more. + /// Depending on the platform and hardware, with [SyncMode::SafeNoSync] you may get a multiple + /// increase of write performance, even 10 times or more. /// - /// In contrast to [SyncMode::UtterlyNoSync] mode, with [SyncMode::SafeNoSync] flag MDBX will keeps untouched pages within B-tree of the last transaction "steady" which was synced to disk completely. - /// This has big implications for both data durability and (unfortunately) performance: + /// In contrast to [SyncMode::UtterlyNoSync] mode, with [SyncMode::SafeNoSync] flag MDBX will + /// keeps untouched pages within B-tree of the last transaction "steady" which was synced to + /// disk completely. This has big implications for both data durability and (unfortunately) + /// performance: /// - /// A system crash can't corrupt the database, but you will lose the last transactions; because MDBX will rollback to last steady commit since it kept explicitly. - /// The last steady transaction makes an effect similar to "long-lived" read transaction since prevents reuse of pages freed by newer write transactions, thus the any data changes will be placed in newly allocated pages. - /// To avoid rapid database growth, the system will sync data and issue a steady commit-point to resume reuse pages, each time there is insufficient space and before increasing the size of the file on disk. - /// In other words, with [SyncMode::SafeNoSync] flag MDBX protects you from the whole database corruption, at the cost increasing database size and/or number of disk IOPs. - /// So, [SyncMode::SafeNoSync] flag could be used with [Environment::sync()](crate::Environment::sync) as alternatively for batch committing or nested transaction (in some cases). + /// A system crash can't corrupt the database, but you will lose the last transactions; because + /// MDBX will rollback to last steady commit since it kept explicitly. The last steady + /// transaction makes an effect similar to "long-lived" read transaction since prevents reuse + /// of pages freed by newer write transactions, thus the any data changes will be placed in + /// newly allocated pages. To avoid rapid database growth, the system will sync data and + /// issue a steady commit-point to resume reuse pages, each time there is insufficient space + /// and before increasing the size of the file on disk. In other words, with + /// [SyncMode::SafeNoSync] flag MDBX protects you from the whole database corruption, at the + /// cost increasing database size and/or number of disk IOPs. So, [SyncMode::SafeNoSync] + /// flag could be used with [Environment::sync()](crate::Environment::sync) as alternatively + /// for batch committing or nested transaction (in some cases). /// - /// The number and volume of of disk IOPs with [SyncMode::SafeNoSync] flag will exactly the as without any no-sync flags. - /// However, you should expect a larger process's work set and significantly worse a locality of reference, due to the more intensive allocation of previously unused pages and increase the size of the database. + /// The number and volume of of disk IOPs with [SyncMode::SafeNoSync] flag will exactly the as + /// without any no-sync flags. However, you should expect a larger process's work set and + /// significantly worse a locality of reference, due to the more intensive allocation of + /// previously unused pages and increase the size of the database. SafeNoSync, /// Don't sync anything and wipe previous steady commits. /// /// Don't flush system buffers to disk when committing a transaction. - /// This optimization means a system crash can corrupt the database, if buffers are not yet flushed to disk. - /// Depending on the platform and hardware, with [SyncMode::UtterlyNoSync] you may get a multiple increase of write performance, even 100 times or more. + /// This optimization means a system crash can corrupt the database, if buffers are not yet + /// flushed to disk. Depending on the platform and hardware, with [SyncMode::UtterlyNoSync] + /// you may get a multiple increase of write performance, even 100 times or more. /// - /// If the filesystem preserves write order (which is rare and never provided unless explicitly noted) and the [WriteMap](crate::WriteMap) and [EnvironmentFlags::liforeclaim] flags are not used, - /// then a system crash can't corrupt the database, but you can lose the last transactions, if at least one buffer is not yet flushed to disk. - /// The risk is governed by how often the system flushes dirty buffers to disk and how often [Environment::sync()](crate::Environment::sync) is called. - /// So, transactions exhibit ACI (atomicity, consistency, isolation) properties and only lose D (durability). + /// If the filesystem preserves write order (which is rare and never provided unless explicitly + /// noted) and the [WriteMap](crate::WriteMap) and [EnvironmentFlags::liforeclaim] flags are + /// not used, then a system crash can't corrupt the database, but you can lose the last + /// transactions, if at least one buffer is not yet flushed to disk. The risk is governed + /// by how often the system flushes dirty buffers to disk and how often + /// [Environment::sync()](crate::Environment::sync) is called. So, transactions exhibit ACI + /// (atomicity, consistency, isolation) properties and only lose D (durability). /// I.e. database integrity is maintained, but a system crash may undo the final transactions. /// - /// Otherwise, if the filesystem not preserves write order (which is typically) or [WriteMap](crate::WriteMap) or [EnvironmentFlags::liforeclaim] flags are used, you should expect the corrupted database after a system crash. + /// Otherwise, if the filesystem not preserves write order (which is typically) or + /// [WriteMap](crate::WriteMap) or [EnvironmentFlags::liforeclaim] flags are used, you should + /// expect the corrupted database after a system crash. /// /// So, most important thing about [SyncMode::UtterlyNoSync]: /// - /// A system crash immediately after commit the write transaction high likely lead to database corruption. - /// Successful completion of [Environment::sync(force=true)](crate::Environment::sync) after one or more committed transactions guarantees consistency and durability. - /// BUT by committing two or more transactions you back database into a weak state, in which a system crash may lead to database corruption! - /// In case single transaction after [Environment::sync()](crate::Environment::sync), you may lose transaction itself, but not a whole database. - /// Nevertheless, [SyncMode::UtterlyNoSync] provides "weak" durability in case of an application crash (but no durability on system failure), - /// and therefore may be very useful in scenarios where data durability is not required over a system failure (e.g for short-lived data), or if you can take such risk. + /// A system crash immediately after commit the write transaction high likely lead to database + /// corruption. Successful completion of + /// [Environment::sync(force=true)](crate::Environment::sync) after one or more committed + /// transactions guarantees consistency and durability. BUT by committing two or more + /// transactions you back database into a weak state, in which a system crash may lead to + /// database corruption! In case single transaction after + /// [Environment::sync()](crate::Environment::sync), you may lose transaction itself, but not a + /// whole database. Nevertheless, [SyncMode::UtterlyNoSync] provides "weak" durability in + /// case of an application crash (but no durability on system failure), and therefore may + /// be very useful in scenarios where data durability is not required over a system failure + /// (e.g for short-lived data), or if you can take such risk. UtterlyNoSync, } @@ -82,18 +111,13 @@ pub enum Mode { impl Default for Mode { fn default() -> Self { - Self::ReadWrite { - sync_mode: SyncMode::default(), - } + Self::ReadWrite { sync_mode: SyncMode::default() } } } impl From for EnvironmentFlags { fn from(mode: Mode) -> Self { - Self { - mode, - ..Default::default() - } + Self { mode, ..Default::default() } } } @@ -165,14 +189,14 @@ bitflags! { #[doc="Database options."] #[derive(Default)] pub struct DatabaseFlags: c_uint { - const REVERSE_KEY = MDBX_REVERSEKEY as u32; - const DUP_SORT = MDBX_DUPSORT as u32; - const INTEGER_KEY = MDBX_INTEGERKEY as u32; - const DUP_FIXED = MDBX_DUPFIXED as u32; - const INTEGER_DUP = MDBX_INTEGERDUP as u32; - const REVERSE_DUP = MDBX_REVERSEDUP as u32; - const CREATE = MDBX_CREATE as u32; - const ACCEDE = MDBX_DB_ACCEDE as u32; + const REVERSE_KEY = MDBX_REVERSEKEY; + const DUP_SORT = MDBX_DUPSORT; + const INTEGER_KEY = MDBX_INTEGERKEY; + const DUP_FIXED = MDBX_DUPFIXED; + const INTEGER_DUP = MDBX_INTEGERDUP; + const REVERSE_DUP = MDBX_REVERSEDUP; + const CREATE = MDBX_CREATE; + const ACCEDE = MDBX_DB_ACCEDE; } } @@ -180,14 +204,14 @@ bitflags! { #[doc="Write options."] #[derive(Default)] pub struct WriteFlags: c_uint { - const UPSERT = MDBX_UPSERT as u32; - const NO_OVERWRITE = MDBX_NOOVERWRITE as u32; - const NO_DUP_DATA = MDBX_NODUPDATA as u32; - const CURRENT = MDBX_CURRENT as u32; - const ALLDUPS = MDBX_ALLDUPS as u32; - const RESERVE = MDBX_RESERVE as u32; - const APPEND = MDBX_APPEND as u32; - const APPEND_DUP = MDBX_APPENDDUP as u32; - const MULTIPLE = MDBX_MULTIPLE as u32; + const UPSERT = MDBX_UPSERT; + const NO_OVERWRITE = MDBX_NOOVERWRITE; + const NO_DUP_DATA = MDBX_NODUPDATA; + const CURRENT = MDBX_CURRENT; + const ALLDUPS = MDBX_ALLDUPS; + const RESERVE = MDBX_RESERVE; + const APPEND = MDBX_APPEND; + const APPEND_DUP = MDBX_APPENDDUP; + const MULTIPLE = MDBX_MULTIPLE; } } diff --git a/crates/libmdbx-rs/src/transaction.rs b/crates/libmdbx-rs/src/transaction.rs index 53d71fc39..2a0d30937 100644 --- a/crates/libmdbx-rs/src/transaction.rs +++ b/crates/libmdbx-rs/src/transaction.rs @@ -23,8 +23,8 @@ mod private { pub trait Sealed {} - impl<'env> Sealed for RO {} - impl<'env> Sealed for RW {} + impl Sealed for RO {} + impl Sealed for RW {} } pub trait TransactionKind: private::Sealed + Debug + 'static { @@ -127,14 +127,9 @@ where where Key: TableObject<'txn>, { - let key_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: key.len(), - iov_base: key.as_ptr() as *mut c_void, - }; - let mut data_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: 0, - iov_base: ptr::null_mut(), - }; + let key_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: key.len(), iov_base: key.as_ptr() as *mut c_void }; + let mut data_val: ffi::MDBX_val = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() }; txn_execute(&self.txn, |txn| unsafe { match ffi::mdbx_get(txn, db.dbi(), &key_val, &mut data_val) { @@ -156,7 +151,8 @@ where self.primed_dbis.lock().insert(db.dbi()); } - /// Commits the transaction and returns table handles permanently open for the lifetime of `Environment`. + /// Commits the transaction and returns table handles permanently open for the lifetime of + /// `Environment`. pub fn commit_and_rebind_open_dbs(mut self) -> Result<(bool, Vec>)> { let txnlck = self.txn.lock(); let txn = *txnlck; @@ -168,23 +164,13 @@ where .txn_manager .as_ref() .unwrap() - .send(TxnManagerMessage::Commit { - tx: TxnPtr(txn), - sender, - }) + .send(TxnManagerMessage::Commit { tx: TxnPtr(txn), sender }) .unwrap(); rx.recv().unwrap() }; self.committed = true; result.map(|v| { - ( - v, - self.primed_dbis - .lock() - .iter() - .map(|&dbi| Database::new_from_ptr(dbi)) - .collect(), - ) + (v, self.primed_dbis.lock().iter().map(|&dbi| Database::new_from_ptr(dbi)).collect()) }) } @@ -261,8 +247,8 @@ where /// case the environment must be configured to allow named databases through /// [EnvironmentBuilder::set_max_dbs()](crate::EnvironmentBuilder::set_max_dbs). /// - /// This function will fail with [Error::BadRslot](crate::error::Error::BadRslot) if called by a thread with an open - /// transaction. + /// This function will fail with [Error::BadRslot](crate::error::Error::BadRslot) if called by a + /// thread with an open transaction. pub fn create_db<'txn>( &'txn self, name: Option<&str>, @@ -286,14 +272,10 @@ where ) -> Result<()> { let key = key.as_ref(); let data = data.as_ref(); - let key_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: key.len(), - iov_base: key.as_ptr() as *mut c_void, - }; - let mut data_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: data.len(), - iov_base: data.as_ptr() as *mut c_void, - }; + let key_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: key.len(), iov_base: key.as_ptr() as *mut c_void }; + let mut data_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: data.len(), iov_base: data.as_ptr() as *mut c_void }; mdbx_result(txn_execute(&self.txn, |txn| unsafe { ffi::mdbx_put(txn, db.dbi(), &key_val, &mut data_val, flags.bits()) }))?; @@ -312,14 +294,10 @@ where flags: WriteFlags, ) -> Result<&'txn mut [u8]> { let key = key.as_ref(); - let key_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: key.len(), - iov_base: key.as_ptr() as *mut c_void, - }; - let mut data_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: len, - iov_base: ptr::null_mut::(), - }; + let key_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: key.len(), iov_base: key.as_ptr() as *mut c_void }; + let mut data_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: len, iov_base: ptr::null_mut::() }; unsafe { mdbx_result(txn_execute(&self.txn, |txn| { ffi::mdbx_put( @@ -330,19 +308,17 @@ where flags.bits() | ffi::MDBX_RESERVE, ) }))?; - Ok(slice::from_raw_parts_mut( - data_val.iov_base as *mut u8, - data_val.iov_len, - )) + Ok(slice::from_raw_parts_mut(data_val.iov_base as *mut u8, data_val.iov_len)) } } /// Delete items from a database. /// This function removes key/data pairs from the database. /// - /// The data parameter is NOT ignored regardless the database does support sorted duplicate data items or not. - /// If the data parameter is [Some] only the matching data item will be deleted. - /// Otherwise, if data parameter is [None], any/all value(s) for specified key will be deleted. + /// The data parameter is NOT ignored regardless the database does support sorted duplicate data + /// items or not. If the data parameter is [Some] only the matching data item will be + /// deleted. Otherwise, if data parameter is [None], any/all value(s) for specified key will + /// be deleted. /// /// Returns `true` if the key/value pair was present. pub fn del<'txn>( @@ -352,10 +328,8 @@ where data: Option<&[u8]>, ) -> Result { let key = key.as_ref(); - let key_val: ffi::MDBX_val = ffi::MDBX_val { - iov_len: key.len(), - iov_base: key.as_ptr() as *mut c_void, - }; + let key_val: ffi::MDBX_val = + ffi::MDBX_val { iov_len: key.len(), iov_base: key.as_ptr() as *mut c_void }; let data_val: Option = data.map(|data| ffi::MDBX_val { iov_len: data.len(), iov_base: data.as_ptr() as *mut c_void, @@ -379,9 +353,7 @@ where /// Empties the given database. All items will be removed. pub fn clear_db<'txn>(&'txn self, db: &Database<'txn>) -> Result<()> { - mdbx_result(txn_execute(&self.txn, |txn| unsafe { - ffi::mdbx_drop(txn, db.dbi(), false) - }))?; + mdbx_result(txn_execute(&self.txn, |txn| unsafe { ffi::mdbx_drop(txn, db.dbi(), false) }))?; Ok(()) } @@ -389,11 +361,10 @@ where /// Drops the database from the environment. /// /// # Safety - /// Caller must close ALL other [Database] and [Cursor] instances pointing to the same dbi BEFORE calling this function. + /// Caller must close ALL other [Database] and [Cursor] instances pointing to the same dbi + /// BEFORE calling this function. pub unsafe fn drop_db<'txn>(&'txn self, db: Database<'txn>) -> Result<()> { - mdbx_result(txn_execute(&self.txn, |txn| { - ffi::mdbx_drop(txn, db.dbi(), true) - }))?; + mdbx_result(txn_execute(&self.txn, |txn| ffi::mdbx_drop(txn, db.dbi(), true)))?; Ok(()) } @@ -406,7 +377,8 @@ where /// Closes the database handle. /// /// # Safety - /// Caller must close ALL other [Database] and [Cursor] instances pointing to the same dbi BEFORE calling this function. + /// Caller must close ALL other [Database] and [Cursor] instances pointing to the same dbi + /// BEFORE calling this function. pub unsafe fn close_db(&self, db: Database<'_>) -> Result<()> { mdbx_result(ffi::mdbx_dbi_close(self.env.env(), db.dbi()))?; @@ -430,9 +402,7 @@ impl<'env> Transaction<'env, RW, NoWriteMap> { }) .unwrap(); - rx.recv() - .unwrap() - .map(|ptr| Transaction::new_from_ptr(self.env, ptr.0)) + rx.recv().unwrap().map(|ptr| Transaction::new_from_ptr(self.env, ptr.0)) }) } } @@ -465,10 +435,7 @@ where .txn_manager .as_ref() .unwrap() - .send(TxnManagerMessage::Abort { - tx: TxnPtr(txn), - sender, - }) + .send(TxnManagerMessage::Abort { tx: TxnPtr(txn), sender }) .unwrap(); rx.recv().unwrap().unwrap(); } diff --git a/crates/libmdbx-rs/tests/cursor.rs b/crates/libmdbx-rs/tests/cursor.rs index c2828fd96..7f73f4bd8 100644 --- a/crates/libmdbx-rs/tests/cursor.rs +++ b/crates/libmdbx-rs/tests/cursor.rs @@ -26,10 +26,7 @@ fn test_get() { assert_eq!(cursor.last().unwrap(), Some((*b"key3", *b"val3"))); assert_eq!(cursor.set(b"key1").unwrap(), Some(*b"val1")); assert_eq!(cursor.set_key(b"key3").unwrap(), Some((*b"key3", *b"val3"))); - assert_eq!( - cursor.set_range(b"key2\0").unwrap(), - Some((*b"key3", *b"val3")) - ); + assert_eq!(cursor.set_range(b"key2\0").unwrap(), Some((*b"key3", *b"val3"))); } #[test] @@ -62,16 +59,10 @@ fn test_get_dup() { assert_eq!(cursor.next_dup::<(), ()>().unwrap(), None); assert_eq!(cursor.set(b"key1").unwrap(), Some(*b"val1")); assert_eq!(cursor.set(b"key2").unwrap(), Some(*b"val1")); - assert_eq!( - cursor.set_range(b"key1\0").unwrap(), - Some((*b"key2", *b"val1")) - ); + assert_eq!(cursor.set_range(b"key1\0").unwrap(), Some((*b"key2", *b"val1"))); assert_eq!(cursor.get_both(b"key1", b"val3").unwrap(), Some(*b"val3")); assert_eq!(cursor.get_both_range::<()>(b"key1", b"val4").unwrap(), None); - assert_eq!( - cursor.get_both_range(b"key2", b"val").unwrap(), - Some(*b"val1") - ); + assert_eq!(cursor.get_both_range(b"key2", b"val").unwrap(), Some(*b"val1")); assert_eq!(cursor.last().unwrap(), Some((*b"key2", *b"val3"))); cursor.del(WriteFlags::empty()).unwrap(); @@ -88,9 +79,7 @@ fn test_get_dupfixed() { let env = Environment::new().open(dir.path()).unwrap(); let txn = env.begin_rw_txn().unwrap(); - let db = txn - .create_db(None, DatabaseFlags::DUP_SORT | DatabaseFlags::DUP_FIXED) - .unwrap(); + let db = txn.create_db(None, DatabaseFlags::DUP_SORT | DatabaseFlags::DUP_FIXED).unwrap(); txn.put(&db, b"key1", b"val1", WriteFlags::empty()).unwrap(); txn.put(&db, b"key1", b"val2", WriteFlags::empty()).unwrap(); txn.put(&db, b"key1", b"val3", WriteFlags::empty()).unwrap(); @@ -144,33 +133,21 @@ fn test_iter() { cursor.iter().collect::>>().unwrap() ); - assert_eq!( - items, - cursor.iter_start().collect::>>().unwrap() - ); + assert_eq!(items, cursor.iter_start().collect::>>().unwrap()); assert_eq!( items.clone().into_iter().skip(1).collect::>(), - cursor - .iter_from(b"key2") - .collect::>>() - .unwrap() + cursor.iter_from(b"key2").collect::>>().unwrap() ); assert_eq!( items.into_iter().skip(3).collect::>(), - cursor - .iter_from(b"key4") - .collect::>>() - .unwrap() + cursor.iter_from(b"key4").collect::>>().unwrap() ); assert_eq!( Vec::<((), ())>::new(), - cursor - .iter_from(b"key6") - .collect::>>() - .unwrap() + cursor.iter_from(b"key6").collect::>>().unwrap() ); } @@ -206,11 +183,7 @@ fn test_iter_empty_dup_database() { assert!(cursor.iter_from::<(), ()>(b"foo").next().is_none()); assert!(cursor.iter_dup::<(), ()>().flatten().next().is_none()); assert!(cursor.iter_dup_start::<(), ()>().flatten().next().is_none()); - assert!(cursor - .iter_dup_from::<(), ()>(b"foo") - .flatten() - .next() - .is_none()); + assert!(cursor.iter_dup_from::<(), ()>(b"foo").flatten().next().is_none()); assert!(cursor.iter_dup_of::<(), ()>(b"foo").next().is_none()); } @@ -253,91 +226,39 @@ fn test_iter_dup() { let txn = env.begin_ro_txn().unwrap(); let db = txn.open_db(None).unwrap(); let mut cursor = txn.cursor(&db).unwrap(); - assert_eq!( - items, - cursor - .iter_dup() - .flatten() - .collect::>>() - .unwrap() - ); + assert_eq!(items, cursor.iter_dup().flatten().collect::>>().unwrap()); cursor.set::<()>(b"b").unwrap(); assert_eq!( items.iter().copied().skip(4).collect::>(), - cursor - .iter_dup() - .flatten() - .collect::>>() - .unwrap() + cursor.iter_dup().flatten().collect::>>().unwrap() + ); + + assert_eq!(items, cursor.iter_dup_start().flatten().collect::>>().unwrap()); + + assert_eq!( + items.iter().copied().into_iter().skip(3).collect::>(), + cursor.iter_dup_from(b"b").flatten().collect::>>().unwrap() ); assert_eq!( - items, - cursor - .iter_dup_start() - .flatten() - .collect::>>() - .unwrap() + items.iter().copied().into_iter().skip(3).collect::>(), + cursor.iter_dup_from(b"ab").flatten().collect::>>().unwrap() ); assert_eq!( - items - .iter() - .copied() - .into_iter() - .skip(3) - .collect::>(), - cursor - .iter_dup_from(b"b") - .flatten() - .collect::>>() - .unwrap() - ); - - assert_eq!( - items - .iter() - .copied() - .into_iter() - .skip(3) - .collect::>(), - cursor - .iter_dup_from(b"ab") - .flatten() - .collect::>>() - .unwrap() - ); - - assert_eq!( - items - .iter() - .copied() - .into_iter() - .skip(9) - .collect::>(), - cursor - .iter_dup_from(b"d") - .flatten() - .collect::>>() - .unwrap() + items.iter().copied().into_iter().skip(9).collect::>(), + cursor.iter_dup_from(b"d").flatten().collect::>>().unwrap() ); assert_eq!( Vec::<([u8; 1], [u8; 1])>::new(), - cursor - .iter_dup_from(b"f") - .flatten() - .collect::>>() - .unwrap() + cursor.iter_dup_from(b"f").flatten().collect::>>().unwrap() ); assert_eq!( items.iter().copied().skip(3).take(3).collect::>(), - cursor - .iter_dup_of(b"b") - .collect::>>() - .unwrap() + cursor.iter_dup_of(b"b").collect::>>().unwrap() ); assert_eq!(0, cursor.iter_dup_of::<(), ()>(b"foo").count()); @@ -376,35 +297,18 @@ fn test_iter_del_get() { let txn = env.begin_rw_txn().unwrap(); let db = txn.open_db(None).unwrap(); let mut cursor = txn.cursor(&db).unwrap(); - assert_eq!( - items, - cursor - .iter_dup() - .flatten() - .collect::>>() - .unwrap() - ); + assert_eq!(items, cursor.iter_dup().flatten().collect::>>().unwrap()); assert_eq!( items.iter().copied().take(1).collect::>(), - cursor - .iter_dup_of(b"a") - .collect::>>() - .unwrap() + cursor.iter_dup_of(b"a").collect::>>().unwrap() ); assert_eq!(cursor.set(b"a").unwrap(), Some(*b"1")); cursor.del(WriteFlags::empty()).unwrap(); - assert_eq!( - cursor - .iter_dup_of::<(), ()>(b"a") - .collect::>>() - .unwrap() - .len(), - 0 - ); + assert_eq!(cursor.iter_dup_of::<(), ()>(b"a").collect::>>().unwrap().len(), 0); } #[test] @@ -422,19 +326,13 @@ fn test_put_del() { assert_eq!( cursor.get_current().unwrap().unwrap(), - ( - Cow::Borrowed(b"key3" as &[u8]), - Cow::Borrowed(b"val3" as &[u8]) - ) + (Cow::Borrowed(b"key3" as &[u8]), Cow::Borrowed(b"val3" as &[u8])) ); cursor.del(WriteFlags::empty()).unwrap(); assert_eq!(cursor.get_current::, Vec>().unwrap(), None); assert_eq!( cursor.last().unwrap().unwrap(), - ( - Cow::Borrowed(b"key2" as &[u8]), - Cow::Borrowed(b"val2" as &[u8]) - ) + (Cow::Borrowed(b"key2" as &[u8]), Cow::Borrowed(b"val2" as &[u8])) ); } diff --git a/crates/libmdbx-rs/tests/environment.rs b/crates/libmdbx-rs/tests/environment.rs index ca3b4efc7..ce3639bb9 100644 --- a/crates/libmdbx-rs/tests/environment.rs +++ b/crates/libmdbx-rs/tests/environment.rs @@ -9,19 +9,13 @@ fn test_open() { let dir = tempdir().unwrap(); // opening non-existent env with read-only should fail - assert!(Environment::new() - .set_flags(Mode::ReadOnly.into()) - .open(dir.path()) - .is_err()); + assert!(Environment::new().set_flags(Mode::ReadOnly.into()).open(dir.path()).is_err()); // opening non-existent env should succeed assert!(Environment::new().open(dir.path()).is_ok()); // opening env with read-only should succeed - assert!(Environment::new() - .set_flags(Mode::ReadOnly.into()) - .open(dir.path()) - .is_ok()); + assert!(Environment::new().set_flags(Mode::ReadOnly.into()).open(dir.path()).is_ok()); } #[test] @@ -38,10 +32,7 @@ fn test_begin_txn() { { // read-only environment - let env = Environment::new() - .set_flags(Mode::ReadOnly.into()) - .open(dir.path()) - .unwrap(); + let env = Environment::new().set_flags(Mode::ReadOnly.into()).open(dir.path()).unwrap(); assert!(env.begin_rw_txn().is_err()); assert!(env.begin_ro_txn().is_ok()); @@ -65,9 +56,7 @@ fn test_create_db() { let txn = env.begin_rw_txn().unwrap(); assert!(txn.open_db(Some("testdb")).is_err()); - assert!(txn - .create_db(Some("testdb"), DatabaseFlags::empty()) - .is_ok()); + assert!(txn.create_db(Some("testdb"), DatabaseFlags::empty()).is_ok()); assert!(txn.open_db(Some("testdb")).is_ok()) } @@ -89,10 +78,7 @@ fn test_sync() { env.sync(true).unwrap(); } { - let env = Environment::new() - .set_flags(Mode::ReadOnly.into()) - .open(dir.path()) - .unwrap(); + let env = Environment::new().set_flags(Mode::ReadOnly.into()).open(dir.path()).unwrap(); env.sync(true).unwrap_err(); } } @@ -115,13 +101,7 @@ fn test_stat() { let mut value = [0u8; 8]; LittleEndian::write_u64(&mut value, i); let tx = env.begin_rw_txn().expect("begin_rw_txn"); - tx.put( - &tx.open_db(None).unwrap(), - &value, - &value, - WriteFlags::default(), - ) - .expect("tx.put"); + tx.put(&tx.open_db(None).unwrap(), &value, &value, WriteFlags::default()).expect("tx.put"); tx.commit().expect("tx.commit"); } @@ -139,10 +119,7 @@ fn test_info() { let map_size = 1024 * 1024; let dir = tempdir().unwrap(); let env = Environment::new() - .set_geometry(Geometry { - size: Some(map_size..), - ..Default::default() - }) + .set_geometry(Geometry { size: Some(map_size..), ..Default::default() }) .open(dir.path()) .unwrap(); @@ -166,13 +143,7 @@ fn test_freelist() { let mut value = [0u8; 8]; LittleEndian::write_u64(&mut value, i); let tx = env.begin_rw_txn().expect("begin_rw_txn"); - tx.put( - &tx.open_db(None).unwrap(), - &value, - &value, - WriteFlags::default(), - ) - .expect("tx.put"); + tx.put(&tx.open_db(None).unwrap(), &value, &value, WriteFlags::default()).expect("tx.put"); tx.commit().expect("tx.commit"); } let tx = env.begin_rw_txn().expect("begin_rw_txn"); diff --git a/crates/libmdbx-rs/tests/transaction.rs b/crates/libmdbx-rs/tests/transaction.rs index 9d59175cb..97f90a5a3 100644 --- a/crates/libmdbx-rs/tests/transaction.rs +++ b/crates/libmdbx-rs/tests/transaction.rs @@ -126,20 +126,12 @@ fn test_nested_txn() { let env = Environment::new().open(dir.path()).unwrap(); let mut txn = env.begin_rw_txn().unwrap(); - txn.put( - &txn.open_db(None).unwrap(), - b"key1", - b"val1", - WriteFlags::empty(), - ) - .unwrap(); + txn.put(&txn.open_db(None).unwrap(), b"key1", b"val1", WriteFlags::empty()).unwrap(); { let nested = txn.begin_nested_txn().unwrap(); let db = nested.open_db(None).unwrap(); - nested - .put(&db, b"key2", b"val2", WriteFlags::empty()) - .unwrap(); + nested.put(&db, b"key2", b"val2", WriteFlags::empty()).unwrap(); assert_eq!(nested.get(&db, b"key1").unwrap(), Some(*b"val1")); assert_eq!(nested.get(&db, b"key2").unwrap(), Some(*b"val2")); } @@ -156,13 +148,7 @@ fn test_clear_db() { { let txn = env.begin_rw_txn().unwrap(); - txn.put( - &txn.open_db(None).unwrap(), - b"key", - b"val", - WriteFlags::empty(), - ) - .unwrap(); + txn.put(&txn.open_db(None).unwrap(), b"key", b"val", WriteFlags::empty()).unwrap(); assert!(!txn.commit().unwrap()); } @@ -173,10 +159,7 @@ fn test_clear_db() { } let txn = env.begin_ro_txn().unwrap(); - assert_eq!( - txn.get::<()>(&txn.open_db(None).unwrap(), b"key").unwrap(), - None - ); + assert_eq!(txn.get::<()>(&txn.open_db(None).unwrap(), b"key").unwrap(), None); } #[test] @@ -195,8 +178,7 @@ fn test_drop_db() { ) .unwrap(); // Workaround for MDBX dbi drop issue - txn.create_db(Some("canary"), DatabaseFlags::empty()) - .unwrap(); + txn.create_db(Some("canary"), DatabaseFlags::empty()).unwrap(); assert!(!txn.commit().unwrap()); } { @@ -205,10 +187,7 @@ fn test_drop_db() { unsafe { txn.drop_db(db).unwrap(); } - assert!(matches!( - txn.open_db(Some("test")).unwrap_err(), - Error::NotFound - )); + assert!(matches!(txn.open_db(Some("test")).unwrap_err(), Error::NotFound)); assert!(!txn.commit().unwrap()); } } @@ -217,10 +196,7 @@ fn test_drop_db() { let txn = env.begin_ro_txn().unwrap(); txn.open_db(Some("canary")).unwrap(); - assert!(matches!( - txn.open_db(Some("test")).unwrap_err(), - Error::NotFound - )); + assert!(matches!(txn.open_db(Some("test")).unwrap_err(), Error::NotFound)); } #[test] @@ -285,13 +261,8 @@ fn test_concurrent_writers() { threads.push(thread::spawn(move || { let txn = writer_env.begin_rw_txn().unwrap(); let db = txn.open_db(None).unwrap(); - txn.put( - &db, - &format!("{}{}", key, i), - &format!("{}{}", val, i), - WriteFlags::empty(), - ) - .unwrap(); + txn.put(&db, &format!("{}{}", key, i), &format!("{}{}", val, i), WriteFlags::empty()) + .unwrap(); txn.commit().is_ok() })); } @@ -303,9 +274,7 @@ fn test_concurrent_writers() { for i in 0..n { assert_eq!( Cow::>::Owned(format!("{}{}", val, i).into_bytes()), - txn.get(&db, format!("{}{}", key, i).as_bytes()) - .unwrap() - .unwrap() + txn.get(&db, format!("{}{}", key, i).as_bytes()).unwrap().unwrap() ); } } diff --git a/deny.toml b/deny.toml index 61a9d4849..f9f99625e 100644 --- a/deny.toml +++ b/deny.toml @@ -57,10 +57,6 @@ exceptions = [ { allow = ["CC0-1.0"], name = "tiny-keccak" }, { allow = ["CC0-1.0"], name = "more-asserts" }, - # TODO: temporarily allow libmdx - { allow = ["GPL-3.0"], name = "libmdbx" }, - { allow = ["GPL-3.0"], name = "mdbx-sys" }, - # TODO: ethers transitive deps { allow = ["GPL-3.0"], name = "fastrlp" }, { allow = ["GPL-3.0"], name = "fastrlp-derive" },