use std::collections::Bound;
use crate::keys::KeyTrait;
use crate::node::{DefaultNode, Node, NodeIter};
use crate::partials::Partial;
type IterEntry<'a, P, V> = (u8, &'a DefaultNode<P, V>);
enum IterFrameIter<'a, P: Partial, V> {
Plain(NodeIter<'a, P, V>),
Leading {
first: Option<IterEntry<'a, P, V>>,
rest: NodeIter<'a, P, V>,
},
}
impl<'a, P: Partial, V> Iterator for IterFrameIter<'a, P, V> {
type Item = IterEntry<'a, P, V>;
fn next(&mut self) -> Option<Self::Item> {
match self {
IterFrameIter::Plain(iter) => iter.next(),
IterFrameIter::Leading { first, rest } => first.take().or_else(|| rest.next()),
}
}
}
pub struct Iter<'a, K: KeyTrait<PartialType = P>, P: Partial + 'a, V> {
inner: Box<dyn Iterator<Item = (K, &'a V)> + 'a>,
_marker: std::marker::PhantomData<(K, P)>,
}
struct IterInner<'a, K: KeyTrait<PartialType = P>, P: Partial + 'a, V> {
node_iter_stack: Vec<(usize, IterFrameIter<'a, P, V>)>,
cur_key: K,
start_bound: Option<Bound<K>>,
}
impl<'a, K: KeyTrait<PartialType = P>, P: Partial + 'a, V> IterInner<'a, K, P, V> {
#[inline]
fn key_order(lhs: &K, rhs: &K) -> std::cmp::Ordering {
let lhs_len = lhs.length_at(0);
let rhs_len = rhs.length_at(0);
let common = lhs_len.min(rhs_len);
for i in 0..common {
match lhs.at(i).cmp(&rhs.at(i)) {
std::cmp::Ordering::Equal => {}
ord => return ord,
}
}
lhs_len.cmp(&rhs_len)
}
fn from_node_and_key(node: &'a DefaultNode<P, V>, cur_key: K) -> Self {
let node_iter_stack = vec![(
cur_key.length_at(0),
IterFrameIter::Plain(node.iter()),
)];
Self {
node_iter_stack,
cur_key,
start_bound: None,
}
}
pub fn new(node: &'a DefaultNode<P, V>) -> Self {
Self::from_node_and_key(node, K::new_from_partial(&node.prefix))
}
pub fn new_with_start_bound(node: &'a DefaultNode<P, V>, start_bound: Bound<K>) -> Self {
let seek_key = match &start_bound {
Bound::Included(key) | Bound::Excluded(key) => Some(key),
Bound::Unbounded => None,
};
if let Some(seek_key) = seek_key {
let positioned_stack = Self::build_positioned_stack(node, seek_key, 0);
let final_stack = if positioned_stack.is_empty() {
vec![] } else {
positioned_stack
};
return Self {
node_iter_stack: final_stack,
cur_key: K::new_from_partial(&node.prefix),
start_bound: Some(start_bound.clone()),
};
}
let node_iter_stack = vec![(node.prefix.len(), IterFrameIter::Plain(node.iter()))];
Self {
node_iter_stack,
cur_key: K::new_from_partial(&node.prefix),
start_bound: None,
}
}
fn build_positioned_stack(
node: &'a DefaultNode<P, V>,
seek_key: &K,
depth: usize,
) -> Vec<(usize, IterFrameIter<'a, P, V>)> {
let prefix_common = node.prefix.prefix_length_key(seek_key, depth);
if prefix_common != node.prefix.len() {
let seek_remaining = seek_key.length_at(depth);
if prefix_common >= seek_remaining {
return vec![(node.prefix.len(), IterFrameIter::Plain(node.iter()))];
}
let node_byte = node.prefix.at(prefix_common);
let seek_byte = seek_key.at(depth + prefix_common);
if node_byte < seek_byte {
return vec![];
}
return vec![(node.prefix.len(), IterFrameIter::Plain(node.iter()))];
}
if seek_key.length_at(depth) == node.prefix.len() {
return vec![(node.prefix.len(), IterFrameIter::Plain(node.iter()))];
}
let target_depth = depth + node.prefix.len();
let target_byte = seek_key.at(target_depth);
let mut iter = node.iter();
while let Some((k, child)) = iter.next() {
if k < target_byte {
continue;
}
let positioned_iter = IterFrameIter::Leading {
first: Some((k, child)),
rest: iter,
};
return vec![(node.prefix.len(), positioned_iter)];
}
vec![]
}
}
impl<'a, K: KeyTrait<PartialType = P> + 'a, P: Partial + 'a, V> Iter<'a, K, P, V> {
fn from_root_and_children(
root_key: K,
root_value: Option<&'a V>,
children: IterInner<'a, K, P, V>,
) -> Self {
let inner: Box<dyn Iterator<Item = (K, &'a V)> + 'a> = match root_value {
Some(value) => Box::new(std::iter::once((root_key, value)).chain(children)),
None => Box::new(children),
};
Self {
inner,
_marker: Default::default(),
}
}
pub(crate) fn new(node: Option<&'a DefaultNode<P, V>>) -> Self {
let Some(root_node) = node else {
return Self {
inner: Box::new(std::iter::empty()),
_marker: Default::default(),
};
};
let root_key = K::new_from_partial(&root_node.prefix);
let root_value = root_node.value();
if root_node.is_leaf() {
return Self {
inner: Box::new(std::iter::once((
root_key,
root_value.expect("corruption: missing data at leaf node during iteration"),
))),
_marker: Default::default(),
};
}
Self::from_root_and_children(root_key, root_value, IterInner::<K, P, V>::new(root_node))
}
pub(crate) fn new_with_prefix(node: Option<&'a DefaultNode<P, V>>, root_key: K) -> Self {
let Some(root_node) = node else {
return Self {
inner: Box::new(std::iter::empty()),
_marker: Default::default(),
};
};
let root_value = root_node.value();
if root_node.is_leaf() {
return Self {
inner: Box::new(std::iter::once((
root_key,
root_value.expect("corruption: missing data at leaf node during iteration"),
))),
_marker: Default::default(),
};
}
Self::from_root_and_children(
root_key.clone(),
root_value,
IterInner::<K, P, V>::from_node_and_key(root_node, root_key),
)
}
pub(crate) fn new_with_start_bound(
node: Option<&'a DefaultNode<P, V>>,
start_bound: Bound<K>,
) -> Self {
let Some(root_node) = node else {
return Self {
inner: Box::new(std::iter::empty()),
_marker: Default::default(),
};
};
let root_key = K::new_from_partial(&root_node.prefix);
let root_value = root_node.value();
let satisfies_start = match &start_bound {
Bound::Included(start_key) => {
IterInner::<K, P, V>::key_order(&root_key, start_key) >= std::cmp::Ordering::Equal
}
Bound::Excluded(start_key) => {
IterInner::<K, P, V>::key_order(&root_key, start_key) > std::cmp::Ordering::Equal
}
Bound::Unbounded => true,
};
if root_node.is_leaf() {
if satisfies_start {
return Self {
inner: Box::new(std::iter::once((
root_key,
root_value.expect("corruption: missing data at leaf node during iteration"),
))),
_marker: Default::default(),
};
}
return Self {
inner: Box::new(std::iter::empty()),
_marker: Default::default(),
};
}
let children = IterInner::<K, P, V>::new_with_start_bound(root_node, start_bound.clone());
if satisfies_start {
return Self::from_root_and_children(root_key, root_value, children);
}
Self {
inner: Box::new(children),
_marker: Default::default(),
}
}
}
impl<'a, K: KeyTrait<PartialType = P>, P: Partial + 'a, V> Iterator for Iter<'a, K, P, V> {
type Item = (K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<'a, K: KeyTrait<PartialType = P>, P: Partial + 'a, V> Iterator for IterInner<'a, K, P, V> {
type Item = (K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
loop {
let (tree_depth, last_iter) = self.node_iter_stack.last_mut()?;
let tree_depth = *tree_depth;
let Some((_k, node)) = last_iter.next() else {
self.node_iter_stack.pop();
if let Some((parent_depth, _)) = self.node_iter_stack.last() {
self.cur_key = self.cur_key.truncate(*parent_depth);
};
continue;
};
let key = self.cur_key.extend_from_partial(&node.prefix);
if node.is_inner() {
self.node_iter_stack.push((
tree_depth + node.prefix.len(),
IterFrameIter::Plain(node.iter()),
));
self.cur_key = key.clone();
}
if let Some(v) = node.value() {
if let Some(start_bound) = self.start_bound.as_ref() {
let satisfies_start = match start_bound {
Bound::Included(start_key) => {
IterInner::<K, P, V>::key_order(&key, start_key)
>= std::cmp::Ordering::Equal
}
Bound::Excluded(start_key) => {
IterInner::<K, P, V>::key_order(&key, start_key)
> std::cmp::Ordering::Equal
}
Bound::Unbounded => true,
};
if !satisfies_start {
continue;
}
self.start_bound = None;
}
return Some((key, v));
}
continue;
}
}
}
pub struct ValuesIter<'a, P: Partial + 'a, V> {
root_value: Option<&'a V>,
node_iter_stack: Vec<NodeIter<'a, P, V>>,
}
impl<'a, P: Partial + 'a, V> ValuesIter<'a, P, V> {
pub(crate) fn new(node: Option<&'a DefaultNode<P, V>>) -> Self {
let Some(root_node) = node else {
return Self {
root_value: None,
node_iter_stack: Vec::new(),
};
};
Self {
root_value: root_node.value(),
node_iter_stack: vec![root_node.iter()],
}
}
}
impl<'a, P: Partial + 'a, V> Iterator for ValuesIter<'a, P, V> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
if let Some(value) = self.root_value.take() {
return Some(value);
}
loop {
let last_iter = self.node_iter_stack.last_mut()?;
let Some((_k, node)) = last_iter.next() else {
self.node_iter_stack.pop();
continue;
};
if node.is_inner() {
self.node_iter_stack.push(node.iter());
}
if let Some(value) = node.value() {
return Some(value);
}
}
}
}