Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify lifetimes in API #752

Merged
merged 3 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions benches/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ impl<'a> RedbBenchDatabase<'a> {
}

impl<'a> BenchDatabase for RedbBenchDatabase<'a> {
type W<'db> = RedbBenchWriteTransaction<'db> where Self: 'db;
type R<'db> = RedbBenchReadTransaction<'db> where Self: 'db;
type W<'db> = RedbBenchWriteTransaction where Self: 'db;
type R<'db> = RedbBenchReadTransaction where Self: 'db;

fn db_type_name() -> &'static str {
"redb"
Expand All @@ -103,24 +103,24 @@ impl<'a> BenchDatabase for RedbBenchDatabase<'a> {
}
}

pub struct RedbBenchReadTransaction<'db> {
txn: redb::ReadTransaction<'db>,
pub struct RedbBenchReadTransaction {
txn: redb::ReadTransaction,
}

impl<'db> BenchReadTransaction for RedbBenchReadTransaction<'db> {
type T<'txn> = RedbBenchReader<'txn> where Self: 'txn;
impl BenchReadTransaction for RedbBenchReadTransaction {
type T<'txn> = RedbBenchReader where Self: 'txn;

fn get_reader(&self) -> Self::T<'_> {
let table = self.txn.open_table(X).unwrap();
RedbBenchReader { table }
}
}

pub struct RedbBenchReader<'txn> {
table: redb::ReadOnlyTable<'txn, &'static [u8], &'static [u8]>,
pub struct RedbBenchReader {
table: redb::ReadOnlyTable<&'static [u8], &'static [u8]>,
}

