From fb125b4b38f9434f56af35c0c27c5804feed3b44 Mon Sep 17 00:00:00 2001 From: Christopher Berner Date: Mon, 20 Jan 2025 20:32:54 -0800 Subject: [PATCH] Optimize retain() and retain_in() Previously all freed pages went through the transactional free mechanism. This commit changes it to reuse dirty pages --- src/tree_store/btree.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tree_store/btree.rs b/src/tree_store/btree.rs index a675bd1a..05c1d7f6 100644 --- a/src/tree_store/btree.rs +++ b/src/tree_store/btree.rs @@ -541,6 +541,8 @@ impl BtreeMut<'_, K, V> { { let iter = self.range(&range)?; let mut freed = vec![]; + // Do not modify the existing tree, because we're iterating over it concurrently with the removals + // TODO: optimize this to iterate and remove at the same time let mut operation: MutateHelper<'_, '_, K, V> = MutateHelper::new_do_not_modify(&mut self.root, self.mem.clone(), &mut freed); for entry in iter { @@ -549,7 +551,12 @@ impl BtreeMut<'_, K, V> { assert!(operation.delete(&entry.key())?.is_some()); } } - self.freed_pages.lock().unwrap().extend_from_slice(&freed); + let mut freed_pages = self.freed_pages.lock().unwrap(); + for page in freed { + if !self.mem.free_if_uncommitted(page) { + freed_pages.push(page); + } + } Ok(()) }