Skip to content

Commit

Permalink
Remove lifetime from Btree
Browse files Browse the repository at this point in the history
  • Loading branch information
cberner committed Dec 21, 2023
1 parent 916aff1 commit 4080f98
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 30 deletions.
22 changes: 18 additions & 4 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,21 @@ impl Database {

pub(crate) fn verify_primary_checksums(mem: Arc<TransactionalMemory>) -> Result<bool> {
let fake_freed_pages = Arc::new(Mutex::new(vec![]));
let table_tree = TableTree::new(mem.get_data_root(), mem.clone(), fake_freed_pages.clone());
let table_tree = TableTree::new(
mem.get_data_root(),
Arc::new(TransactionGuard::fake()),
mem.clone(),
fake_freed_pages.clone(),
);
if !table_tree.verify_checksums()? {
return Ok(false);
}
let system_table_tree =
TableTree::new(mem.get_system_root(), mem.clone(), fake_freed_pages.clone());
let system_table_tree = TableTree::new(
mem.get_system_root(),
Arc::new(TransactionGuard::fake()),
mem.clone(),
fake_freed_pages.clone(),
);
if !system_table_tree.verify_checksums()? {
return Ok(false);
}
Expand Down Expand Up @@ -444,7 +453,12 @@ impl Database {
oldest_unprocessed_free_transaction: TransactionId,
) -> Result {
let freed_list = Arc::new(Mutex::new(vec![]));
let table_tree = TableTree::new(system_root, mem.clone(), freed_list);
let table_tree = TableTree::new(
system_root,
Arc::new(TransactionGuard::fake()),
mem.clone(),
freed_list,
);
let fake_transaction_tracker = Arc::new(TransactionTracker::new(TransactionId::new(0)));
if let Some(savepoint_table_def) = table_tree
.get_table::<SavepointId, SerializedSavepoint>(
Expand Down
24 changes: 19 additions & 5 deletions src/multimap_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,12 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, '
name: name.to_string(),
transaction,
freed_pages: freed_pages.clone(),
tree: BtreeMut::new(table_root, mem.clone(), freed_pages),
tree: BtreeMut::new(
table_root,
transaction.transaction_guard(),
mem.clone(),
freed_pages,
),
mem,
_value_type: Default::default(),
}
Expand Down Expand Up @@ -866,6 +871,7 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, '
// Don't bother computing the checksum, since we're about to modify the tree
let mut subtree: BtreeMut<'_, V, ()> = BtreeMut::new(
Some((page_number, 0)),
self.transaction.transaction_guard(),
self.mem.clone(),
self.freed_pages.clone(),
);
Expand All @@ -883,6 +889,7 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, '
Subtree => {
let mut subtree: BtreeMut<'_, V, ()> = BtreeMut::new(
Some(guard.value().as_subtree()),
self.transaction.transaction_guard(),
self.mem.clone(),
self.freed_pages.clone(),
);
Expand Down Expand Up @@ -920,8 +927,12 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, '
self.tree
.insert(key.borrow(), &DynamicCollection::new(&inline_data))?;
} else {
let mut subtree: BtreeMut<'_, V, ()> =
BtreeMut::new(None, self.mem.clone(), self.freed_pages.clone());
let mut subtree: BtreeMut<'_, V, ()> = BtreeMut::new(
None,
self.transaction.transaction_guard(),
self.mem.clone(),
self.freed_pages.clone(),
);
subtree.insert(value.borrow(), &())?;
let (new_root, new_checksum) = subtree.get_root().unwrap();
let subtree_data =
Expand Down Expand Up @@ -1008,6 +1019,7 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbKey + 'static> MultimapTable<'db, '
Subtree => {
let mut subtree: BtreeMut<V, ()> = BtreeMut::new(
Some(v.as_subtree()),
self.transaction.transaction_guard(),
self.mem.clone(),
self.freed_pages.clone(),
);
Expand Down Expand Up @@ -1262,10 +1274,11 @@ impl<'txn> ReadOnlyUntypedMultimapTable<'txn> {

/// A read-only multimap table
pub struct ReadOnlyMultimapTable<'txn, K: RedbKey + 'static, V: RedbKey + 'static> {
tree: Btree<'txn, K, &'static DynamicCollection<V>>,
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> {
Expand All @@ -1276,10 +1289,11 @@ impl<'txn, K: RedbKey + 'static, V: RedbKey + 'static> ReadOnlyMultimapTable<'tx
mem: Arc<TransactionalMemory>,
) -> Result<ReadOnlyMultimapTable<'txn, K, V>> {
Ok(ReadOnlyMultimapTable {
tree: Btree::new(root_page, hint, mem.clone())?,
tree: Btree::new(root_page, hint, guard.clone(), mem.clone())?,
mem,
transaction_guard: guard,
_value_type: Default::default(),
_lifetime: Default::default(),
})
}
}
Expand Down
13 changes: 10 additions & 3 deletions src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ impl<'db, 'txn, K: RedbKey + 'static, V: RedbValue + 'static> Table<'db, 'txn, K
Table {
name: name.to_string(),
transaction,
tree: BtreeMut::new(table_root, mem, freed_pages),
tree: BtreeMut::new(
table_root,
transaction.transaction_guard(),
mem,
freed_pages,
),
}
}

