space_partitioning/interval_tree/
inorder_iterator.rs

1//! Provides an `Iterator` that yields elements in order of interval starting points.
2use crate::interval_tree::interval::IntervalType;
3use crate::interval_tree::interval_tree_node::{ChildNode, IntervalTreeNode};
4use crate::interval_tree::IntervalTreeEntry;
5
6#[derive(Debug)]
7enum State<'a, T, D>
8where
9    T: IntervalType,
10{
11    Initial,
12    EmitLeft(Box<InorderIterator<'a, T, D>>),
13    EmitSelf,
14    EmitRight(Box<InorderIterator<'a, T, D>>),
15    Done,
16}
17
18#[derive(Debug)]
19pub struct InorderIterator<'a, T, D>
20where
21    T: IntervalType,
22{
23    root: Option<&'a IntervalTreeNode<T, D>>,
24    current_state: State<'a, T, D>,
25}
26
27impl<'a, T, D> InorderIterator<'a, T, D>
28where
29    T: IntervalType,
30{
31    pub(crate) fn new(root: &'a IntervalTreeNode<T, D>) -> Self {
32        Self {
33            root: Some(root),
34            current_state: State::Initial,
35        }
36    }
37
38    pub(crate) fn empty() -> Self {
39        Self {
40            root: None,
41            current_state: State::Done,
42        }
43    }
44}
45
46impl<'a, T, D> Iterator for InorderIterator<'a, T, D>
47where
48    T: IntervalType,
49{
50    type Item = &'a IntervalTreeEntry<T, D>;
51
52    fn next(&mut self) -> Option<Self::Item> {
53        if self.root.is_none() {
54            return None;
55        }
56
57        let root = self.root.unwrap();
58
59        loop {
60            match &mut self.current_state {
61                // The initial state is entered always.
62                State::Initial => {
63                    if let Some(left) = &root.left {
64                        let iter = left.iter_inorder();
65                        self.current_state = State::EmitLeft(Box::new(iter))
66                    } else {
67                        self.current_state = State::EmitSelf;
68                    }
69                }
70                // Only happens when there is a left child,
71                // enumerate until it is exhausted.
72                State::EmitLeft(iter) => {
73                    if let Some(value) = iter.next() {
74                        return Some(value);
75                    }
76                    self.current_state = State::EmitSelf;
77                }
78                // The "self" state is entered always.
79                State::EmitSelf => {
80                    if let Some(right) = &root.right {
81                        let iter = right.iter_inorder();
82                        self.current_state = State::EmitRight(Box::new(iter));
83                    } else {
84                        self.current_state = State::Done;
85                    }
86                    return Some(&root.entry);
87                }
88                // Only happens when there is a right child,
89                // enumerate until it is exhausted.
90                State::EmitRight(iter) => {
91                    if let Some(value) = iter.next() {
92                        return Some(value);
93                    }
94                    self.current_state = State::Done;
95                }
96                // The "Done" state is entered last.
97                State::Done => {
98                    return None;
99                }
100            }
101        }
102    }
103
104    fn size_hint(&self) -> (usize, Option<usize>) {
105        if self.root.is_none() {
106            return (0, None);
107        }
108
109        let size = self.root.unwrap().len();
110        return (size, Some(size));
111    }
112
113    fn count(self) -> usize
114    where
115        Self: Sized,
116    {
117        if let Some(node) = self.root {
118            node.len()
119        } else {
120            0
121        }
122    }
123
124    fn last(self) -> Option<Self::Item> {
125        if self.root.is_none() {
126            return None;
127        }
128
129        let mut token = self.root.unwrap();
130
131        while token.right.is_some() {
132            token = token.right.as_ref().unwrap();
133        }
134
135        Some(&token.entry)
136    }
137
138    fn for_each<F>(self, mut f: F)
139    where
140        F: FnMut(Self::Item),
141    {
142        fn inorder<'a, T, D, F>(node: &'a IntervalTreeNode<T, D>, f: &mut F)
143        where
144            F: FnMut(&'a IntervalTreeEntry<T, D>),
145            T: IntervalType,
146        {
147            inorder_child(&node.left, f);
148            (*f)(&node.entry);
149            inorder_child(&node.right, f);
150        }
151
152        fn inorder_child<'a, T, D, F>(node: &'a ChildNode<T, D>, f: &mut F)
153        where
154            F: FnMut(&'a IntervalTreeEntry<T, D>),
155            T: IntervalType,
156        {
157            if node.is_none() {
158                return;
159            }
160
161            inorder(&node.as_ref().unwrap(), f);
162        }
163
164        if let Some(root) = self.root {
165            inorder(&root, &mut f);
166        }
167    }
168}
169
170#[cfg(test)]
171mod test {
172    use crate::interval_tree::interval_tree_node::{test::construct_test_root_node, ChildNode};
173    use crate::interval_tree::{InorderIterator, IntervalTreeNode, IntervalType};
174
175    #[test]
176    fn size_hint_when_empty_works() {
177        let iter = InorderIterator::<i32, ()>::empty();
178        let (min, max) = iter.size_hint();
179        assert_eq!(min, 0);
180        assert_eq!(max, None);
181    }
182
183    #[test]
184    fn size_hint_works() {
185        let root = construct_test_root_node();
186        let (min, max) = root.iter_inorder().size_hint();
187        assert_eq!(min, 6);
188        assert_eq!(max, Some(6));
189    }
190
191    #[test]
192    fn count_when_empty_works() {
193        let iter = InorderIterator::<i32, ()>::empty();
194        assert_eq!(iter.count(), 0);
195    }
196
197    #[test]
198    fn count_works() {
199        let root = construct_test_root_node();
200        let count = root.iter_inorder().count();
201        assert_eq!(count, 6);
202    }
203
204    #[test]
205    fn last_works() {
206        let root = construct_test_root_node();
207        let last = root.iter_inorder().last();
208        assert!(last.is_some());
209        let last = last.unwrap();
210        assert_eq!(last.interval.start, 30);
211        assert_eq!(last.interval.end, 40);
212    }
213
214    #[test]
215    fn iteration_when_empty_works() {
216        let mut iter = InorderIterator::<i32, ()>::empty();
217        assert!(iter.next().is_none());
218    }
219
220    #[test]
221    fn iteration_works() {
222        let root = construct_test_root_node();
223
224        // Collect the expected nodes.
225        let mut expected = Vec::default();
226        collect_inorder(&root, &mut expected);
227
228        // Reverse the collection for easier handling.
229        // This allows us to pop elements from the back until
230        // the set is empty.
231        expected.reverse();
232
233        // Act / Assert
234        for node in root.iter_inorder() {
235            let expected_node = expected.pop();
236            assert!(expected_node.is_some());
237            assert_eq!(expected_node.unwrap().entry.interval, node.interval);
238        }
239    }
240
241    #[test]
242    fn for_each_works() {
243        let root = construct_test_root_node();
244
245        // Collect the expected nodes.
246        let mut expected = Vec::default();
247        collect_inorder(&root, &mut expected);
248
249        // Act
250        let mut collected = Vec::default();
251        root.iter_inorder().for_each(|node| collected.push(node));
252
253        // Assert
254        assert_eq!(expected.len(), collected.len());
255        for (expected_node, node) in expected.into_iter().zip(collected) {
256            assert_eq!(expected_node.entry.interval, node.interval);
257        }
258    }
259
260    fn collect_inorder<'a, T, D>(
261        node: &'a IntervalTreeNode<T, D>,
262        out: &mut Vec<&'a IntervalTreeNode<T, D>>,
263    ) where
264        T: IntervalType,
265    {
266        collect_inorder_child(&node.left, out);
267        out.push(node);
268        collect_inorder_child(&node.right, out);
269    }
270
271    fn collect_inorder_child<'a, T, D>(
272        node: &'a ChildNode<T, D>,
273        out: &mut Vec<&'a IntervalTreeNode<T, D>>,
274    ) where
275        T: IntervalType,
276    {
277        if node.is_none() {
278            return;
279        }
280
281        collect_inorder(&node.as_ref().unwrap(), out);
282    }
283}