mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-11-16 15:58:14 +00:00
Storage: fix lifetimes (#215)
Some checks are pending
Audit / audit (push) Waiting to run
CI / fmt (push) Waiting to run
CI / typo (push) Waiting to run
CI / ci (macos-latest, stable, bash) (push) Waiting to run
CI / ci (ubuntu-latest, stable, bash) (push) Waiting to run
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Waiting to run
Deny / audit (push) Waiting to run
Doc / build (push) Waiting to run
Doc / deploy (push) Blocked by required conditions
Some checks are pending
Audit / audit (push) Waiting to run
CI / fmt (push) Waiting to run
CI / typo (push) Waiting to run
CI / ci (macos-latest, stable, bash) (push) Waiting to run
CI / ci (ubuntu-latest, stable, bash) (push) Waiting to run
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Waiting to run
Deny / audit (push) Waiting to run
Doc / build (push) Waiting to run
Doc / deploy (push) Blocked by required conditions
* fix db lifetimes * fix redb * fix blockchain with redb * add docs
This commit is contained in:
parent
d5c8eba1d8
commit
a82c08cc80
6 changed files with 59 additions and 61 deletions
|
@ -50,20 +50,12 @@ pub fn open(config: Config) -> Result<ConcreteEnv, InitError> {
|
|||
// we want since it is agnostic, so we are responsible for this.
|
||||
{
|
||||
let env_inner = env.env_inner();
|
||||
let tx_rw = env_inner.tx_rw();
|
||||
let tx_rw = match tx_rw {
|
||||
Ok(tx_rw) => tx_rw,
|
||||
Err(e) => return Err(runtime_to_init_error(e)),
|
||||
};
|
||||
let tx_rw = env_inner.tx_rw().map_err(runtime_to_init_error)?;
|
||||
|
||||
// Create all tables.
|
||||
if let Err(e) = OpenTables::create_tables(&env_inner, &tx_rw) {
|
||||
return Err(runtime_to_init_error(e));
|
||||
};
|
||||
OpenTables::create_tables(&env_inner, &tx_rw).map_err(runtime_to_init_error)?;
|
||||
|
||||
if let Err(e) = tx_rw.commit() {
|
||||
return Err(runtime_to_init_error(e));
|
||||
}
|
||||
TxRw::commit(tx_rw).map_err(runtime_to_init_error)?;
|
||||
}
|
||||
|
||||
Ok(env)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! TODO
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Import
|
||||
use cuprate_database::{EnvInner, RuntimeError, TxRo, TxRw};
|
||||
use cuprate_database::{EnvInner, RuntimeError};
|
||||
|
||||
use crate::tables::{TablesIter, TablesMut};
|
||||
|
||||
|
@ -84,12 +84,12 @@ pub(crate) use call_fn_on_all_tables_or_early_return;
|
|||
/// let mut tables = env_inner.open_tables_mut(&tx_rw)?;
|
||||
/// # Ok(()) }
|
||||
/// ```
|
||||
pub trait OpenTables<'env, Ro, Rw>
|
||||
where
|
||||
Self: 'env,
|
||||
Ro: TxRo<'env>,
|
||||
Rw: TxRw<'env>,
|
||||
{
|
||||
pub trait OpenTables<'env> {
|
||||
/// The read-only transaction type of the backend.
|
||||
type Ro<'a>;
|
||||
/// The read-write transaction type of the backend.
|
||||
type Rw<'a>;
|
||||
|
||||
/// Open all tables in read/iter mode.
|
||||
///
|
||||
/// This calls [`EnvInner::open_db_ro`] on all database tables
|
||||
|
@ -100,7 +100,7 @@ where
|
|||
///
|
||||
/// As all tables are created upon [`crate::open`],
|
||||
/// this function will never error because a table doesn't exist.
|
||||
fn open_tables(&'env self, tx_ro: &Ro) -> Result<impl TablesIter, RuntimeError>;
|
||||
fn open_tables(&self, tx_ro: &Self::Ro<'_>) -> Result<impl TablesIter, RuntimeError>;
|
||||
|
||||
/// Open all tables in read-write mode.
|
||||
///
|
||||
|
@ -109,7 +109,7 @@ where
|
|||
///
|
||||
/// # Errors
|
||||
/// This will only return [`RuntimeError::Io`] on errors.
|
||||
fn open_tables_mut(&'env self, tx_rw: &Rw) -> Result<impl TablesMut, RuntimeError>;
|
||||
fn open_tables_mut(&self, tx_rw: &Self::Rw<'_>) -> Result<impl TablesMut, RuntimeError>;
|
||||
|
||||
/// Create all database tables.
|
||||
///
|
||||
|
@ -118,28 +118,29 @@ where
|
|||
///
|
||||
/// # Errors
|
||||
/// This will only return [`RuntimeError::Io`] on errors.
|
||||
fn create_tables(&'env self, tx_rw: &Rw) -> Result<(), RuntimeError>;
|
||||
fn create_tables(&self, tx_rw: &Self::Rw<'_>) -> Result<(), RuntimeError>;
|
||||
}
|
||||
|
||||
impl<'env, Ei, Ro, Rw> OpenTables<'env, Ro, Rw> for Ei
|
||||
impl<'env, Ei> OpenTables<'env> for Ei
|
||||
where
|
||||
Ei: EnvInner<'env, Ro, Rw>,
|
||||
Ro: TxRo<'env>,
|
||||
Rw: TxRw<'env>,
|
||||
Ei: EnvInner<'env>,
|
||||
{
|
||||
fn open_tables(&'env self, tx_ro: &Ro) -> Result<impl TablesIter, RuntimeError> {
|
||||
type Ro<'a> = <Ei as EnvInner<'env>>::Ro<'a>;
|
||||
type Rw<'a> = <Ei as EnvInner<'env>>::Rw<'a>;
|
||||
|
||||
fn open_tables(&self, tx_ro: &Self::Ro<'_>) -> Result<impl TablesIter, RuntimeError> {
|
||||
call_fn_on_all_tables_or_early_return! {
|
||||
Self::open_db_ro(self, tx_ro)
|
||||
}
|
||||
}
|
||||
|
||||
fn open_tables_mut(&'env self, tx_rw: &Rw) -> Result<impl TablesMut, RuntimeError> {
|
||||
fn open_tables_mut(&self, tx_rw: &Self::Rw<'_>) -> Result<impl TablesMut, RuntimeError> {
|
||||
call_fn_on_all_tables_or_early_return! {
|
||||
Self::open_db_rw(self, tx_rw)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_tables(&'env self, tx_rw: &Rw) -> Result<(), RuntimeError> {
|
||||
fn create_tables(&self, tx_rw: &Self::Rw<'_>) -> Result<(), RuntimeError> {
|
||||
match call_fn_on_all_tables_or_early_return! {
|
||||
Self::create_db(self, tx_rw)
|
||||
} {
|
||||
|
|
|
@ -9,7 +9,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/storage/database"
|
|||
keywords = ["cuprate", "database"]
|
||||
|
||||
[features]
|
||||
default = ["heed"]
|
||||
# default = ["heed"]
|
||||
# default = ["redb"]
|
||||
# default = ["redb-memory"]
|
||||
heed = ["dep:heed"]
|
||||
|
|
|
@ -244,25 +244,28 @@ impl Env for ConcreteEnv {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- EnvInner Impl
|
||||
impl<'env> EnvInner<'env, heed::RoTxn<'env>, RefCell<heed::RwTxn<'env>>>
|
||||
for RwLockReadGuard<'env, heed::Env>
|
||||
impl<'env> EnvInner<'env> for RwLockReadGuard<'env, heed::Env>
|
||||
where
|
||||
Self: 'env,
|
||||
{
|
||||
type Ro<'a> = heed::RoTxn<'a>;
|
||||
|
||||
type Rw<'a> = RefCell<heed::RwTxn<'a>>;
|
||||
|
||||
#[inline]
|
||||
fn tx_ro(&'env self) -> Result<heed::RoTxn<'env>, RuntimeError> {
|
||||
fn tx_ro(&self) -> Result<Self::Ro<'_>, RuntimeError> {
|
||||
Ok(self.read_txn()?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn tx_rw(&'env self) -> Result<RefCell<heed::RwTxn<'env>>, RuntimeError> {
|
||||
fn tx_rw(&self) -> Result<Self::Rw<'_>, RuntimeError> {
|
||||
Ok(RefCell::new(self.write_txn()?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn open_db_ro<T: Table>(
|
||||
&self,
|
||||
tx_ro: &heed::RoTxn<'env>,
|
||||
tx_ro: &Self::Ro<'_>,
|
||||
) -> Result<impl DatabaseRo<T> + DatabaseIter<T>, RuntimeError> {
|
||||
// Open up a read-only database using our table's const metadata.
|
||||
//
|
||||
|
@ -280,7 +283,7 @@ where
|
|||
#[inline]
|
||||
fn open_db_rw<T: Table>(
|
||||
&self,
|
||||
tx_rw: &RefCell<heed::RwTxn<'env>>,
|
||||
tx_rw: &Self::Rw<'_>,
|
||||
) -> Result<impl DatabaseRw<T>, RuntimeError> {
|
||||
// Open up a read/write database using our table's const metadata.
|
||||
//
|
||||
|
@ -293,7 +296,7 @@ where
|
|||
})
|
||||
}
|
||||
|
||||
fn create_db<T: Table>(&self, tx_rw: &RefCell<heed::RwTxn<'env>>) -> Result<(), RuntimeError> {
|
||||
fn create_db<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> Result<(), RuntimeError> {
|
||||
// Create a database using our:
|
||||
// - [`Table`]'s const metadata.
|
||||
// - (potentially) our [`Key`] comparison function
|
||||
|
@ -325,10 +328,7 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn clear_db<T: Table>(
|
||||
&self,
|
||||
tx_rw: &mut RefCell<heed::RwTxn<'env>>,
|
||||
) -> Result<(), RuntimeError> {
|
||||
fn clear_db<T: Table>(&self, tx_rw: &mut Self::Rw<'_>) -> Result<(), RuntimeError> {
|
||||
let tx_rw = tx_rw.get_mut();
|
||||
|
||||
// Open the table. We don't care about flags or key
|
||||
|
|
|
@ -118,18 +118,20 @@ impl Env for ConcreteEnv {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- EnvInner Impl
|
||||
impl<'env> EnvInner<'env, redb::ReadTransaction, redb::WriteTransaction>
|
||||
for (&'env redb::Database, redb::Durability)
|
||||
impl<'env> EnvInner<'env> for (&'env redb::Database, redb::Durability)
|
||||
where
|
||||
Self: 'env,
|
||||
{
|
||||
type Ro<'a> = redb::ReadTransaction;
|
||||
type Rw<'a> = redb::WriteTransaction;
|
||||
|
||||
#[inline]
|
||||
fn tx_ro(&'env self) -> Result<redb::ReadTransaction, RuntimeError> {
|
||||
fn tx_ro(&self) -> Result<redb::ReadTransaction, RuntimeError> {
|
||||
Ok(self.0.begin_read()?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn tx_rw(&'env self) -> Result<redb::WriteTransaction, RuntimeError> {
|
||||
fn tx_rw(&self) -> Result<redb::WriteTransaction, RuntimeError> {
|
||||
// `redb` has sync modes on the TX level, unlike heed,
|
||||
// which sets it at the Environment level.
|
||||
//
|
||||
|
@ -142,7 +144,7 @@ where
|
|||
#[inline]
|
||||
fn open_db_ro<T: Table>(
|
||||
&self,
|
||||
tx_ro: &redb::ReadTransaction,
|
||||
tx_ro: &Self::Ro<'_>,
|
||||
) -> Result<impl DatabaseRo<T> + DatabaseIter<T>, RuntimeError> {
|
||||
// Open up a read-only database using our `T: Table`'s const metadata.
|
||||
let table: redb::TableDefinition<'static, StorableRedb<T::Key>, StorableRedb<T::Value>> =
|
||||
|
@ -154,7 +156,7 @@ where
|
|||
#[inline]
|
||||
fn open_db_rw<T: Table>(
|
||||
&self,
|
||||
tx_rw: &redb::WriteTransaction,
|
||||
tx_rw: &Self::Rw<'_>,
|
||||
) -> Result<impl DatabaseRw<T>, RuntimeError> {
|
||||
// Open up a read/write database using our `T: Table`'s const metadata.
|
||||
let table: redb::TableDefinition<'static, StorableRedb<T::Key>, StorableRedb<T::Value>> =
|
||||
|
|
|
@ -62,17 +62,17 @@ pub trait Env: Sized {
|
|||
// For `heed`, this is just `heed::Env`, for `redb` this is
|
||||
// `(redb::Database, redb::Durability)` as each transaction
|
||||
// needs the sync mode set during creation.
|
||||
type EnvInner<'env>: EnvInner<'env, Self::TxRo<'env>, Self::TxRw<'env>>
|
||||
type EnvInner<'env>: EnvInner<'env>
|
||||
where
|
||||
Self: 'env;
|
||||
|
||||
/// The read-only transaction type of the backend.
|
||||
type TxRo<'env>: TxRo<'env> + 'env
|
||||
type TxRo<'env>: TxRo<'env>
|
||||
where
|
||||
Self: 'env;
|
||||
|
||||
/// The read/write transaction type of the backend.
|
||||
type TxRw<'env>: TxRw<'env> + 'env
|
||||
type TxRw<'env>: TxRw<'env>
|
||||
where
|
||||
Self: 'env;
|
||||
|
||||
|
@ -209,23 +209,23 @@ Subsequent table opens will follow the flags/ordering, but only if
|
|||
///
|
||||
/// # Invariant
|
||||
#[doc = doc_heed_create_db_invariant!()]
|
||||
pub trait EnvInner<'env, Ro, Rw>
|
||||
where
|
||||
Self: 'env,
|
||||
Ro: TxRo<'env>,
|
||||
Rw: TxRw<'env>,
|
||||
{
|
||||
pub trait EnvInner<'env> {
|
||||
/// The read-only transaction type of the backend.
|
||||
type Ro<'a>: TxRo<'a>;
|
||||
/// The read-write transaction type of the backend.
|
||||
type Rw<'a>: TxRw<'a>;
|
||||
|
||||
/// Create a read-only transaction.
|
||||
///
|
||||
/// # Errors
|
||||
/// This will only return [`RuntimeError::Io`] if it errors.
|
||||
fn tx_ro(&'env self) -> Result<Ro, RuntimeError>;
|
||||
fn tx_ro(&self) -> Result<Self::Ro<'_>, RuntimeError>;
|
||||
|
||||
/// Create a read/write transaction.
|
||||
///
|
||||
/// # Errors
|
||||
/// This will only return [`RuntimeError::Io`] if it errors.
|
||||
fn tx_rw(&'env self) -> Result<Rw, RuntimeError>;
|
||||
fn tx_rw(&self) -> Result<Self::Rw<'_>, RuntimeError>;
|
||||
|
||||
/// Open a database in read-only mode.
|
||||
///
|
||||
|
@ -252,7 +252,7 @@ where
|
|||
#[doc = doc_heed_create_db_invariant!()]
|
||||
fn open_db_ro<T: Table>(
|
||||
&self,
|
||||
tx_ro: &Ro,
|
||||
tx_ro: &Self::Ro<'_>,
|
||||
) -> Result<impl DatabaseRo<T> + DatabaseIter<T>, RuntimeError>;
|
||||
|
||||
/// Open a database in read/write mode.
|
||||
|
@ -271,7 +271,10 @@ where
|
|||
///
|
||||
/// # Invariant
|
||||
#[doc = doc_heed_create_db_invariant!()]
|
||||
fn open_db_rw<T: Table>(&self, tx_rw: &Rw) -> Result<impl DatabaseRw<T>, RuntimeError>;
|
||||
fn open_db_rw<T: Table>(
|
||||
&self,
|
||||
tx_rw: &Self::Rw<'_>,
|
||||
) -> Result<impl DatabaseRw<T>, RuntimeError>;
|
||||
|
||||
/// Create a database table.
|
||||
///
|
||||
|
@ -282,7 +285,7 @@ where
|
|||
///
|
||||
/// # Invariant
|
||||
#[doc = doc_heed_create_db_invariant!()]
|
||||
fn create_db<T: Table>(&self, tx_rw: &Rw) -> Result<(), RuntimeError>;
|
||||
fn create_db<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> Result<(), RuntimeError>;
|
||||
|
||||
/// Clear all `(key, value)`'s from a database table.
|
||||
///
|
||||
|
@ -297,5 +300,5 @@ where
|
|||
///
|
||||
/// If the specified table is not created upon before this function is called,
|
||||
/// this will return [`RuntimeError::TableNotFound`].
|
||||
fn clear_db<T: Table>(&self, tx_rw: &mut Rw) -> Result<(), RuntimeError>;
|
||||
fn clear_db<T: Table>(&self, tx_rw: &mut Self::Rw<'_>) -> Result<(), RuntimeError>;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue