Skip to content

Commit

Permalink
Implement Iterator for RangeIter
Browse files Browse the repository at this point in the history
  • Loading branch information
cberner committed Oct 10, 2022
1 parent 3ce2569 commit 754e361
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 116 deletions.
9 changes: 4 additions & 5 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,9 @@ impl Database {
}

// Iterate over all other tables
let mut iter: BtreeRangeIter<str, InternalTableDefinition> =
let iter: BtreeRangeIter<str, InternalTableDefinition> =
BtreeRangeIter::new::<RangeFull, str>(.., Some(root), mem);
while let Some(entry) = iter.next() {
for entry in iter {
let definition = InternalTableDefinition::from_bytes(entry.value());
if let Some((table_root, table_checksum)) = definition.get_root() {
if !RawBtree::new(
Expand Down Expand Up @@ -330,11 +330,11 @@ impl Database {
mem.mark_pages_allocated(master_pages_iter)?;

// Iterate over all other tables
let mut iter: BtreeRangeIter<str, InternalTableDefinition> =
let iter: BtreeRangeIter<str, InternalTableDefinition> =
BtreeRangeIter::new::<RangeFull, str>(.., Some(root), &mem);

// Chain all the other tables to the master table iter
while let Some(entry) = iter.next() {
for entry in iter {
let definition = InternalTableDefinition::from_bytes(entry.value());
if let Some((table_root, _)) = definition.get_root() {
let table_pages_iter = AllPageNumbersBtreeIter::new(
Expand Down Expand Up @@ -365,7 +365,6 @@ impl Database {
}
}
}
drop(iter);

mem.end_repair()?;

Expand Down
31 changes: 19 additions & 12 deletions src/multimap_table.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::multimap_table::DynamicCollectionType::{Inline, Subtree};
use crate::tree_store::{
AllPageNumbersBtreeIter, Btree, BtreeMut, BtreeRangeIter, Checksum, LeafAccessor, LeafKeyIter,
Page, PageNumber, RawLeafBuilder, TransactionalMemory, BRANCH, LEAF,
AllPageNumbersBtreeIter, Btree, BtreeMut, BtreeRangeIter, Checksum, EntryAccessor,
LeafAccessor, LeafKeyIter, Page, PageNumber, RawLeafBuilder, TransactionalMemory, BRANCH, LEAF,
};
use crate::types::{
AsBytesWithLifetime, OwnedLifetime, RedbKey, RedbValue, RefAsBytesLifetime, WithLifetime,
Expand Down Expand Up @@ -195,35 +195,37 @@ impl DynamicCollection {
}
}

enum ValueIterState<'a, V: RedbKey + ?Sized + 'a> {
Subtree(BtreeRangeIter<'a, V, ()>),
enum ValueIterState<'a> {
Subtree(Box<dyn DoubleEndedIterator<Item = EntryAccessor<'a>> + 'a>),
InlineLeaf(LeafKeyIter),
}

impl<'a, V: RedbKey + ?Sized + 'a> ValueIterState<'a, V> {
impl<'a> ValueIterState<'a> {
fn reverse(self) -> Self {
match self {
ValueIterState::Subtree(iter) => ValueIterState::Subtree(iter.reverse()),
ValueIterState::Subtree(iter) => ValueIterState::Subtree(Box::new(iter.rev())),
ValueIterState::InlineLeaf(iter) => ValueIterState::InlineLeaf(iter.reverse()),
}
}
}

#[doc(hidden)]
pub struct MultimapValueIter<'a, V: RedbKey + ?Sized + 'a> {
inner: ValueIterState<'a, V>,
inner: ValueIterState<'a>,
freed_pages: Option<Rc<RefCell<Vec<PageNumber>>>>,
free_on_drop: Vec<PageNumber>,
mem: Option<&'a TransactionalMemory>,
_value_type: PhantomData<V>,
}

impl<'a, V: RedbKey + ?Sized + 'a> MultimapValueIter<'a, V> {
fn new_subtree(inner: BtreeRangeIter<'a, V, ()>) -> Self {
Self {
inner: ValueIterState::Subtree(inner),
inner: ValueIterState::Subtree(Box::new(inner)),
freed_pages: None,
free_on_drop: vec![],
mem: None,
_value_type: Default::default(),
}
}

Expand All @@ -234,10 +236,11 @@ impl<'a, V: RedbKey + ?Sized + 'a> MultimapValueIter<'a, V> {
mem: &'a TransactionalMemory,
) -> Self {
Self {
inner: ValueIterState::Subtree(inner),
inner: ValueIterState::Subtree(Box::new(inner)),
freed_pages: Some(freed_pages),
free_on_drop: pages,
mem: Some(mem),
_value_type: Default::default(),
}
}

Expand All @@ -247,6 +250,7 @@ impl<'a, V: RedbKey + ?Sized + 'a> MultimapValueIter<'a, V> {
freed_pages: None,
free_on_drop: vec![],
mem: None,
_value_type: Default::default(),
}
}

Expand Down Expand Up @@ -296,16 +300,18 @@ impl<'a, V: RedbKey + ?Sized> Drop for MultimapValueIter<'a, V> {

#[doc(hidden)]
pub struct MultimapRangeIter<'a, K: RedbKey + ?Sized + 'a, V: RedbKey + ?Sized + 'a> {
inner: BtreeRangeIter<'a, K, DynamicCollection>,
inner: Box<dyn DoubleEndedIterator<Item = EntryAccessor<'a>> + 'a>,
mem: &'a TransactionalMemory,
_key_type: PhantomData<K>,
_value_type: PhantomData<V>,
}

impl<'a, K: RedbKey + ?Sized + 'a, V: RedbKey + ?Sized + 'a> MultimapRangeIter<'a, K, V> {
fn new(inner: BtreeRangeIter<'a, K, DynamicCollection>, mem: &'a TransactionalMemory) -> Self {
Self {
inner,
inner: Box::new(inner),
mem,
_key_type: Default::default(),
_value_type: Default::default(),
}
}
Expand All @@ -330,8 +336,9 @@ impl<'a, K: RedbKey + ?Sized + 'a, V: RedbKey + ?Sized + 'a> MultimapRangeIter<'

pub fn rev(self) -> Self {
Self {
inner: self.inner.reverse(),
inner: Box::new(self.inner.rev()),
mem: self.mem,
_key_type: Default::default(),
_value_type: Default::default(),
}
}
Expand Down
32 changes: 20 additions & 12 deletions src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,17 +195,15 @@ impl<'a, K: RedbKey + ?Sized + 'a, V: RedbValue + ?Sized + 'a> RangeIter<'a, K,
fn new(inner: BtreeRangeIter<'a, K, V>) -> Self {
Self { inner }
}
}

// TODO: Simplify this when GATs are stable
#[allow(clippy::type_complexity)]
// TODO: implement Iter when GATs are stable
#[allow(clippy::should_implement_trait)]
pub fn next(
&mut self,
) -> Option<(
<<K as RedbValue>::View as WithLifetime>::Out,
<<V as RedbValue>::View as WithLifetime>::Out,
)> {
impl<'a, K: RedbKey + ?Sized + 'a, V: RedbValue + ?Sized + 'a> Iterator for RangeIter<'a, K, V> {
type Item = (
<<K as RedbValue>::View as WithLifetime<'a>>::Out,
<<V as RedbValue>::View as WithLifetime<'a>>::Out,
);

fn next(&mut self) -> Option<Self::Item> {
if let Some(entry) = self.inner.next() {
let key = K::from_bytes(entry.key());
let value = V::from_bytes(entry.value());
Expand All @@ -214,9 +212,19 @@ impl<'a, K: RedbKey + ?Sized + 'a, V: RedbValue + ?Sized + 'a> RangeIter<'a, K,
None
}
}
}

pub fn rev(self) -> Self {
Self::new(self.inner.reverse())
impl<'a, K: RedbKey + ?Sized + 'a, V: RedbValue + ?Sized + 'a> DoubleEndedIterator
for RangeIter<'a, K, V>
{
fn next_back(&mut self) -> Option<Self::Item> {
if let Some(entry) = self.inner.next_back() {
let key = K::from_bytes(entry.key());
let value = V::from_bytes(entry.value());
Some((key, value))
} else {
None
}
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,9 @@ impl<'db> WriteTransaction<'db> {
};
let mut freed_tree = BtreeMut::new(freed_root, db.get_memory(), freed_pages.clone());
let mut to_remove = vec![];
let mut iter = freed_tree.range(..lookup_key)?;
while let Some(entry) = iter.next() {
for entry in freed_tree.range(..lookup_key)? {
to_remove.push(FreedTableKey::from_bytes(entry.key()));
}
drop(iter);
for key in to_remove {
// Safety: all references to the freed table above have already been dropped.
unsafe { freed_tree.remove(&key)? };
Expand Down Expand Up @@ -447,8 +445,7 @@ impl<'db> WriteTransaction<'db> {
};

let mut to_remove = vec![];
let mut iter = self.freed_tree.range(..lookup_key)?;
while let Some(entry) = iter.next() {
for entry in self.freed_tree.range(..lookup_key)? {
to_remove.push(FreedTableKey::from_bytes(entry.key()));
let value = entry.value();
let length: usize = u64::from_le_bytes(value[..size_of::<u64>()].try_into().unwrap())
Expand All @@ -464,7 +461,6 @@ impl<'db> WriteTransaction<'db> {
}
}
}
drop(iter);

// Remove all the old transactions
for key in to_remove {
Expand Down
Loading

0 comments on commit 754e361

Please sign in to comment.