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}