use crate::{NodeLeaf, ContentTraits, TreeMetrics, Cursor, ContentTreeRaw};
use rle::{Searchable, MergeIter, merge_items};
#[derive(Debug)]
pub struct ItemIterator<'a, E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize>(pub Cursor<'a, E, I, IE, LE>);
impl<'a, E: ContentTraits + Searchable, I: TreeMetrics<E>, const IE: usize, const LE: usize> Iterator for ItemIterator<'a, E, I, IE, LE> {
type Item = E::Item;
fn next(&mut self) -> Option<Self::Item> {
if self.0.inner.idx == usize::MAX {
None
} else {
let entry = self.0.inner.get_raw_entry();
let len = entry.len();
let item = entry.at_offset(self.0.inner.offset);
self.0.inner.offset += 1;
if self.0.inner.offset >= len {
let has_next = self.0.inner.next_entry();
if !has_next {
self.0.inner.idx = usize::MAX;
}
}
Some(item)
}
}
}
#[derive(Debug)]
pub struct NodeIter<'a, E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize>(Option<&'a NodeLeaf<E, I, IE, LE>>);
impl<'a, E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> Iterator for NodeIter<'a, E, I, IE, LE> {
type Item = &'a NodeLeaf<E, I, IE, LE>;
fn next(&mut self) -> Option<Self::Item> {
if let Some(leaf) = self.0 {
let this_ref = self.0;
self.0 = leaf.next.map(|ptr| unsafe { ptr.as_ref() });
this_ref
} else { None }
}
}
impl<E: ContentTraits, I: TreeMetrics<E>, const IE: usize, const LE: usize> ContentTreeRaw<E, I, IE, LE> {
pub fn raw_iter(&self) -> Cursor<E, I, IE, LE> { self.cursor_at_start() }
pub fn iter(&self) -> MergeIter<Cursor<E, I, IE, LE>> { merge_items(self.cursor_at_start()) }
pub fn item_iter(&self) -> ItemIterator<E, I, IE, LE> {
ItemIterator(self.raw_iter())
}
pub fn node_iter(&self) -> NodeIter<E, I, IE, LE> {
let leaf_ref = self.leaf_at_start();
NodeIter(if leaf_ref.num_entries > 0 { Some(leaf_ref) } else { None })
}
}
#[cfg(test)]
mod test {
use crate::ContentTree;
use crate::testrange::TestRange;
#[test]
fn node_iter_smoke_test() {
let mut tree = ContentTree::new();
let mut iter = tree.node_iter();
assert!(iter.next().is_none());
tree.push(TestRange { id: 1000, len: 100, is_activated: true });
let mut iter = tree.node_iter();
let first = iter.next().unwrap();
assert_eq!(first.num_entries, 1);
assert!(iter.next().is_none());
}
}