b3_stable_structures/btreemap/
iter.rs

1use super::{
2    node::{Node, NodeType},
3    BTreeMap,
4};
5use crate::{types::NULL, Address, BoundedStorable, Memory};
6use std::borrow::Cow;
7use std::ops::{Bound, RangeBounds};
8
9/// An indicator of the current position in the map.
10pub(crate) enum Cursor<K: BoundedStorable + Ord + Clone> {
11    Address(Address),
12    Node { node: Node<K>, next: Index },
13}
14
15/// An index into a node's child or entry.
16pub(crate) enum Index {
17    Child(usize),
18    Entry(usize),
19}
20
21/// An iterator over the entries of a [`BTreeMap`].
22#[must_use = "iterators are lazy and do nothing unless consumed"]
23pub struct Iter<'a, K, V, M>
24where
25    K: BoundedStorable + Ord + Clone,
26    V: BoundedStorable,
27    M: Memory,
28{
29    // A reference to the map being iterated on.
30    map: &'a BTreeMap<K, V, M>,
31
32    // A stack of cursors indicating the current position in the tree.
33    cursors: Vec<Cursor<K>>,
34
35    // The range of keys we want to traverse.
36    range: (Bound<K>, Bound<K>),
37}
38
39impl<'a, K, V, M> Iter<'a, K, V, M>
40where
41    K: BoundedStorable + Ord + Clone,
42    V: BoundedStorable,
43    M: Memory,
44{
45    pub(crate) fn new(map: &'a BTreeMap<K, V, M>) -> Self {
46        Self {
47            map,
48            // Initialize the cursors with the address of the root of the map.
49            cursors: vec![Cursor::Address(map.root_addr)],
50            range: (Bound::Unbounded, Bound::Unbounded),
51        }
52    }
53
54    /// Returns an empty iterator.
55    pub(crate) fn null(map: &'a BTreeMap<K, V, M>) -> Self {
56        Self {
57            map,
58            cursors: vec![],
59            range: (Bound::Unbounded, Bound::Unbounded),
60        }
61    }
62
63    pub(crate) fn new_in_range(
64        map: &'a BTreeMap<K, V, M>,
65        range: (Bound<K>, Bound<K>),
66        cursors: Vec<Cursor<K>>,
67    ) -> Self {
68        Self {
69            map,
70            cursors,
71            range,
72        }
73    }
74}
75
76impl<K, V, M> Iterator for Iter<'_, K, V, M>
77where
78    K: BoundedStorable + Ord + Clone,
79    V: BoundedStorable,
80    M: Memory,
81{
82    type Item = (K, V);
83
84    fn next(&mut self) -> Option<Self::Item> {
85        match self.cursors.pop() {
86            Some(Cursor::Address(address)) => {
87                if address != NULL {
88                    // Load the node at the given address, and add it to the cursors.
89                    let node = self.map.load_node(address);
90                    self.cursors.push(Cursor::Node {
91                        next: match node.node_type() {
92                            // Iterate on internal nodes starting from the first child.
93                            NodeType::Internal => Index::Child(0),
94                            // Iterate on leaf nodes starting from the first entry.
95                            NodeType::Leaf => Index::Entry(0),
96                        },
97                        node,
98                    });
99                }
100                self.next()
101            }
102
103            Some(Cursor::Node {
104                node,
105                next: Index::Child(child_idx),
106            }) => {
107                let child_address = node.child(child_idx);
108
109                // After iterating on the child, iterate on the next _entry_ in this node.
110                // The entry immediately after the child has the same index as the child's.
111                self.cursors.push(Cursor::Node {
112                    node,
113                    next: Index::Entry(child_idx),
114                });
115
116                // Add the child to the top of the cursors to be iterated on first.
117                self.cursors.push(Cursor::Address(child_address));
118
119                self.next()
120            }
121
122            Some(Cursor::Node {
123                node,
124                next: Index::Entry(entry_idx),
125            }) => {
126                if entry_idx >= node.entries_len() {
127                    // No more entries to iterate on in this node.
128                    return self.next();
129                }
130
131                let (key, encoded_value) = node.entry(entry_idx, self.map.memory());
132
133                // Add to the cursors the next element to be traversed.
134                self.cursors.push(Cursor::Node {
135                    next: match node.node_type() {
136                        // If this is an internal node, add the next child to the cursors.
137                        NodeType::Internal => Index::Child(entry_idx + 1),
138                        // If this is a leaf node, add the next entry to the cursors.
139                        NodeType::Leaf => Index::Entry(entry_idx + 1),
140                    },
141                    node,
142                });
143
144                // If the key does not belong to the range, iteration stops.
145                if !self.range.contains(&key) {
146                    // Clear all cursors to avoid needless work in subsequent calls.
147                    self.cursors = vec![];
148                    return None;
149                }
150
151                Some((key, V::from_bytes(Cow::Owned(encoded_value))))
152            }
153            None => {
154                // The cursors are empty. Iteration is complete.
155                None
156            }
157        }
158    }
159}
160
161#[cfg(test)]
162mod test {
163    use super::*;
164    use std::cell::RefCell;
165    use std::rc::Rc;
166
167    fn make_memory() -> Rc<RefCell<Vec<u8>>> {
168        Rc::new(RefCell::new(Vec::new()))
169    }
170
171    #[test]
172    fn iterate_leaf() {
173        let mem = make_memory();
174        let mut btree = BTreeMap::new(mem);
175
176        for i in 0..10u8 {
177            btree.insert(i, i + 1);
178        }
179
180        let mut i = 0;
181        for (key, value) in btree.iter() {
182            assert_eq!(key, i);
183            assert_eq!(value, i + 1);
184            i += 1;
185        }
186
187        assert_eq!(i, 10u8);
188    }
189
190    #[test]
191    fn iterate_children() {
192        let mem = make_memory();
193        let mut btree = BTreeMap::new(mem);
194
195        // Insert the elements in reverse order.
196        for i in (0..100u64).rev() {
197            btree.insert(i, i + 1);
198        }
199
200        // Iteration should be in ascending order.
201        let mut i = 0;
202        for (key, value) in btree.iter() {
203            assert_eq!(key, i);
204            assert_eq!(value, i + 1);
205            i += 1;
206        }
207
208        assert_eq!(i, 100);
209    }
210}