From 5e7ee57482e2e581aa7187bbe388bbc56440148d Mon Sep 17 00:00:00 2001 From: hinto-janai Date: Sun, 24 Mar 2024 18:15:26 -0400 Subject: [PATCH] database: `redb 1.5.0` -> `redb 2.0.0` (#95) * `redb 1.5.0` -> `redb 2.0.0` * `Redb{Key,Value}` -> `redb::{Key,Value}` * redb: remove unneeded lifetimes * database: remove read table lifetime * redb: remove read table lifetime * heed: remove `'tx` lifetime on read table * remove `'env, 'tx` lifetime from read/write table * redb: remove `'env, 'tx` lifetime from read/write table * heed: remove `'env, 'tx` lifetime from read/write table * redb: update `TxRo::commit()` docs --- Cargo.lock | 4 +- database/Cargo.toml | 2 +- database/src/backend/heed/database.rs | 6 +-- database/src/backend/heed/env.rs | 12 ++--- database/src/backend/redb/database.rs | 8 ++- database/src/backend/redb/env.rs | 24 ++++----- database/src/backend/redb/storable.rs | 64 ++++++++++++------------ database/src/backend/redb/transaction.rs | 12 +++-- database/src/backend/redb/types.rs | 6 +-- database/src/database.rs | 4 +- database/src/env.rs | 10 +--- 11 files changed, 73 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b57f1e5..1207e7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2188,9 +2188,9 @@ dependencies = [ [[package]] name = "redb" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72623e6275cd430215b741f41ebda34db93a13ebde253f908b70871c46afc5ba" +checksum = "a1100a056c5dcdd4e5513d5333385223b26ef1bf92f31eb38f407e8c20549256" dependencies = [ "libc", ] diff --git a/database/Cargo.toml b/database/Cargo.toml index ac01584..a340d0d 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -37,7 +37,7 @@ rayon = { workspace = true, optional = true } # Optional features. heed = { version = "0.20.0-alpha.9", optional = true } -redb = { version = "1.5.0", optional = true } +redb = { version = "2.0.0", optional = true } serde = { workspace = true, optional = true } [dev-dependencies] diff --git a/database/src/backend/heed/database.rs b/database/src/backend/heed/database.rs index d54958f..5153f28 100644 --- a/database/src/backend/heed/database.rs +++ b/database/src/backend/heed/database.rs @@ -77,7 +77,7 @@ where } //---------------------------------------------------------------------------------------------------- DatabaseRo Impl -impl<'tx, T: Table> DatabaseRo<'tx, T> for HeedTableRo<'tx, T> { +impl DatabaseRo for HeedTableRo<'_, T> { #[inline] fn get(&self, key: &T::Key) -> Result { get::(&self.db, self.tx_ro, key) @@ -96,7 +96,7 @@ impl<'tx, T: Table> DatabaseRo<'tx, T> for HeedTableRo<'tx, T> { } //---------------------------------------------------------------------------------------------------- DatabaseRw Impl -impl<'tx, T: Table> DatabaseRo<'tx, T> for HeedTableRw<'_, 'tx, T> { +impl DatabaseRo for HeedTableRw<'_, '_, T> { #[inline] fn get(&self, key: &T::Key) -> Result { get::(&self.db, self.tx_rw, key) @@ -114,7 +114,7 @@ impl<'tx, T: Table> DatabaseRo<'tx, T> for HeedTableRw<'_, 'tx, T> { } } -impl<'env, 'tx, T: Table> DatabaseRw<'env, 'tx, T> for HeedTableRw<'env, 'tx, T> { +impl DatabaseRw for HeedTableRw<'_, '_, T> { #[inline] fn put(&mut self, key: &T::Key, value: &T::Value) -> Result<(), RuntimeError> { Ok(self.db.put(self.tx_rw, key, value)?) diff --git a/database/src/backend/heed/env.rs b/database/src/backend/heed/env.rs index 62c4f25..1bf5bee 100644 --- a/database/src/backend/heed/env.rs +++ b/database/src/backend/heed/env.rs @@ -278,10 +278,10 @@ where } #[inline] - fn open_db_ro<'tx, T: Table>( + fn open_db_ro( &self, - tx_ro: &'tx heed::RoTxn<'env>, - ) -> Result, RuntimeError> { + tx_ro: &heed::RoTxn<'env>, + ) -> Result, RuntimeError> { // Open up a read-only database using our table's const metadata. Ok(HeedTableRo { db: self @@ -292,10 +292,10 @@ where } #[inline] - fn open_db_rw<'tx, T: Table>( + fn open_db_rw( &self, - tx_rw: &'tx mut heed::RwTxn<'env>, - ) -> Result, RuntimeError> { + tx_rw: &mut heed::RwTxn<'env>, + ) -> Result, RuntimeError> { // Open up a read/write database using our table's const metadata. Ok(HeedTableRw { db: self diff --git a/database/src/backend/redb/database.rs b/database/src/backend/redb/database.rs index ab65f3f..40ea7a9 100644 --- a/database/src/backend/redb/database.rs +++ b/database/src/backend/redb/database.rs @@ -49,7 +49,7 @@ where } //---------------------------------------------------------------------------------------------------- DatabaseRo -impl<'tx, T: Table + 'static> DatabaseRo<'tx, T> for RedbTableRo<'tx, T::Key, T::Value> { +impl DatabaseRo for RedbTableRo { #[inline] fn get(&self, key: &T::Key) -> Result { get::(self, key) @@ -68,7 +68,7 @@ impl<'tx, T: Table + 'static> DatabaseRo<'tx, T> for RedbTableRo<'tx, T::Key, T: } //---------------------------------------------------------------------------------------------------- DatabaseRw -impl<'tx, T: Table + 'static> DatabaseRo<'tx, T> for RedbTableRw<'_, 'tx, T::Key, T::Value> { +impl DatabaseRo for RedbTableRw<'_, T::Key, T::Value> { #[inline] fn get(&self, key: &T::Key) -> Result { get::(self, key) @@ -86,9 +86,7 @@ impl<'tx, T: Table + 'static> DatabaseRo<'tx, T> for RedbTableRw<'_, 'tx, T::Key } } -impl<'env, 'tx, T: Table + 'static> DatabaseRw<'env, 'tx, T> - for RedbTableRw<'env, 'tx, T::Key, T::Value> -{ +impl DatabaseRw for RedbTableRw<'_, T::Key, T::Value> { // `redb` returns the value after `insert()/remove()` // we end with Ok(()) instead. diff --git a/database/src/backend/redb/env.rs b/database/src/backend/redb/env.rs index d160eed..0f4949e 100644 --- a/database/src/backend/redb/env.rs +++ b/database/src/backend/redb/env.rs @@ -48,8 +48,8 @@ impl Env for ConcreteEnv { const MANUAL_RESIZE: bool = false; const SYNCS_PER_TX: bool = false; type EnvInner<'env> = (&'env redb::Database, redb::Durability); - type TxRo<'tx> = redb::ReadTransaction<'tx>; - type TxRw<'tx> = redb::WriteTransaction<'tx>; + type TxRo<'tx> = redb::ReadTransaction; + type TxRw<'tx> = redb::WriteTransaction; #[cold] #[inline(never)] // called once. @@ -88,7 +88,7 @@ impl Env for ConcreteEnv { // /// Function that creates the tables based off the passed `T: Table`. - fn create_table(tx_rw: &redb::WriteTransaction<'_>) -> Result<(), InitError> { + fn create_table(tx_rw: &redb::WriteTransaction) -> Result<(), InitError> { println!("create_table(): {}", T::NAME); // TODO: use tracing. let table: redb::TableDefinition< @@ -155,18 +155,18 @@ impl Env for ConcreteEnv { } //---------------------------------------------------------------------------------------------------- EnvInner Impl -impl<'env> EnvInner<'env, redb::ReadTransaction<'env>, redb::WriteTransaction<'env>> +impl<'env> EnvInner<'env, redb::ReadTransaction, redb::WriteTransaction> for (&'env redb::Database, redb::Durability) where Self: 'env, { #[inline] - fn tx_ro(&'env self) -> Result, RuntimeError> { + fn tx_ro(&'env self) -> Result { Ok(self.0.begin_read()?) } #[inline] - fn tx_rw(&'env self) -> Result, RuntimeError> { + fn tx_rw(&'env self) -> Result { // `redb` has sync modes on the TX level, unlike heed, // which sets it at the Environment level. // @@ -177,10 +177,10 @@ where } #[inline] - fn open_db_ro<'tx, T: Table>( + fn open_db_ro( &self, - tx_ro: &'tx redb::ReadTransaction<'env>, - ) -> Result, RuntimeError> { + tx_ro: &redb::ReadTransaction, + ) -> Result, RuntimeError> { // Open up a read-only database using our `T: Table`'s const metadata. let table: redb::TableDefinition<'static, StorableRedb, StorableRedb> = redb::TableDefinition::new(T::NAME); @@ -190,10 +190,10 @@ where } #[inline] - fn open_db_rw<'tx, T: Table>( + fn open_db_rw( &self, - tx_rw: &'tx mut redb::WriteTransaction<'env>, - ) -> Result, RuntimeError> { + tx_rw: &mut redb::WriteTransaction, + ) -> Result, RuntimeError> { // Open up a read/write database using our `T: Table`'s const metadata. let table: redb::TableDefinition<'static, StorableRedb, StorableRedb> = redb::TableDefinition::new(T::NAME); diff --git a/database/src/backend/redb/storable.rs b/database/src/backend/redb/storable.rs index 4a6b8f9..64e7d06 100644 --- a/database/src/backend/redb/storable.rs +++ b/database/src/backend/redb/storable.rs @@ -3,7 +3,7 @@ //---------------------------------------------------------------------------------------------------- Use use std::{any::Any, borrow::Cow, cmp::Ordering, fmt::Debug, marker::PhantomData}; -use redb::{RedbKey, RedbValue, TypeName}; +use redb::TypeName; use crate::{key::Key, storable::Storable}; @@ -17,9 +17,9 @@ pub(super) struct StorableRedb(PhantomData) where T: Storable; -//---------------------------------------------------------------------------------------------------- RedbKey -// If `Key` is also implemented, this can act as a `RedbKey`. -impl RedbKey for StorableRedb +//---------------------------------------------------------------------------------------------------- redb::Key +// If `Key` is also implemented, this can act as a `redb::Key`. +impl redb::Key for StorableRedb where T: Key + 'static, { @@ -29,8 +29,8 @@ where } } -//---------------------------------------------------------------------------------------------------- RedbValue -impl RedbValue for StorableRedb +//---------------------------------------------------------------------------------------------------- redb::Value +impl redb::Value for StorableRedb where T: Storable + 'static, { @@ -77,7 +77,7 @@ mod test { // - make sure the right function is being called #[test] - /// Assert `RedbKey::compare` works for `StorableRedb`. + /// Assert `redb::Key::compare` works for `StorableRedb`. fn compare() { fn test(left: T, right: T, expected: Ordering) where @@ -85,9 +85,9 @@ mod test { { println!("left: {left:?}, right: {right:?}, expected: {expected:?}"); assert_eq!( - as RedbKey>::compare( - as RedbValue>::as_bytes(&left), - as RedbValue>::as_bytes(&right) + as redb::Key>::compare( + as redb::Value>::as_bytes(&left), + as redb::Value>::as_bytes(&right) ), expected ); @@ -100,13 +100,13 @@ mod test { } #[test] - /// Assert `RedbKey::fixed_width` is accurate. + /// Assert `redb::Key::fixed_width` is accurate. fn fixed_width() { fn test(expected: Option) where T: Storable + 'static, { - assert_eq!( as RedbValue>::fixed_width(), expected); + assert_eq!( as redb::Value>::fixed_width(), expected); } test::<()>(Some(0)); @@ -127,14 +127,14 @@ mod test { } #[test] - /// Assert `RedbKey::as_bytes` is accurate. + /// Assert `redb::Key::as_bytes` is accurate. fn as_bytes() { fn test(t: &T, expected: &[u8]) where T: Storable + 'static, { println!("t: {t:?}, expected: {expected:?}"); - assert_eq!( as RedbValue>::as_bytes(t), expected); + assert_eq!( as redb::Value>::as_bytes(t), expected); } test::<()>(&(), &[]); @@ -155,7 +155,7 @@ mod test { } #[test] - /// Assert `RedbKey::from_bytes` is accurate. + /// Assert `redb::Key::from_bytes` is accurate. fn from_bytes() { fn test(bytes: &[u8], expected: &T) where @@ -163,7 +163,7 @@ mod test { { println!("bytes: {bytes:?}, expected: {expected:?}"); assert_eq!( - & as RedbValue>::from_bytes(bytes), + & as redb::Value>::from_bytes(bytes), expected ); } @@ -186,27 +186,27 @@ mod test { } #[test] - /// Assert `RedbKey::type_name` returns unique names. + /// Assert `redb::Key::type_name` returns unique names. /// The name itself isn't tested, the invariant is that /// they are all unique. fn type_name() { // Can't use a proper set because `redb::TypeName: !Ord`. let set = [ - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - > as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), - as RedbValue>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + > as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), + as redb::Value>::type_name(), ]; // Check every permutation is unique. diff --git a/database/src/backend/redb/transaction.rs b/database/src/backend/redb/transaction.rs index 758a11a..21a22ec 100644 --- a/database/src/backend/redb/transaction.rs +++ b/database/src/backend/redb/transaction.rs @@ -9,17 +9,21 @@ use crate::{ }; //---------------------------------------------------------------------------------------------------- TxRo -impl TxRo<'_> for redb::ReadTransaction<'_> { +impl TxRo<'_> for redb::ReadTransaction { /// This function is infallible. fn commit(self) -> Result<(), RuntimeError> { - // `redb`'s read transactions cleanup in their `drop()`, there is no `commit()`. - // https://docs.rs/redb/latest/src/redb/transactions.rs.html#1258-1265 + // `redb`'s read transactions cleanup automatically when all references are dropped. + // + // There is `close()`: + // + // but this will error if there are outstanding references, i.e. an open table. + // This is unwanted behavior in our case, so we don't call this. Ok(()) } } //---------------------------------------------------------------------------------------------------- TxRw -impl TxRw<'_> for redb::WriteTransaction<'_> { +impl TxRw<'_> for redb::WriteTransaction { fn commit(self) -> Result<(), RuntimeError> { Ok(self.commit()?) } diff --git a/database/src/backend/redb/types.rs b/database/src/backend/redb/types.rs index 54062ef..1890af1 100644 --- a/database/src/backend/redb/types.rs +++ b/database/src/backend/redb/types.rs @@ -5,9 +5,7 @@ use crate::{backend::redb::storable::StorableRedb, table::Table}; //---------------------------------------------------------------------------------------------------- Types /// The concrete type for readable `redb` tables. -pub(super) type RedbTableRo<'env, K, V> = - redb::ReadOnlyTable<'env, StorableRedb, StorableRedb>; +pub(super) type RedbTableRo = redb::ReadOnlyTable, StorableRedb>; /// The concrete type for readable/writable `redb` tables. -pub(super) type RedbTableRw<'env, 'tx, K, V> = - redb::Table<'env, 'tx, StorableRedb, StorableRedb>; +pub(super) type RedbTableRw<'tx, K, V> = redb::Table<'tx, StorableRedb, StorableRedb>; diff --git a/database/src/database.rs b/database/src/database.rs index 67fbaaa..c94896d 100644 --- a/database/src/database.rs +++ b/database/src/database.rs @@ -18,7 +18,7 @@ use crate::{ /// /// This is a read-only database table, /// write operations are defined in [`DatabaseRw`]. -pub trait DatabaseRo<'tx, T: Table> { +pub trait DatabaseRo { /// Get the value corresponding to a key. /// /// The returned value is _owned_. @@ -51,7 +51,7 @@ pub trait DatabaseRo<'tx, T: Table> { /// Database (key-value store) read/write abstraction. /// /// All [`DatabaseRo`] functions are also callable by [`DatabaseRw`]. -pub trait DatabaseRw<'env, 'tx, T: Table>: DatabaseRo<'tx, T> { +pub trait DatabaseRw: DatabaseRo { /// Insert a key-value pair into the database. /// /// This will overwrite any existing key-value pairs. diff --git a/database/src/env.rs b/database/src/env.rs index cac0a8d..c815d0b 100644 --- a/database/src/env.rs +++ b/database/src/env.rs @@ -199,10 +199,7 @@ where /// As [`Table`] is `Sealed`, and all tables are created /// upon [`Env::open`], this function will never error because /// a table doesn't exist. - fn open_db_ro<'tx, T: Table>( - &self, - tx_ro: &'tx Ro, - ) -> Result, RuntimeError>; + fn open_db_ro(&self, tx_ro: &Ro) -> Result, RuntimeError>; /// Open a database in read/write mode. /// @@ -216,8 +213,5 @@ where /// As [`Table`] is `Sealed`, and all tables are created /// upon [`Env::open`], this function will never error because /// a table doesn't exist. - fn open_db_rw<'tx, T: Table>( - &self, - tx_rw: &'tx mut Rw, - ) -> Result, RuntimeError>; + fn open_db_rw(&self, tx_rw: &mut Rw) -> Result, RuntimeError>; }