use super::cursor::{Ptr, HT_CAPACITY, MAX_HEIGHT};
use std::collections::VecDeque;
use std::fmt::Debug;
use std::hash::Hash;
use std::marker::PhantomData;
pub struct Iter<'a, K, V>
where
K: Hash + Eq + Clone + Debug,
V: Clone,
{
length: usize,
stack: VecDeque<(usize, Ptr)>,
k: PhantomData<&'a K>,
v: PhantomData<&'a V>,
}
impl<'a, K: Clone + Hash + Eq + Debug, V: Clone> Iter<'a, K, V> {
pub(crate) fn new(root: Ptr, length: usize) -> Self {
let mut stack = VecDeque::with_capacity(MAX_HEIGHT as usize);
stack.push_back((0, root));
Iter {
length,
stack,
k: PhantomData,
v: PhantomData,
}
}
}
impl<'a, K: Clone + Hash + Eq + Debug, V: Clone> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
if self.stack.is_empty() {
return None;
}
'outer: loop {
if let Some((mut idx, tgt_ptr)) = self.stack.pop_back() {
if tgt_ptr.is_bucket() {
let v = &(tgt_ptr.as_bucket::<K, V>()[idx].v) as *const V;
let k = &(tgt_ptr.as_bucket::<K, V>()[idx].k) as *const K;
idx += 1;
if idx < tgt_ptr.as_bucket::<K, V>().len() {
self.stack.push_back((idx, tgt_ptr));
}
return Some(unsafe { (&*k as &K, &*v as &V) });
} else {
debug_assert!(tgt_ptr.is_branch());
let brch = tgt_ptr.as_branch::<K, V>();
while idx < HT_CAPACITY {
let interest_ptr = brch.nodes[idx];
idx += 1;
if !interest_ptr.is_null() {
self.stack.push_back((idx, tgt_ptr));
self.stack.push_back((0, interest_ptr));
continue 'outer;
}
}
}
} else {
return None;
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.length, Some(self.length))
}
}
pub struct KeyIter<'a, K, V>
where
K: Hash + Eq + Clone + Debug,
V: Clone,
{
iter: Iter<'a, K, V>,
}
impl<'a, K: Clone + Hash + Eq + Debug, V: Clone> KeyIter<'a, K, V> {
pub(crate) fn new(root: Ptr, length: usize) -> Self {
KeyIter {
iter: Iter::new(root, length),
}
}
}
impl<'a, K: Clone + Hash + Eq + Debug, V: Clone> Iterator for KeyIter<'a, K, V> {
type Item = &'a K;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
pub struct ValueIter<'a, K, V>
where
K: Hash + Eq + Clone + Debug,
V: Clone,
{
iter: Iter<'a, K, V>,
}
impl<'a, K: Clone + Hash + Eq + Debug, V: Clone> ValueIter<'a, K, V> {
pub(crate) fn new(root: Ptr, length: usize) -> Self {
ValueIter {
iter: Iter::new(root, length),
}
}
}
impl<'a, K: Clone + Hash + Eq + Debug, V: Clone> Iterator for ValueIter<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(_, v)| v)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}