impl<'txn> BenchReader for RedbBenchReader<'txn> {
impl BenchReader for RedbBenchReader {
type Output<'out> = RedbAccessGuard<'out> where Self: 'out;
type Iterator<'out> = RedbBenchIterator<'out> where Self: 'out;

Expand Down Expand Up @@ -165,12 +165,12 @@ impl<'a> AsRef<[u8]> for RedbAccessGuard<'a> {
}
}

pub struct RedbBenchWriteTransaction<'db> {
txn: redb::WriteTransaction<'db>,
pub struct RedbBenchWriteTransaction {
txn: redb::WriteTransaction,
}

impl<'db> BenchWriteTransaction for RedbBenchWriteTransaction<'db> {
type W<'txn> = RedbBenchInserter<'db, 'txn> where Self: 'txn;
impl BenchWriteTransaction for RedbBenchWriteTransaction {
type W<'txn> = RedbBenchInserter<'txn> where Self: 'txn;

fn get_inserter(&mut self) -> Self::W<'_> {
let table = self.txn.open_table(X).unwrap();
Expand All @@ -182,11 +182,11 @@ impl<'db> BenchWriteTransaction for RedbBenchWriteTransaction<'db> {
}
}

pub struct RedbBenchInserter<'db, 'txn> {
table: redb::Table<'db, 'txn, &'static [u8], &'static [u8]>,
pub struct RedbBenchInserter<'txn> {
table: redb::Table<'txn, &'static [u8], &'static [u8]>,
}

impl BenchInserter for RedbBenchInserter<'_, '_> {
impl BenchInserter for RedbBenchInserter<'_> {
fn insert(&mut self, key: &[u8], value: &[u8]) -> Result<(), ()> {
self.table.insert(key, value).map(|_| ()).map_err(|_| ())
}
Expand Down
14 changes: 7 additions & 7 deletions examples/special_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ impl SpecialValuesDb {
}

struct SpecialValuesTransaction<'db> {
inner: WriteTransaction<'db>,
inner: WriteTransaction,
file: &'db mut File,
}

impl<'db> SpecialValuesTransaction<'db> {
fn open_table<'txn, K: RedbKey + 'static, V: RedbValue + 'static>(
&'txn mut self,
fn open_table<K: RedbKey + 'static, V: RedbValue + 'static>(
&mut self,
table: TableDefinition<K, V>,
) -> SpecialValuesTable<'db, 'txn, K, V> {
) -> SpecialValuesTable<K, V> {
let def: TableDefinition<K, (u64, u64)> = TableDefinition::new(table.name());
SpecialValuesTable {
inner: self.inner.open_table(def).unwrap(),
Expand All @@ -58,13 +58,13 @@ impl<'db> SpecialValuesTransaction<'db> {
}
}

struct SpecialValuesTable<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> {
inner: Table<'db, 'txn, K, (u64, u64)>,
struct SpecialValuesTable<'txn, K: RedbKey + 'static, V: RedbValue + 'static> {
inner: Table<'txn, K, (u64, u64)>,
file: &'txn mut File,
_value_type: PhantomData<V>,
}

impl<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> SpecialValuesTable<'db, 'txn, K, V> {
impl<'txn, K: RedbKey + 'static, V: RedbValue + 'static> SpecialValuesTable<'txn, K, V> {
fn insert(&mut self, key: K::SelfType<'_>, value: V::SelfType<'_>) {
// Append to end of file
let offset = self.file.seek(SeekFrom::End(0)).unwrap();
Expand Down
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/fuzz_redb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ fn is_simulated_io_error(err: &redb::Error) -> bool {
}
}

fn exec_table_crash_support<T: Clone>(config: &FuzzConfig, apply: fn(WriteTransaction<'_>, &mut BTreeMap<u64, T>, &FuzzTransaction, &mut SavepointManager<T>) -> Result<(), redb::Error>) -> Result<(), redb::Error> {
fn exec_table_crash_support<T: Clone>(config: &FuzzConfig, apply: fn(WriteTransaction, &mut BTreeMap<u64, T>, &FuzzTransaction, &mut SavepointManager<T>) -> Result<(), redb::Error>) -> Result<(), redb::Error> {
let mut redb_file: NamedTempFile = NamedTempFile::new().unwrap();
let backend = FuzzerBackend::new(FileBackend::new(redb_file.as_file().try_clone().unwrap())?);
let countdown = backend.countdown.clone();
Expand Down Expand Up @@ -642,7 +642,7 @@ fn handle_savepoints<T: Clone>(mut txn: WriteTransaction, reference: &mut BTreeM

}

fn apply_crashable_transaction_multimap(txn: WriteTransaction<'_>, uncommitted_reference: &mut BTreeMap<u64, BTreeSet<usize>>, transaction: &FuzzTransaction, savepoints: &mut SavepointManager<BTreeSet<usize>>) -> Result<(), redb::Error> {
fn apply_crashable_transaction_multimap(txn: WriteTransaction, uncommitted_reference: &mut BTreeMap<u64, BTreeSet<usize>>, transaction: &FuzzTransaction, savepoints: &mut SavepointManager<BTreeSet<usize>>) -> Result<(), redb::Error> {
{
let mut table = txn.open_multimap_table(MULTIMAP_TABLE_DEF)?;
for op in transaction.ops.iter() {
Expand All @@ -662,7 +662,7 @@ fn apply_crashable_transaction_multimap(txn: WriteTransaction<'_>, uncommitted_r
Ok(())
}

fn apply_crashable_transaction(txn: WriteTransaction<'_>, uncommitted_reference: &mut BTreeMap<u64, usize>, transaction: &FuzzTransaction, savepoints: &mut SavepointManager<usize>) -> Result<(), redb::Error> {
fn apply_crashable_transaction(txn: WriteTransaction, uncommitted_reference: &mut BTreeMap<u64, usize>, transaction: &FuzzTransaction, savepoints: &mut SavepointManager<usize>) -> Result<(), redb::Error> {
{
let mut table = txn.open_table(TABLE_DEF)?;
for op in transaction.ops.iter() {
Expand Down
12 changes: 4 additions & 8 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ impl TransactionGuard {
self.transaction_id.unwrap()
}

fn leak(mut self) -> TransactionId {
pub(crate) fn leak(mut self) -> TransactionId {
self.transaction_id.take().unwrap()
}
}
Expand Down Expand Up @@ -768,11 +768,6 @@ impl Database {
))
}

pub(crate) fn allocate_savepoint(&self) -> Result<(SavepointId, TransactionId)> {
let id = self.transaction_tracker.allocate_savepoint();
Ok((id, self.allocate_read_transaction()?.leak()))
}

/// Convenience method for [`Builder::new`]
pub fn builder() -> Builder {
Builder::new()
Expand All @@ -788,7 +783,8 @@ impl Database {
self.transaction_tracker.start_write_transaction(),
self.transaction_tracker.clone(),
);
WriteTransaction::new(self, guard, self.transaction_tracker.clone()).map_err(|e| e.into())
WriteTransaction::new(guard, self.transaction_tracker.clone(), self.mem.clone())
.map_err(|e| e.into())
}

/// Begins a read transaction
Expand All @@ -798,7 +794,7 @@ impl Database {
///
/// Returns a [`ReadTransaction`] which may be used to read from the database. Read transactions
/// may exist concurrently with writes
pub fn begin_read(&self) -> Result<ReadTransaction<'static>, TransactionError> {
pub fn begin_read(&self) -> Result<ReadTransaction, TransactionError> {
let guard = self.allocate_read_transaction()?;
#[cfg(feature = "logging")]
info!("Beginning read transaction id={:?}", guard.id());
Expand Down
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ pub enum TransactionError {
/// Error from underlying storage
Storage(StorageError),
/// The transaction is still referenced by a table or other object
ReadTransactionStillInUse(ReadTransaction<'static>),
ReadTransactionStillInUse(ReadTransaction),
}

impl TransactionError {
Expand Down Expand Up @@ -463,7 +463,7 @@ pub enum Error {
Io(io::Error),
LockPoisoned(&'static panic::Location<'static>),
/// The transaction is still referenced by a table or other object
ReadTransactionStillInUse(ReadTransaction<'static>),
ReadTransactionStillInUse(ReadTransaction),
}

impl<T> From<PoisonError<T>> for Error {
Expand Down
44 changes: 18 additions & 26 deletions src/multimap_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -740,31 +740,29 @@ impl<'a, K: RedbKey + 'static, V: RedbKey + 'static> DoubleEndedIterator
/// A multimap table
///
/// [Multimap tables](https://en.wikipedia.org/wiki/Multimap) may have multiple values associated with each key
pub struct MultimapTable<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> {
pub struct MultimapTable<'txn, K: RedbKey + 'static, V: RedbKey + 'static> {
name: String,
transaction: &'txn WriteTransaction<'db>,
transaction: &'txn WriteTransaction,
freed_pages: Arc<Mutex<Vec<PageNumber>>>,
tree: BtreeMut<'txn, K, &'static DynamicCollection<V>>,
mem: Arc<TransactionalMemory>,
_value_type: PhantomData<V>,
}

impl<K: RedbKey + 'static, V: RedbKey + 'static> MultimapTableHandle
for MultimapTable<'_, '_, K, V>
{
impl<K: RedbKey + 'static, V: RedbKey + 'static> MultimapTableHandle for MultimapTable<'_, K, V> {
fn name(&self) -> &str {
&self.name
}
}

impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, 'txn, K, V> {
impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'txn, K, V> {
pub(crate) fn new(
name: &str,
table_root: Option<(PageNumber, Checksum)>,
freed_pages: Arc<Mutex<Vec<PageNumber>>>,
mem: Arc<TransactionalMemory>,
transaction: &'txn WriteTransaction<'db>,
) -> MultimapTable<'db, 'txn, K, V> {
transaction: &'txn WriteTransaction,
) -> MultimapTable<'txn, K, V> {
MultimapTable {
name: name.to_string(),
transaction,
Expand Down Expand Up @@ -1115,8 +1113,8 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, '
}
}

impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadableMultimapTable<K, V>
for MultimapTable<'db, 'txn, K, V>
impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadableMultimapTable<K, V>
for MultimapTable<'txn, K, V>
{
/// Returns an iterator over all values for the given key. Values are in ascending order.
fn get<'a>(&self, key: impl Borrow<K::SelfType<'a>>) -> Result<MultimapValue<V>>
Expand Down Expand Up @@ -1187,11 +1185,9 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadableMultimapTabl
}
}

impl<K: RedbKey + 'static, V: RedbKey + 'static> Sealed for MultimapTable<'_, '_, K, V> {}
impl<K: RedbKey + 'static, V: RedbKey + 'static> Sealed for MultimapTable<'_, K, V> {}

impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> Drop
for MultimapTable<'db, 'txn, K, V>
{
impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> Drop for MultimapTable<'txn, K, V> {
fn drop(&mut self) {
self.transaction.close_table(&self.name, &self.tree);
}
Expand Down Expand Up @@ -1223,15 +1219,14 @@ pub trait ReadableMultimapTable<K: RedbKey + 'static, V: RedbKey + 'static>: Sea
}

/// A read-only untyped multimap table
pub struct ReadOnlyUntypedMultimapTable<'txn> {
pub struct ReadOnlyUntypedMultimapTable {
tree: RawBtree,
fixed_key_size: Option<usize>,
fixed_value_size: Option<usize>,
mem: Arc<TransactionalMemory>,
_lifetime: PhantomData<&'txn ()>,
}

impl<'txn> ReadOnlyUntypedMultimapTable<'txn> {
impl ReadOnlyUntypedMultimapTable {
pub(crate) fn new(
root_page: Option<(PageNumber, Checksum)>,
fixed_key_size: Option<usize>,
Expand All @@ -1248,7 +1243,6 @@ impl<'txn> ReadOnlyUntypedMultimapTable<'txn> {
fixed_key_size,
fixed_value_size,
mem,
_lifetime: Default::default(),
}
}

Expand All @@ -1273,27 +1267,25 @@ impl<'txn> ReadOnlyUntypedMultimapTable<'txn> {
}

/// A read-only multimap table
pub struct ReadOnlyMultimapTable<'txn, K: RedbKey + 'static, V: RedbKey + 'static> {
pub struct ReadOnlyMultimapTable<K: RedbKey + 'static, V: RedbKey + 'static> {
tree: Btree<K, &'static DynamicCollection<V>>,
mem: Arc<TransactionalMemory>,
transaction_guard: Arc<TransactionGuard>,
_value_type: PhantomData<V>,
_lifetime: PhantomData<&'txn ()>,
}

impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadOnlyMultimapTable<'txn, K, V> {
impl<K: RedbKey + 'static, V: RedbKey + 'static> ReadOnlyMultimapTable<K, V> {
pub(crate) fn new(
root_page: Option<(PageNumber, Checksum)>,
hint: PageHint,
guard: Arc<TransactionGuard>,
mem: Arc<TransactionalMemory>,
) -> Result<ReadOnlyMultimapTable<'txn, K, V>> {
) -> Result<ReadOnlyMultimapTable<K, V>> {
Ok(ReadOnlyMultimapTable {
tree: Btree::new(root_page, hint, guard.clone(), mem.clone())?,
mem,
transaction_guard: guard,
_value_type: Default::default(),
_lifetime: Default::default(),
})
}

Expand Down Expand Up @@ -1327,8 +1319,8 @@ impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadOnlyMultimapTable<'tx
}
}

impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadableMultimapTable<K, V>
for ReadOnlyMultimapTable<'txn, K, V>
impl<K: RedbKey + 'static, V: RedbKey + 'static> ReadableMultimapTable<K, V>
for ReadOnlyMultimapTable<K, V>
{
/// Returns an iterator over all values for the given key. Values are in ascending order.
fn get<'a>(&self, key: impl Borrow<K::SelfType<'a>>) -> Result<MultimapValue<V>>
Expand Down Expand Up @@ -1395,4 +1387,4 @@ impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadableMultimapTable<K,
}
}

impl<K: RedbKey, V: RedbKey> Sealed for ReadOnlyMultimapTable<'_, K, V> {}
impl<K: RedbKey, V: RedbKey> Sealed for ReadOnlyMultimapTable<K, V> {}
Loading
Loading