1use safe_bump::Idx;
4
5use crate::node::{self, Entry, Node};
6use crate::store::ChampStore;
7
8pub struct Iter<'a, K, V> {
10 entries: Vec<(&'a K, &'a V)>,
11 pos: usize,
12}
13
14impl<'a, K, V> Iter<'a, K, V> {
15 pub fn new<S: ChampStore<K, V>>(store: &'a S, root: Option<Idx<Node<K, V>>>) -> Self {
17 let mut entries = Vec::new();
18 if let Some(idx) = root {
19 collect(store, idx, &mut entries);
20 }
21 Self { entries, pos: 0 }
22 }
23}
24
25impl<'a, K, V> Iterator for Iter<'a, K, V> {
26 type Item = (&'a K, &'a V);
27
28 fn next(&mut self) -> Option<Self::Item> {
29 if self.pos < self.entries.len() {
30 let item = self.entries[self.pos];
31 self.pos += 1;
32 Some(item)
33 } else {
34 None
35 }
36 }
37
38 fn size_hint(&self) -> (usize, Option<usize>) {
39 let remaining = self.entries.len() - self.pos;
40 (remaining, Some(remaining))
41 }
42}
43
44impl<K, V> ExactSizeIterator for Iter<'_, K, V> {}
45
46fn collect<'a, K, V, S: ChampStore<K, V>>(
48 store: &'a S,
49 node_idx: Idx<Node<K, V>>,
50 out: &mut Vec<(&'a K, &'a V)>,
51) {
52 match *store.get_node(node_idx) {
53 Node::Inner {
54 data_map,
55 node_map,
56 data_start,
57 children_start,
58 ..
59 } => {
60 let data_len = data_map.count_ones() as usize;
61 let children_len = node_map.count_ones() as usize;
62
63 for i in 0..data_len {
64 let e: &'a Entry<K, V> = store.get_entry(node::offset(data_start, i));
65 out.push((&e.key, &e.value));
66 }
67
68 for i in 0..children_len {
69 let child = *store.get_child(node::offset(children_start, i));
70 collect(store, child, out);
71 }
72 }
73 Node::Collision {
74 entries_start,
75 entries_len,
76 ..
77 } => {
78 for i in 0..usize::from(entries_len) {
79 let e: &'a Entry<K, V> = store.get_entry(node::offset(entries_start, i));
80 out.push((&e.key, &e.value));
81 }
82 }
83 }
84}