sweep_bptree/tree/
iterator.rs1use std::iter::FusedIterator;
2
3use super::*;
4
5#[derive(Clone)]
9pub struct Iter<'a, S: NodeStore> {
10 tree: &'a BPlusTree<S>,
11 len: usize,
12 leaf: Option<&'a LeafNode<S::K, S::V>>,
13 leaf_offset: usize,
14
15 end: Option<(&'a LeafNode<S::K, S::V>, usize)>,
16}
17
18impl<'a, S: NodeStore> Iter<'a, S> {
19 pub(crate) fn new(tree: &'a BPlusTree<S>) -> Self {
20 let leaf = tree
21 .first_leaf()
22 .map(|leaf_id| tree.node_store.get_leaf(leaf_id));
23 Self {
24 tree,
25 len: tree.len(),
26 leaf,
27 leaf_offset: 0,
28 end: None,
29 }
30 }
31}
32
33impl<'a, S: NodeStore> Iterator for Iter<'a, S> {
34 type Item = (&'a S::K, &'a S::V);
35
36 #[inline]
37 fn size_hint(&self) -> (usize, Option<usize>) {
38 (self.len, Some(self.len))
39 }
40
41 fn next(&mut self) -> Option<Self::Item> {
42 if self.len == 0 {
43 return None;
44 }
45
46 let leaf = self.leaf?;
47 let offset = self.leaf_offset;
48 let kv = leaf.data_at(offset);
49
50 if offset + 1 < leaf.len() {
52 self.leaf_offset = offset + 1;
53 self.len -= 1;
54 Some(kv)
55 } else {
56 match leaf.next() {
57 Some(next_id) => {
58 self.leaf = Some(self.tree.node_store.get_leaf(next_id));
59 self.leaf_offset = 0;
60 }
61 None => {
62 self.leaf = None;
63 self.leaf_offset = 0;
64 }
65 }
66
67 self.len -= 1;
68 Some(kv)
69 }
70 }
71}
72
73impl<'a, S: NodeStore> DoubleEndedIterator for Iter<'a, S> {
74 fn next_back(&mut self) -> Option<Self::Item> {
75 if self.len == 0 {
76 return None;
77 }
78
79 match self.end {
80 Some((leaf, offset)) => {
81 if offset > 0 {
82 let offset = offset - 1;
83 let kv = leaf.data_at(offset);
84 self.end = Some((leaf, offset));
85 Some(kv)
86 } else {
87 let prev_id = leaf.prev()?;
89 let leaf = self.tree.node_store.get_leaf(prev_id);
90 let offset = leaf.len() - 1;
91
92 self.end = Some((leaf, offset));
93 Some(leaf.data_at(offset))
94 }
95 }
96 None => {
97 let last_leaf_id = self.tree.last_leaf()?;
98 let last_leaf = self.tree.node_store.get_leaf(last_leaf_id);
99 let last_leaf_size = last_leaf.len();
100 if last_leaf_size == 0 {
101 return None;
102 }
103
104 let offset = last_leaf_size - 1;
105
106 self.end = Some((last_leaf, offset));
107 Some(last_leaf.data_at(offset))
108 }
109 }
110 }
111}
112
113impl<'a, S: NodeStore> FusedIterator for Iter<'a, S> {}
114impl<'a, S: NodeStore> ExactSizeIterator for Iter<'a, S> {}
115
116pub struct IntoIter<S: NodeStore> {
117 node_store: S,
118 len: usize,
119 pos: (LeafNodeId, usize),
121 end: (LeafNodeId, usize),
123}
124
125impl<S: NodeStore> IntoIter<S> {
126 pub fn new(tree: BPlusTree<S>) -> Self {
127 let first_leaf_id = tree.first_leaf().unwrap();
129 let last_leaf_id = tree.last_leaf().unwrap();
130
131 let (node_store, _root_id, len) = tree.into_parts();
132
133 let last_leaf_size = node_store.get_leaf(last_leaf_id).len();
134
135 Self {
136 node_store,
137 len,
138 pos: (first_leaf_id, 0),
139 end: (last_leaf_id, last_leaf_size),
140 }
141 }
142}
143
144impl<S: NodeStore> Iterator for IntoIter<S> {
145 type Item = (S::K, S::V);
146
147 #[inline]
148 fn size_hint(&self) -> (usize, Option<usize>) {
149 (self.len, Some(self.len))
150 }
151
152 fn next(&mut self) -> Option<Self::Item> {
153 if self.len() == 0 {
154 return None;
155 }
156
157 let (leaf_id, offset) = self.pos;
158 let leaf = self.node_store.get_mut_leaf(leaf_id);
159
160 if offset < leaf.len() {
161 self.len -= 1;
163 let kv = unsafe { leaf.take_data(offset) };
167 self.pos = (leaf_id, offset + 1);
168 return Some(kv);
169 } else {
170 match leaf.next() {
172 Some(next_id) => {
173 self.pos = (next_id, 0);
174 self.next()
175 }
176 None => {
177 unreachable!()
180 }
181 }
182 }
183 }
184}
185
186impl<S: NodeStore> DoubleEndedIterator for IntoIter<S> {
187 fn next_back(&mut self) -> Option<Self::Item> {
188 if self.len() == 0 {
189 return None;
190 }
191
192 let (leaf_id, offset) = self.end;
193 let leaf = self.node_store.get_mut_leaf(leaf_id);
194
195 if offset > 0 {
196 self.len -= 1;
198 let kv = unsafe { leaf.take_data(offset - 1) };
202 self.end = (leaf_id, offset - 1);
203 return Some(kv);
204 } else {
205 match leaf.prev() {
207 Some(prev_id) => {
208 let prev_leaf = self.node_store.get_mut_leaf(prev_id);
209 self.end = (prev_id, prev_leaf.len());
210 self.next_back()
211 }
212 None => {
213 unreachable!()
215 }
216 }
217 }
218 }
219}
220
221impl<S: NodeStore> FusedIterator for IntoIter<S> {}
222impl<S: NodeStore> ExactSizeIterator for IntoIter<S> {}
223
224impl<S: NodeStore> Drop for IntoIter<S> {
225 fn drop(&mut self) {
226 while self.next().is_some() {}
228 }
229}
230
231#[cfg(test)]
232mod tests {
233 use std::rc::Rc;
234
235 use super::*;
236 use crate::tree::tests::create_test_tree;
237
238 #[derive(Clone)]
239 struct TestValue {
240 counter: Rc<std::sync::atomic::AtomicU64>,
241 }
242
243 impl TestValue {
244 fn new(counter: Rc<std::sync::atomic::AtomicU64>) -> Self {
245 Self { counter }
246 }
247 }
248
249 impl Drop for TestValue {
250 fn drop(&mut self) {
251 self.counter
252 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
253 }
254 }
255
256 #[test]
257 fn test_iter() {
258 let (tree, _) = create_test_tree::<100>();
259 let iter = Iter::new(&tree);
260 let kvs = iter.collect::<Vec<_>>();
261 assert_eq!(kvs.len(), tree.len());
262 }
263
264 #[test]
265 fn test_iter_double_ended() {
266 let (tree, _keys) = create_test_tree::<100>();
267 let kvs = Iter::new(&tree).collect::<Vec<_>>();
268 let rev_kvs = Iter::new(&tree).rev().collect::<Vec<_>>();
269
270 assert_eq!(rev_kvs.len(), kvs.len());
271 assert_eq!(rev_kvs, kvs.iter().rev().cloned().collect::<Vec<_>>());
272 }
273
274 #[test]
275 fn test_into_iter_collect() {
276 let node_store = NodeStoreVec::<i64, TestValue>::new();
278 let mut tree = BPlusTree::new(node_store);
279 let counter = Rc::new(std::sync::atomic::AtomicU64::new(0));
280 for i in 0..10 {
281 tree.insert(i, TestValue::new(counter.clone()));
282 }
283 let iter = IntoIter::new(tree);
284 let items = iter.collect::<Vec<_>>();
285 assert_eq!(items.len(), 10);
286 drop(items);
287
288 assert_eq!(counter.load(std::sync::atomic::Ordering::Relaxed), 10);
289 }
290
291 #[test]
292 fn test_into_iter_drop() {
293 let node_store = NodeStoreVec::<i64, TestValue>::new();
295 let mut tree = BPlusTree::new(node_store);
296 let counter = Rc::new(std::sync::atomic::AtomicU64::new(0));
297 for i in 0..10 {
298 tree.insert(i, TestValue::new(counter.clone()));
299 }
300 let iter = IntoIter::new(tree);
301 drop(iter);
302
303 assert_eq!(counter.load(std::sync::atomic::Ordering::Relaxed), 10);
304 }
305
306 #[test]
307 fn test_into_iter_double_ended() {
308 let node_store = NodeStoreVec::<i64, TestValue>::new();
309 let mut tree = BPlusTree::new(node_store);
310 let counter = Rc::new(std::sync::atomic::AtomicU64::new(0));
311 for i in 0..10 {
312 tree.insert(i, TestValue::new(counter.clone()));
313 }
314 let items = IntoIter::new(tree)
315 .rev()
316 .map(|(k, _v)| k)
317 .collect::<Vec<_>>();
318 assert_eq!(items.len(), 10);
319 assert_eq!(counter.load(std::sync::atomic::Ordering::Relaxed), 10);
320 assert_eq!(items, (0..10).rev().collect::<Vec<_>>());
321 }
322}