b3_stable_structures/btreemap/
iter.rs1use 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
9pub(crate) enum Cursor<K: BoundedStorable + Ord + Clone> {
11 Address(Address),
12 Node { node: Node<K>, next: Index },
13}
14
15pub(crate) enum Index {
17 Child(usize),
18 Entry(usize),
19}
20
21#[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 map: &'a BTreeMap<K, V, M>,
31
32 cursors: Vec<Cursor<K>>,
34
35 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 cursors: vec![Cursor::Address(map.root_addr)],
50 range: (Bound::Unbounded, Bound::Unbounded),
51 }
52 }
53
54 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 let node = self.map.load_node(address);
90 self.cursors.push(Cursor::Node {
91 next: match node.node_type() {
92 NodeType::Internal => Index::Child(0),
94 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 self.cursors.push(Cursor::Node {
112 node,
113 next: Index::Entry(child_idx),
114 });
115
116 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 return self.next();
129 }
130
131 let (key, encoded_value) = node.entry(entry_idx, self.map.memory());
132
133 self.cursors.push(Cursor::Node {
135 next: match node.node_type() {
136 NodeType::Internal => Index::Child(entry_idx + 1),
138 NodeType::Leaf => Index::Entry(entry_idx + 1),
140 },
141 node,
142 });
143
144 if !self.range.contains(&key) {
146 self.cursors = vec![];
148 return None;
149 }
150
151 Some((key, V::from_bytes(Cow::Owned(encoded_value))))
152 }
153 None => {
154 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 for i in (0..100u64).rev() {
197 btree.insert(i, i + 1);
198 }
199
200 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}