flat_tree/iterator.rs
1//! ## Usage
2//! ```rust
3//! let mut iter = flat_tree::Iterator::new(0);
4//! assert_eq!(iter.next(), Some(2));
5//! assert_eq!(iter.next(), Some(4));
6//! assert_eq!(iter.next(), Some(6));
7//! assert_eq!(iter.parent(), 5);
8//! ```
9use super::*;
10
11use std::iter;
12
13/// Iterator over a flat-tree.
14#[derive(Debug)]
15pub struct Iterator {
16 index: u64,
17 offset: u64,
18 factor: u64,
19}
20
21impl Iterator {
22 /// Create a new iterator.
23 ///
24 /// ## Examples
25 /// ```rust
26 /// use flat_tree::Iterator;
27 /// assert_eq!(Iterator::new(0).take(3).collect::<Vec<u64>>(), [2, 4, 6]);
28 /// ```
29 #[inline]
30 pub fn new(index: u64) -> Self {
31 let mut instance = Self {
32 index: 0,
33 offset: 0,
34 factor: 0,
35 };
36
37 instance.seek(index);
38 instance
39 }
40
41 /// Get the current index.
42 #[inline]
43 pub fn index(&self) -> u64 {
44 self.index
45 }
46
47 /// Get the current offset.
48 #[inline]
49 pub fn offset(&self) -> u64 {
50 self.offset
51 }
52
53 /// Get the current factor.
54 #[inline]
55 pub fn factor(&self) -> u64 {
56 self.factor
57 }
58
59 /// Seek to a position in the iterator.
60 ///
61 /// ## Examples
62 /// ```rust
63 /// let mut iter = flat_tree::Iterator::new(0);
64 /// iter.seek(4);
65 /// assert_eq!(iter.next(), Some(6));
66 /// iter.seek(2);
67 /// assert_eq!(iter.next(), Some(4));
68 /// ```
69 #[inline]
70 pub fn seek(&mut self, index: u64) {
71 self.index = index;
72 if is_odd(self.index) {
73 self.offset = offset(index);
74 self.factor = two_pow(depth(index) + 1);
75 } else {
76 self.offset = index / 2;
77 self.factor = 2;
78 }
79 }
80
81 /// Check if the position of the iterator is currently on a left node.
82 ///
83 /// ## Examples
84 /// ```rust
85 /// assert_eq!(flat_tree::Iterator::new(0).is_left(), true);
86 /// assert_eq!(flat_tree::Iterator::new(2).is_left(), false);
87 /// assert_eq!(flat_tree::Iterator::new(1).is_left(), true);
88 /// ```
89 #[inline]
90 pub fn is_left(&self) -> bool {
91 is_even(self.offset)
92 }
93
94 /// Check if the position of the iterator is currently on a right node.
95 ///
96 /// ## Examples
97 /// ```rust
98 /// assert_eq!(flat_tree::Iterator::new(0).is_right(), false);
99 /// assert_eq!(flat_tree::Iterator::new(2).is_right(), true);
100 /// assert_eq!(flat_tree::Iterator::new(1).is_right(), false);
101 /// ```
102 #[inline]
103 pub fn is_right(&self) -> bool {
104 is_odd(self.offset)
105 }
106
107 /// Check if the the iterator contains given index.
108 ///
109 /// ## Examples
110 /// ```rust
111 /// let iter = flat_tree::Iterator::new(3);
112 /// assert_eq!(iter.contains(0), true);
113 /// assert_eq!(iter.contains(1), true);
114 /// assert_eq!(iter.contains(2), true);
115 /// assert_eq!(iter.contains(3), true);
116 /// assert_eq!(iter.contains(4), true);
117 /// assert_eq!(iter.contains(5), true);
118 /// assert_eq!(iter.contains(6), true);
119 /// assert_eq!(iter.contains(7), false);
120 /// assert_eq!(iter.contains(8), false);
121 ///
122 /// let iter = flat_tree::Iterator::new(9);
123 /// assert_eq!(iter.contains(8), true);
124 /// assert_eq!(iter.contains(9), true);
125 /// assert_eq!(iter.contains(10), true);
126 /// assert_eq!(iter.contains(6), false);
127 /// assert_eq!(iter.contains(7), false);
128 /// assert_eq!(iter.contains(12), false);
129 /// assert_eq!(iter.contains(13), false);
130 ///
131 /// let iter = flat_tree::Iterator::new(8);
132 /// assert_eq!(iter.contains(8), true);
133 /// assert_eq!(iter.contains(6), false);
134 /// assert_eq!(iter.contains(7), false);
135 /// assert_eq!(iter.contains(9), false);
136 /// assert_eq!(iter.contains(10), false);
137 /// ```
138 #[inline]
139 #[allow(clippy::comparison_chain)]
140 pub fn contains(&self, index: u64) -> bool {
141 if index > self.index {
142 index < (self.index + self.factor / 2)
143 } else if index < self.index {
144 let comp = self.factor / 2;
145 self.index < comp || index > (self.index - comp)
146 } else {
147 true
148 }
149 }
150
151 /// Returns how many nodes are in the tree of the current position.
152 ///
153 /// ## Examples
154 /// ```rust
155 /// assert_eq!(flat_tree::Iterator::new(0).count_nodes(), 1);
156 /// assert_eq!(flat_tree::Iterator::new(1).count_nodes(), 3);
157 /// assert_eq!(flat_tree::Iterator::new(3).count_nodes(), 7);
158 /// assert_eq!(flat_tree::Iterator::new(5).count_nodes(), 3);
159 /// assert_eq!(flat_tree::Iterator::new(23).count_nodes(), 15);
160 /// assert_eq!(flat_tree::Iterator::new(27).count_nodes(), 7);
161 /// ```
162 #[inline]
163 pub fn count_nodes(&self) -> u64 {
164 if is_even(self.index) {
165 1
166 } else {
167 self.factor - 1
168 }
169 }
170
171 /// Returns how many leaves are in the tree of the current position.
172 ///
173 /// ## Examples
174 /// ```rust
175 /// assert_eq!(flat_tree::Iterator::new(0).count_leaves(), 1);
176 /// assert_eq!(flat_tree::Iterator::new(1).count_leaves(), 2);
177 /// assert_eq!(flat_tree::Iterator::new(2).count_leaves(), 1);
178 /// assert_eq!(flat_tree::Iterator::new(3).count_leaves(), 4);
179 /// assert_eq!(flat_tree::Iterator::new(5).count_leaves(), 2);
180 /// assert_eq!(flat_tree::Iterator::new(23).count_leaves(), 8);
181 /// assert_eq!(flat_tree::Iterator::new(27).count_leaves(), 4);
182 /// ```
183 #[inline]
184 pub fn count_leaves(&self) -> u64 {
185 (self.count_nodes() + 1) / 2
186 }
187
188 /// Move the cursor and get the previous item from the current position.
189 ///
190 /// ## Examples
191 /// ```rust
192 /// let mut iter = flat_tree::Iterator::new(6);
193 /// assert_eq!(iter.prev(), 4);
194 /// assert_eq!(iter.prev(), 2);
195 /// assert_eq!(iter.prev(), 0);
196 /// ```
197 #[inline]
198 pub fn prev(&mut self) -> u64 {
199 if self.offset == 0 {
200 return self.index;
201 }
202 self.offset -= 1;
203 self.index -= self.factor;
204 self.index
205 }
206
207 /// Get the sibling for the current position and move the cursor.
208 ///
209 /// ## Examples
210 /// ```rust
211 /// assert_eq!(flat_tree::Iterator::new(0).sibling(), 2);
212 /// assert_eq!(flat_tree::Iterator::new(1).sibling(), 5);
213 /// assert_eq!(flat_tree::Iterator::new(4).sibling(), 6);
214 /// ```
215 #[inline]
216 pub fn sibling(&mut self) -> u64 {
217 if self.is_left() {
218 self.next().unwrap() // this is always safe
219 } else {
220 self.prev()
221 }
222 }
223
224 /// Get the parent for the current position and move the cursor.
225 ///
226 /// ## Examples
227 /// ```rust
228 /// assert_eq!(flat_tree::Iterator::new(0).parent(), 1);
229 /// assert_eq!(flat_tree::Iterator::new(1).parent(), 3);
230 /// assert_eq!(flat_tree::Iterator::new(4).parent(), 5);
231 /// ```
232 #[inline]
233 pub fn parent(&mut self) -> u64 {
234 if is_odd(self.offset) {
235 self.index -= self.factor / 2;
236 self.offset = (self.offset - 1) / 2;
237 } else {
238 self.index += self.factor / 2;
239 self.offset /= 2;
240 }
241 self.factor *= 2;
242 self.index
243 }
244
245 /// Get the left_span for the current position and move the cursor.
246 ///
247 /// ## Examples
248 /// ```rust
249 /// assert_eq!(flat_tree::Iterator::new(0).left_span(), 0);
250 /// assert_eq!(flat_tree::Iterator::new(1).left_span(), 0);
251 /// assert_eq!(flat_tree::Iterator::new(3).left_span(), 0);
252 /// assert_eq!(flat_tree::Iterator::new(23).left_span(), 16);
253 /// assert_eq!(flat_tree::Iterator::new(27).left_span(), 24);
254 /// ```
255 #[inline]
256 pub fn left_span(&mut self) -> u64 {
257 self.index = self.index + 1 - self.factor / 2;
258 self.offset = self.index / 2;
259 self.factor = 2;
260 self.index
261 }
262
263 /// Get the right_span for the current position and move the cursor.
264 ///
265 /// ## Examples
266 /// ```rust
267 /// assert_eq!(flat_tree::Iterator::new(0).right_span(), 0);
268 /// assert_eq!(flat_tree::Iterator::new(1).right_span(), 2);
269 /// assert_eq!(flat_tree::Iterator::new(3).right_span(), 6);
270 /// assert_eq!(flat_tree::Iterator::new(23).right_span(), 30);
271 /// assert_eq!(flat_tree::Iterator::new(27).right_span(), 30);
272 /// ```
273 #[inline]
274 pub fn right_span(&mut self) -> u64 {
275 self.index = self.index + self.factor / 2 - 1;
276 self.offset = self.index / 2;
277 self.factor = 2;
278 self.index
279 }
280
281 /// Get the left_child for the current position and move the cursor.
282 ///
283 /// ## Examples
284 /// ```rust
285 /// assert_eq!(flat_tree::Iterator::new(1).left_child(), 0);
286 /// assert_eq!(flat_tree::Iterator::new(3).left_child(), 1);
287 /// assert_eq!(flat_tree::Iterator::new(7).left_child(), 3);
288 /// ```
289 #[inline]
290 pub fn left_child(&mut self) -> u64 {
291 if self.factor == 2 {
292 return self.index;
293 }
294 self.factor /= 2;
295 self.index -= self.factor / 2;
296 self.offset *= 2;
297 self.index
298 }
299
300 /// Get the right_child for the current position and move the cursor.
301 ///
302 /// ## Examples
303 /// ```rust
304 /// assert_eq!(flat_tree::Iterator::new(1).right_child(), 2);
305 /// assert_eq!(flat_tree::Iterator::new(3).right_child(), 5);
306 /// assert_eq!(flat_tree::Iterator::new(7).right_child(), 11);
307 /// ```
308 #[inline]
309 pub fn right_child(&mut self) -> u64 {
310 if self.factor == 2 {
311 return self.index;
312 }
313 self.factor /= 2;
314 self.index += self.factor / 2;
315 self.offset = 2 * self.offset + 1;
316 self.index
317 }
318
319 /// Move to the next tree from the current position and return
320 /// new index.
321 ///
322 /// ## Examples
323 /// ```rust
324 /// assert_eq!(flat_tree::Iterator::new(0).next_tree(), 2);
325 /// assert_eq!(flat_tree::Iterator::new(1).next_tree(), 4);
326 /// assert_eq!(flat_tree::Iterator::new(3).next_tree(), 8);
327 /// assert_eq!(flat_tree::Iterator::new(7).next_tree(), 16);
328 /// ```
329 #[inline]
330 pub fn next_tree(&mut self) -> u64 {
331 self.index = self.index + self.factor / 2 + 1;
332 self.offset = self.index / 2;
333 self.factor = 2;
334 self.index
335 }
336
337 /// Move to the previous tree from the current position and return
338 /// new index.
339 ///
340 /// ## Examples
341 /// ```rust
342 /// assert_eq!(flat_tree::Iterator::new(0).prev_tree(), 0);
343 /// assert_eq!(flat_tree::Iterator::new(1).prev_tree(), 0);
344 /// assert_eq!(flat_tree::Iterator::new(2).prev_tree(), 0);
345 /// assert_eq!(flat_tree::Iterator::new(3).prev_tree(), 0);
346 /// assert_eq!(flat_tree::Iterator::new(7).prev_tree(), 0);
347 /// assert_eq!(flat_tree::Iterator::new(5).prev_tree(), 2);
348 /// assert_eq!(flat_tree::Iterator::new(9).prev_tree(), 6);
349 /// assert_eq!(flat_tree::Iterator::new(11).prev_tree(), 6);
350 /// ```
351 #[inline]
352 pub fn prev_tree(&mut self) -> u64 {
353 if self.offset == 0 {
354 self.index = 0;
355 self.factor = 2;
356 } else {
357 self.index = self.index - self.factor / 2 - 1;
358 self.offset = self.index / 2;
359 self.factor = 2;
360 }
361 self.index
362 }
363
364 /// Move cursor to the full root of given leaf index that the iterator
365 /// index is a part of. If the cursor is already there, nothing is
366 /// changed.
367 ///
368 /// Returns true if a full root exists (moved or not), false if
369 /// there are no full roots for the cursor or if given index is not a
370 /// leaf.
371 ///
372 /// See full_roots() for what is meant by a full root.
373 ///
374 /// ## Examples
375 /// ```rust
376 /// let mut iter = flat_tree::Iterator::new(0);
377 /// assert_eq!(iter.full_root(0), false);
378 /// assert_eq!(iter.full_root(22), true);
379 /// assert_eq!(iter.index(), 7);
380 /// assert_eq!(iter.next_tree(), 16);
381 /// assert_eq!(iter.full_root(22), true);
382 /// assert_eq!(iter.index(), 17);
383 /// assert_eq!(iter.next_tree(), 20);
384 /// assert_eq!(iter.full_root(22), true);
385 /// assert_eq!(iter.index(), 20);
386 /// assert_eq!(iter.next_tree(), 22);
387 /// assert_eq!(iter.full_root(22), false);
388 /// ```
389 #[inline]
390 pub fn full_root(&mut self, index: u64) -> bool {
391 if index <= self.index || is_odd(self.index) {
392 return false;
393 }
394 while index > self.index + self.factor + self.factor / 2 {
395 self.index += self.factor / 2;
396 self.factor *= 2;
397 self.offset /= 2;
398 }
399 true
400 }
401}
402
403impl iter::Iterator for Iterator {
404 type Item = u64;
405
406 #[inline]
407 fn next(&mut self) -> Option<Self::Item> {
408 self.offset += 1;
409 self.index += self.factor;
410 Some(self.index)
411 }
412}
413
414impl Default for Iterator {
415 #[inline]
416 fn default() -> Self {
417 Self::new(0)
418 }
419}
420
421#[inline]
422fn two_pow(n: u64) -> u64 {
423 if n < 31 {
424 1 << n
425 } else {
426 (1 << 30) * (1 << (n - 30))
427 }
428}
429
430#[cfg(test)]
431mod tests {
432 use super::*;
433
434 #[test]
435 fn test_two_pow() {
436 assert_eq!(two_pow(0), 1);
437 assert_eq!(two_pow(1), 2);
438 assert_eq!(two_pow(2), 4);
439 assert_eq!(two_pow(3), 8);
440 assert_eq!(two_pow(31), 2147483648);
441 }
442
443 #[cfg(target_pointer_width = "64")]
444 #[test]
445 fn test_two_pow_64bit() {
446 assert_eq!(two_pow(34), 17179869184);
447 assert_eq!(two_pow(63), 9223372036854775808);
448 }
449}