Expand Down Expand Up @@ -414,8 +419,9 @@ impl<'txn> ReadOnlyUntypedTable<'txn> {
/// A read-only table
pub struct ReadOnlyTable<'txn, K: RedbKey + 'static, V: RedbValue + 'static> {
name: String,
tree: Btree<'txn, K, V>,
tree: Btree<K, V>,
transaction_guard: Arc<TransactionGuard>,
_lifetime: PhantomData<&'txn ()>,
}

impl<'txn, K: RedbKey + 'static, V: RedbValue + 'static> ReadOnlyTable<'txn, K, V> {
Expand All @@ -428,8 +434,9 @@ impl<'txn, K: RedbKey + 'static, V: RedbValue + 'static> ReadOnlyTable<'txn, K,
) -> Result<ReadOnlyTable<'txn, K, V>> {
Ok(ReadOnlyTable {
name,
tree: Btree::new(root_page, hint, mem)?,
tree: Btree::new(root_page, hint, guard.clone(), mem)?,
transaction_guard: guard,
_lifetime: Default::default(),
})
}
}
Expand Down
34 changes: 26 additions & 8 deletions src/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl<'db, 's, K: RedbKey + 'static, V: RedbValue + 'static> SystemTable<'db, 's,
SystemTable {
name: name.to_string(),
namespace,
tree: BtreeMut::new(table_root, mem, freed_pages),
tree: BtreeMut::new(table_root, guard.clone(), mem, freed_pages),
transaction_guard: guard,
}
}
Expand Down Expand Up @@ -457,23 +457,34 @@ impl<'db> WriteTransaction<'db> {

let tables = TableNamespace {
open_tables: Default::default(),
table_tree: TableTree::new(root_page, db.get_memory(), freed_pages.clone()),
table_tree: TableTree::new(
root_page,
guard.clone(),
db.get_memory(),
freed_pages.clone(),
),
};
let system_tables = SystemNamespace {
table_tree: TableTree::new(system_page, db.get_memory(), freed_pages.clone()),
table_tree: TableTree::new(
system_page,
guard.clone(),
db.get_memory(),
freed_pages.clone(),
),
transaction_guard: guard.clone(),
};

Ok(Self {
db,
transaction_tracker,
mem: db.get_memory(),
transaction_guard: guard,
transaction_guard: guard.clone(),
transaction_id,
tables: Mutex::new(tables),
system_tables: Mutex::new(system_tables),
freed_tree: Mutex::new(BtreeMut::new(
freed_root,
guard,
db.get_memory(),
post_commit_frees.clone(),
)),
Expand Down Expand Up @@ -682,6 +693,7 @@ impl<'db> WriteTransaction<'db> {
*self.freed_pages.lock().unwrap() = freed_pages;
self.tables.lock().unwrap().table_tree = TableTree::new(
savepoint.get_user_root(),
self.transaction_guard.clone(),
self.mem.clone(),
self.freed_pages.clone(),
);
Expand All @@ -702,6 +714,7 @@ impl<'db> WriteTransaction<'db> {

let mut freed_tree = BtreeMut::new(
savepoint.get_freed_root(),
self.transaction_guard.clone(),
self.mem.clone(),
self.post_commit_frees.clone(),
);
Expand Down Expand Up @@ -1122,8 +1135,12 @@ impl<'db> WriteTransaction<'db> {
.unwrap()
{
eprintln!("Master tree:");
let master_tree: Btree<&str, InternalTableDefinition> =
Btree::new(Some(page), PageHint::None, self.mem.clone())?;
let master_tree: Btree<&str, InternalTableDefinition> = Btree::new(
Some(page),
PageHint::None,
self.transaction_guard.clone(),
self.mem.clone(),
)?;
master_tree.print_debug(true)?;
}

Expand Down Expand Up @@ -1155,10 +1172,11 @@ pub struct ReadTransaction<'a> {
impl<'db> ReadTransaction<'db> {
pub(crate) fn new(mem: Arc<TransactionalMemory>, guard: TransactionGuard) -> Self {
let root_page = mem.get_data_root();
let guard = Arc::new(guard);
Self {
mem: mem.clone(),
tree: TableTree::new(root_page, mem, Default::default()),
transaction_guard: Arc::new(guard),
tree: TableTree::new(root_page, guard.clone(), mem, Default::default()),
transaction_guard: guard,
}
}

Expand Down
27 changes: 18 additions & 9 deletions src/tree_store/btree.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::db::TransactionGuard;
use crate::tree_store::btree_base::{
branch_checksum, leaf_checksum, BranchAccessor, BranchMutator, Checksum, LeafAccessor, BRANCH,
DEFERRED, LEAF,
Expand Down Expand Up @@ -218,6 +219,7 @@ impl UntypedBtreeMut {

pub(crate) struct BtreeMut<'a, K: RedbKey, V: RedbValue> {
mem: Arc<TransactionalMemory>,
transaction_guard: Arc<TransactionGuard>,
root: Arc<Mutex<Option<(PageNumber, Checksum)>>>,
freed_pages: Arc<Mutex<Vec<PageNumber>>>,
_key_type: PhantomData<K>,
Expand All @@ -228,11 +230,13 @@ pub(crate) struct BtreeMut<'a, K: RedbKey, V: RedbValue> {
impl<'a, K: RedbKey + 'a, V: RedbValue + 'a> BtreeMut<'a, K, V> {
pub(crate) fn new(
root: Option<(PageNumber, Checksum)>,
guard: Arc<TransactionGuard>,
mem: Arc<TransactionalMemory>,
freed_pages: Arc<Mutex<Vec<PageNumber>>>,
) -> Self {
Self {
mem,
transaction_guard: guard,
root: Arc::new(Mutex::new(root)),
freed_pages,
_key_type: Default::default(),
Expand Down Expand Up @@ -342,8 +346,13 @@ impl<'a, K: RedbKey + 'a, V: RedbValue + 'a> BtreeMut<'a, K, V> {
)
}

fn read_tree(&self) -> Result<Btree<'a, K, V>> {
Btree::new(self.get_root(), PageHint::None, self.mem.clone())
fn read_tree(&self) -> Result<Btree<K, V>> {
Btree::new(
self.get_root(),
PageHint::None,
self.transaction_guard.clone(),
self.mem.clone(),
)
}

pub(crate) fn get(&self, key: &K::SelfType<'_>) -> Result<Option<AccessGuard<'_, V>>> {
Expand Down Expand Up @@ -543,22 +552,22 @@ impl RawBtree {
}
}

pub(crate) struct Btree<'a, K: RedbKey, V: RedbValue> {
pub(crate) struct Btree<K: RedbKey, V: RedbValue> {
mem: Arc<TransactionalMemory>,
_transaction_guard: Arc<TransactionGuard>,
// Cache of the root page to avoid repeated lookups
cached_root: Option<PageImpl>,
root: Option<(PageNumber, Checksum)>,
hint: PageHint,
_key_type: PhantomData<K>,
_value_type: PhantomData<V>,
// TODO: can we remove this and replace it with a TransactionGuard?
_lifetime: PhantomData<&'a ()>,
}

impl<'a, K: RedbKey, V: RedbValue> Btree<'a, K, V> {
impl<K: RedbKey, V: RedbValue> Btree<K, V> {
pub(crate) fn new(
root: Option<(PageNumber, Checksum)>,
hint: PageHint,
guard: Arc<TransactionGuard>,
mem: Arc<TransactionalMemory>,
) -> Result<Self> {
let cached_root = if let Some((r, _)) = root {
Expand All @@ -568,20 +577,20 @@ impl<'a, K: RedbKey, V: RedbValue> Btree<'a, K, V> {
};
Ok(Self {
mem,
_transaction_guard: guard,
cached_root,
root,
hint,
_key_type: Default::default(),
_value_type: Default::default(),
_lifetime: Default::default(),
})
}

pub(crate) fn get_root(&self) -> Option<(PageNumber, Checksum)> {
self.root
}

pub(crate) fn get(&self, key: &K::SelfType<'_>) -> Result<Option<AccessGuard<'a, V>>> {
pub(crate) fn get(&self, key: &K::SelfType<'_>) -> Result<Option<AccessGuard<'static, V>>> {
if let Some(ref root_page) = self.cached_root {
self.get_helper(root_page.clone(), K::as_bytes(key).as_ref())
} else {
Expand All @@ -590,7 +599,7 @@ impl<'a, K: RedbKey, V: RedbValue> Btree<'a, K, V> {
}

// Returns the value for the queried key, if present
fn get_helper(&self, page: PageImpl, query: &[u8]) -> Result<Option<AccessGuard<'a, V>>> {
fn get_helper(&self, page: PageImpl, query: &[u8]) -> Result<Option<AccessGuard<'static, V>>> {
let node_mem = page.memory();
match node_mem[0] {
LEAF => {
Expand Down
4 changes: 3 additions & 1 deletion src/tree_store/table_tree.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::db::TransactionGuard;
use crate::error::TableError;
use crate::multimap_table::{
finalize_tree_and_subtree_checksums, multimap_btree_stats, verify_tree_and_subtree_checksums,
Expand Down Expand Up @@ -417,11 +418,12 @@ pub(crate) struct TableTree<'txn> {
impl<'txn> TableTree<'txn> {
pub(crate) fn new(
master_root: Option<(PageNumber, Checksum)>,
guard: Arc<TransactionGuard>,
mem: Arc<TransactionalMemory>,
freed_pages: Arc<Mutex<Vec<PageNumber>>>,
) -> Self {
Self {
tree: BtreeMut::new(master_root, mem.clone(), freed_pages.clone()),
tree: BtreeMut::new(master_root, guard, mem.clone(), freed_pages.clone()),
mem,
pending_table_updates: Default::default(),
freed_pages,
Expand Down

0 comments on commit 4080f98

Please sign in to comment.