orx_tree/node_ref.rs
1use crate::{
2 Dfs, Node, NodeIdx, Traverser, Tree, TreeVariant,
3 aliases::{Col, N},
4 iter::{AncestorsIterPtr, CustomWalkIterPtr},
5 memory::MemoryPolicy,
6 pinned_storage::PinnedStorage,
7 subtrees::{ClonedSubTree, CopiedSubTree},
8 traversal::{
9 Over, OverData,
10 enumeration::Enumeration,
11 enumerations::Val,
12 over::{OverDepthPtr, OverItem},
13 traverser_core::TraverserCore,
14 },
15 tree_variant::RefsChildren,
16};
17#[cfg(feature = "parallel")]
18use orx_parallel::*;
19use orx_selfref_col::{NodePtr, Refs};
20
21pub trait NodeRefCore<'a, V, M, P>
22where
23 V: TreeVariant + 'a,
24 M: MemoryPolicy,
25 P: PinnedStorage,
26{
27 fn col(&self) -> &'a Col<V, M, P>;
28
29 fn node_ptr(&self) -> NodePtr<V>;
30
31 #[inline(always)]
32 fn node(&self) -> &'a N<V> {
33 unsafe { &*self.node_ptr().ptr() }
34 }
35}
36
37impl<'a, V, M, P, X> NodeRef<'a, V, M, P> for X
38where
39 V: TreeVariant + 'a,
40 M: MemoryPolicy,
41 P: PinnedStorage,
42 X: NodeRefCore<'a, V, M, P>,
43{
44}
45
46/// Reference to a tree node.
47pub trait NodeRef<'a, V, M, P>: NodeRefCore<'a, V, M, P>
48where
49 V: TreeVariant + 'a,
50 M: MemoryPolicy,
51 P: PinnedStorage,
52{
53 /// Returns the node index of this node.
54 ///
55 /// Note that a [`NodeIdx`] is used to provide safe and constant time access to any node in the tree.
56 ///
57 /// Validity of node indices is crucial, while it is conveniently possible to have complete control
58 /// on this.
59 /// Please see the documentation of [`NodeIdx`] and [`MemoryPolicy`] for details.
60 fn idx(&self) -> NodeIdx<V> {
61 NodeIdx(orx_selfref_col::NodeIdx::new(
62 self.col().memory_state(),
63 self.node_ptr(),
64 ))
65 }
66
67 /// Returns true if this is the root node; equivalently, if its [`parent`] is none.
68 ///
69 /// [`parent`]: NodeRef::parent
70 ///
71 /// # Examples
72 ///
73 /// ```
74 /// use orx_tree::*;
75 ///
76 /// let mut tree = BinaryTree::<char>::new('r');
77 ///
78 /// let mut root = tree.root_mut();
79 /// assert!(root.is_root());
80 ///
81 /// root.push_children(['a', 'b']);
82 /// for node in root.children() {
83 /// assert!(!node.is_root());
84 /// }
85 /// ```
86 #[inline(always)]
87 fn is_root(&self) -> bool {
88 self.node().prev().get().is_none()
89 }
90
91 /// Returns the `root` node of the tree that this node belongs to.
92 ///
93 /// Note that if this node is the root of its tree, this method will return itself.
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// use orx_tree::*;
99 ///
100 /// // 1
101 /// // ╱ ╲
102 /// // ╱ ╲
103 /// // 2 3
104 /// // ╱ ╲ ╱ ╲
105 /// // 4 5 6 7
106 /// // | | ╱ ╲
107 /// // 8 9 10 11
108 ///
109 /// let mut tree = DynTree::new(1);
110 ///
111 /// let mut root = tree.root_mut();
112 /// let [id2, id3] = root.push_children([2, 3]);
113 /// let [id4, _] = tree.node_mut(id2).push_children([4, 5]);
114 /// tree.node_mut(id4).push_child(8);
115 /// let [id6, id7] = tree.node_mut(id3).push_children([6, 7]);
116 /// tree.node_mut(id6).push_child(9);
117 /// let [id10, _] = tree.node_mut(id7).push_children([10, 11]);
118 ///
119 /// // reach back to root from any node
120 ///
121 /// let n1 = tree.root();
122 /// assert_eq!(n1.root(), tree.root());
123 ///
124 /// let n4 = tree.node(id4);
125 /// assert_eq!(n4.root(), tree.root());
126 ///
127 /// let n10 = tree.node(id10);
128 /// assert_eq!(n10.root(), tree.root());
129 /// ```
130 fn root(&self) -> Node<'a, V, M, P> {
131 let ends = self.col().ends().get();
132 let root_ptr = ends.expect("Tree is not-empty, and hence, has a root");
133 Node::new(self.col(), root_ptr)
134 }
135
136 /// Returns true if this is a leaf node; equivalently, if [`num_children`] is zero.
137 ///
138 /// [`num_children`]: NodeRef::num_children
139 ///
140 /// ```
141 /// use orx_tree::*;
142 ///
143 /// // 1
144 /// // ╱ ╲
145 /// // ╱ ╲
146 /// // 2 3
147 /// // ╱ ╲ ╱
148 /// // 4 5 6
149 ///
150 /// let mut tree = DynTree::new(1);
151 /// assert_eq!(tree.get_root().unwrap().is_leaf(), true); // both root & leaf
152 ///
153 /// let mut root = tree.root_mut();
154 /// let [id2, id3] = root.push_children([2, 3]);
155 ///
156 /// let mut n2 = tree.node_mut(id2);
157 /// let [id4, id5] = n2.push_children([4, 5]);
158 ///
159 /// let mut n3 = tree.node_mut(id3);
160 /// let [id6] = n3.push_children([6]);
161 ///
162 /// // walk over any subtree rooted at a selected node
163 /// // with different traversals
164 ///
165 /// assert_eq!(tree.get_root().unwrap().is_leaf(), false);
166 /// assert_eq!(tree.node(id2).is_leaf(), false);
167 /// assert_eq!(tree.node(id3).is_leaf(), false);
168 ///
169 /// assert_eq!(tree.node(id4).is_leaf(), true);
170 /// assert_eq!(tree.node(id5).is_leaf(), true);
171 /// assert_eq!(tree.node(id6).is_leaf(), true);
172 /// ```
173 #[inline(always)]
174 fn is_leaf(&self) -> bool {
175 self.num_children() == 0
176 }
177
178 /// Returns a reference to the data of the node.
179 ///
180 /// # Examples
181 ///
182 /// ```
183 /// use orx_tree::*;
184 ///
185 /// let mut tree = DynTree::new(0);
186 ///
187 /// let mut root = tree.root_mut();
188 /// assert_eq!(root.data(), &0);
189 ///
190 /// let [id_a] = root.push_children([1]);
191 /// let a = tree.node(id_a);
192 /// assert_eq!(a.data(), &1);
193 /// ```
194 #[inline(always)]
195 #[allow(clippy::missing_panics_doc)]
196 fn data(&self) -> &'a V::Item {
197 self.node()
198 .data()
199 .expect("node holding a tree reference must be active")
200 }
201
202 /// Returns the number of child nodes of this node.
203 ///
204 /// # Examples
205 ///
206 /// ```
207 /// use orx_tree::*;
208 ///
209 /// let mut tree = DynTree::new(0);
210 ///
211 /// let mut root = tree.root_mut();
212 /// assert_eq!(root.num_children(), 0);
213 ///
214 /// let [id_a, id_b] = root.push_children([1, 2]);
215 /// assert_eq!(root.num_children(), 2);
216 ///
217 /// let mut node = tree.node_mut(id_a);
218 /// node.push_child(3);
219 /// node.push_children([4, 5, 6]);
220 /// assert_eq!(node.num_children(), 4);
221 ///
222 /// assert_eq!(tree.node(id_b).num_children(), 0);
223 /// ```
224 #[inline(always)]
225 fn num_children(&self) -> usize {
226 self.node().next().num_children()
227 }
228
229 /// Returns the number of siblings **including this node**.
230 /// In other words, it returns the `num_children` of its parent;
231 /// or returns 1 if this is the root.
232 ///
233 /// # Examples
234 ///
235 /// ```
236 /// use orx_tree::*;
237 ///
238 /// let mut tree = DynTree::new(0);
239 /// let [id1, id2, id3] = tree.root_mut().push_children([1, 2, 3]);
240 /// let id4 = tree.node_mut(id3).push_child(4);
241 ///
242 /// assert_eq!(tree.root().num_siblings(), 1);
243 /// assert_eq!(tree.node(id1).num_siblings(), 3);
244 /// assert_eq!(tree.node(id2).num_siblings(), 3);
245 /// assert_eq!(tree.node(id3).num_siblings(), 3);
246 /// assert_eq!(tree.node(id4).num_siblings(), 1);
247 /// ```
248 fn num_siblings(&self) -> usize {
249 match self.parent() {
250 Some(parent) => parent.num_children(),
251 None => 1,
252 }
253 }
254
255 /// Returns an exact-sized iterator of children nodes of this node.
256 ///
257 /// # Examples
258 ///
259 /// ```
260 /// use orx_tree::*;
261 ///
262 /// // build the tree:
263 /// // r
264 /// // |-- a
265 /// // |-- c, d, e
266 /// // |-- b
267 /// let mut tree = DynTree::<char>::new('r');
268 ///
269 /// let mut root = tree.root_mut();
270 /// let [id_a] = root.push_children(['a']);
271 /// root.push_child('b');
272 ///
273 /// let mut a = tree.node_mut(id_a);
274 /// a.push_children(['c', 'd', 'e']);
275 ///
276 /// // iterate over children of nodes
277 ///
278 /// let root = tree.root();
279 /// let depth1: Vec<_> = root.children().map(|x| *x.data()).collect();
280 /// assert_eq!(depth1, ['a', 'b']);
281 ///
282 /// let b = root.children().nth(0).unwrap();
283 /// let depth2: Vec<_> = b.children().map(|x| *x.data()).collect();
284 /// assert_eq!(depth2, ['c', 'd', 'e']);
285 ///
286 /// // depth first - two levels deep
287 /// let mut data = vec![];
288 /// for node in root.children() {
289 /// data.push(*node.data());
290 ///
291 /// for child in node.children() {
292 /// data.push(*child.data());
293 /// }
294 /// }
295 ///
296 /// assert_eq!(data, ['a', 'c', 'd', 'e', 'b']);
297 /// ```
298 fn children(&'a self) -> impl ExactSizeIterator<Item = Node<'a, V, M, P>> {
299 self.node()
300 .next()
301 .children_ptr()
302 .map(|ptr| Node::new(self.col(), *ptr))
303 }
304
305 /// Creates a **[parallel iterator]** of children nodes of this node.
306 ///
307 /// Please see [`children`] for details, since `children_par` is the parallelized counterpart.
308 /// * Parallel iterators can be used similar to regular iterators.
309 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
310 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
311 ///
312 /// You may also see [children_iterator](https://github.com/orxfun/orx-tree/blob/main/benches/children_iterator.rs) benchmark to
313 /// see an example use case.
314 ///
315 /// [`children`]: NodeRef::children
316 /// [parallel iterator]: orx_parallel::ParIter
317 /// [`num_threads`]: orx_parallel::ParIter::num_threads
318 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
319 ///
320 /// # Examples
321 ///
322 /// ```rust
323 /// use orx_tree::*;
324 ///
325 /// const N: usize = 8;
326 ///
327 /// fn build_tree(n: usize) -> DaryTree<N, String> {
328 /// let mut tree = DaryTree::new(0.to_string());
329 /// let mut dfs = Traversal.dfs().over_nodes();
330 /// while tree.len() < n {
331 /// let root = tree.root();
332 /// let x: Vec<_> = root.leaves_with(&mut dfs).map(|x| x.idx()).collect();
333 /// for idx in x {
334 /// let count = tree.len();
335 /// let mut node = tree.node_mut(idx);
336 /// for j in 0..N {
337 /// node.push_child((count + j).to_string());
338 /// }
339 /// }
340 /// }
341 /// tree
342 /// }
343 ///
344 /// fn compute_subtree_value(subtree: &DaryNode<N, String>) -> u64 {
345 /// subtree
346 /// .walk::<Dfs>()
347 /// .map(|x| x.parse::<u64>().unwrap())
348 /// .sum()
349 /// }
350 ///
351 /// let tree = build_tree(64 * 1_024);
352 ///
353 /// let seq_value: u64 = tree
354 /// .root()
355 /// .children()
356 /// .map(|x| compute_subtree_value(&x))
357 /// .sum();
358 ///
359 /// let par_value: u64 = tree
360 /// .root()
361 /// .children_par() // compute 8 subtrees in parallel
362 /// .map(|x| compute_subtree_value(&x))
363 /// .sum();
364 ///
365 /// let par_value_4t: u64 = tree
366 /// .root()
367 /// .children_par() // compute 8 subtrees in parallel
368 /// .num_threads(4) // but limited to using 4 threads
369 /// .map(|x| compute_subtree_value(&x))
370 /// .sum();
371 ///
372 /// assert_eq!(seq_value, par_value);
373 /// assert_eq!(seq_value, par_value_4t);
374 /// ```
375 #[cfg(feature = "parallel")]
376 fn children_par(&'a self) -> impl ParIter<Item = Node<'a, V, M, P>>
377 where
378 V::Item: Send + Sync,
379 Self: Sync,
380 {
381 self.node()
382 .next()
383 .children_ptr_par()
384 .map(|ptr| Node::new(self.col(), *ptr))
385 }
386
387 /// Returns the `child-index`-th child of the node; returns None if out of bounds.
388 ///
389 /// # Examples
390 ///
391 /// ```
392 /// use orx_tree::*;
393 ///
394 /// // build the tree:
395 /// // r
396 /// // |-- a
397 /// // |-- c, d, e
398 /// // |-- b
399 /// let mut tree = DynTree::<char>::new('r');
400 ///
401 /// let mut root = tree.root_mut();
402 /// let [id_a] = root.push_children(['a']);
403 /// root.push_child('b');
404 ///
405 /// let mut a = tree.node_mut(id_a);
406 /// a.push_children(['c', 'd', 'e']);
407 ///
408 /// // use child to access lower level nodes
409 ///
410 /// let root = tree.root();
411 ///
412 /// let a = root.get_child(0).unwrap();
413 /// assert_eq!(a.data(), &'a');
414 /// assert_eq!(a.num_children(), 3);
415 ///
416 /// assert_eq!(a.get_child(1).unwrap().data(), &'d');
417 /// assert_eq!(a.get_child(3), None);
418 /// ```
419 fn get_child(&self, child_index: usize) -> Option<Node<'a, V, M, P>> {
420 self.node()
421 .next()
422 .get_ptr(child_index)
423 .map(|ptr| Node::new(self.col(), ptr))
424 }
425
426 /// Returns the `child-index`-th child of the node.
427 ///
428 /// # Panics
429 ///
430 /// Panics if the child index is out of bounds; i.e., `child_index >= self.num_children()`.
431 ///
432 /// # Examples
433 ///
434 /// ```
435 /// use orx_tree::*;
436 ///
437 /// // build the tree:
438 /// // r
439 /// // |-- a
440 /// // |-- c, d, e
441 /// // |-- b
442 /// let mut tree = DynTree::<char>::new('r');
443 ///
444 /// let mut root = tree.root_mut();
445 /// let [id_a] = root.push_children(['a']);
446 /// root.push_child('b');
447 ///
448 /// let mut a = tree.node_mut(id_a);
449 /// a.push_children(['c', 'd', 'e']);
450 ///
451 /// // use child to access lower level nodes
452 ///
453 /// let root = tree.root();
454 ///
455 /// let a = root.child(0);
456 /// assert_eq!(a.data(), &'a');
457 /// assert_eq!(a.num_children(), 3);
458 ///
459 /// assert_eq!(a.child(1).data(), &'d');
460 /// // let child = a.child(3); // out-of-bounds, panics!
461 /// ```
462 fn child(&self, child_index: usize) -> Node<'a, V, M, P> {
463 self.get_child(child_index)
464 .expect("Given child_index is out of bounds; i.e., child_index >= self.num_children()")
465 }
466
467 /// Returns the parent of this node; returns None if this is the root node.
468 ///
469 /// # Examples
470 ///
471 /// ```
472 /// use orx_tree::*;
473 ///
474 /// let mut tree = BinaryTree::<char>::new('r');
475 ///
476 /// let mut root = tree.root_mut();
477 /// assert_eq!(root.parent(), None);
478 ///
479 /// root.push_children(['a', 'b']);
480 /// for node in root.children() {
481 /// assert_eq!(node.parent().unwrap(), root);
482 /// }
483 /// ```
484 fn parent(&self) -> Option<Node<'a, V, M, P>> {
485 self.node()
486 .prev()
487 .get()
488 .map(|ptr| Node::new(self.col(), ptr))
489 }
490
491 /// Returns the position of this node in the children collection of its parent;
492 /// returns 0 if this is the root node (root has no other siblings).
493 ///
494 /// **O(S)** where S is the number of siblings; i.e.,
495 /// requires linear search over the children of the parent of this node.
496 /// Therefore, S depends on the tree size. It bounded by 2 in a [`BinaryTree`],
497 /// by 4 in a [`DaryTree`] with D=4. In a [`DynTree`] the children list can grow
498 /// arbitrarily, therefore, it is not bounded.
499 ///
500 /// [`BinaryTree`]: crate::BinaryTree
501 /// [`DaryTree`]: crate::DaryTree
502 /// [`DynTree`]: crate::DynTree
503 ///
504 /// # Examples
505 ///
506 /// ```
507 /// use orx_tree::*;
508 ///
509 /// // r
510 /// // ╱ ╲
511 /// // ╱ ╲
512 /// // a b
513 /// // ╱|╲ ╱ ╲
514 /// // c d e f g
515 /// // ╱|╲
516 /// // h i j
517 ///
518 /// let mut tree = DynTree::<char>::new('r');
519 ///
520 /// let mut root = tree.root_mut();
521 /// let [id_a, id_b] = root.push_children(['a', 'b']);
522 ///
523 /// let mut a = tree.node_mut(id_a);
524 /// a.push_children(['c', 'd', 'e']);
525 ///
526 /// let mut b = tree.node_mut(id_b);
527 /// let [_, id_g] = b.push_children(['f', 'g']);
528 ///
529 /// let mut g = tree.node_mut(id_g);
530 /// let [id_h, id_i, id_j] = g.push_children(['h', 'i', 'j']);
531 ///
532 /// // check sibling positions
533 ///
534 /// let root = tree.root();
535 /// assert_eq!(root.sibling_idx(), 0);
536 ///
537 /// for (i, node) in root.children().enumerate() {
538 /// assert_eq!(node.sibling_idx(), i);
539 /// }
540 ///
541 /// assert_eq!(tree.node(id_h).sibling_idx(), 0);
542 /// assert_eq!(tree.node(id_i).sibling_idx(), 1);
543 /// assert_eq!(tree.node(id_j).sibling_idx(), 2);
544 /// ```
545 fn sibling_idx(&self) -> usize {
546 let parent = self.node().prev().get().map(|ptr| unsafe { ptr.node() });
547 parent
548 .map(|parent| {
549 let ptr = self.node_ptr();
550 let mut children = parent.next().children_ptr();
551 children.position(|x| *x == ptr).expect("this node exists")
552 })
553 .unwrap_or(0)
554 }
555
556 /// Returns the depth of this node with respect to the root of the tree which has a
557 /// depth of 0.
558 ///
559 /// **O(D)** requires linear time in maximum depth of the tree.
560 ///
561 /// # Examples
562 ///
563 /// ```
564 /// use orx_tree::*;
565 ///
566 /// // 1
567 /// // ╱ ╲
568 /// // ╱ ╲
569 /// // 2 3
570 /// // ╱ ╲ ╱ ╲
571 /// // 4 5 6 7
572 /// // |
573 /// // 8
574 ///
575 /// let mut tree = DynTree::new(1);
576 ///
577 /// let mut root = tree.root_mut();
578 /// let [id2, id3] = root.push_children([2, 3]);
579 ///
580 /// let mut n2 = tree.node_mut(id2);
581 /// let [id4, id5] = n2.push_children([4, 5]);
582 ///
583 /// let [id8] = tree.node_mut(id4).push_children([8]);
584 ///
585 /// let mut n3 = tree.node_mut(id3);
586 /// let [id6, id7] = n3.push_children([6, 7]);
587 ///
588 /// // access the leaves in different orders that is determined by traversal
589 ///
590 /// assert_eq!(tree.root().depth(), 0);
591 ///
592 /// assert_eq!(tree.node(id2).depth(), 1);
593 /// assert_eq!(tree.node(id3).depth(), 1);
594 ///
595 /// assert_eq!(tree.node(id4).depth(), 2);
596 /// assert_eq!(tree.node(id5).depth(), 2);
597 /// assert_eq!(tree.node(id6).depth(), 2);
598 /// assert_eq!(tree.node(id7).depth(), 2);
599 ///
600 /// assert_eq!(tree.node(id8).depth(), 3);
601 /// ```
602 fn depth(&self) -> usize {
603 let mut depth = 0;
604
605 let mut current = unsafe { &*self.node_ptr().ptr() };
606 while let Some(parent_ptr) = current.prev().get() {
607 depth += 1;
608 current = unsafe { &*parent_ptr.ptr() };
609 }
610
611 depth
612 }
613
614 /// Returns an iterator starting from this node's parent moving upwards until the root:
615 ///
616 /// * yields all ancestors of this node,
617 /// * the first element is always this node's parent, and
618 /// * the last element is always the root node of the tree.
619 ///
620 /// It returns an empty iterator if this is the root node.
621 ///
622 /// # Examples
623 ///
624 /// ```
625 /// use orx_tree::*;
626 ///
627 /// // 1
628 /// // ╱ ╲
629 /// // ╱ ╲
630 /// // 2 3
631 /// // ╱ ╲ ╱ ╲
632 /// // 4 5 6 7
633 /// // | | ╱ ╲
634 /// // 8 9 10 11
635 ///
636 /// let mut tree = DynTree::new(1);
637 ///
638 /// let mut root = tree.root_mut();
639 /// let [id2, id3] = root.push_children([2, 3]);
640 ///
641 /// let mut n2 = tree.node_mut(id2);
642 /// let [id4, _] = n2.push_children([4, 5]);
643 ///
644 /// tree.node_mut(id4).push_child(8);
645 ///
646 /// let mut n3 = tree.node_mut(id3);
647 /// let [id6, id7] = n3.push_children([6, 7]);
648 ///
649 /// tree.node_mut(id6).push_child(9);
650 /// let [id10, _] = tree.node_mut(id7).push_children([10, 11]);
651 ///
652 /// // ancestors iterator over nodes upwards to the root
653 ///
654 /// let root = tree.root();
655 /// let mut iter = root.ancestors();
656 /// assert_eq!(iter.next(), None);
657 ///
658 /// let n10 = tree.node(id10);
659 /// let ancestors_data: Vec<_> = n10.ancestors().map(|x| *x.data()).collect();
660 /// assert_eq!(ancestors_data, [7, 3, 1]);
661 ///
662 /// let n4 = tree.node(id4);
663 /// let ancestors_data: Vec<_> = n4.ancestors().map(|x| *x.data()).collect();
664 /// assert_eq!(ancestors_data, [2, 1]);
665 /// ```
666 fn ancestors(&'a self) -> impl Iterator<Item = Node<'a, V, M, P>> {
667 let root_ptr = self.col().ends().get().expect("Tree is non-empty");
668 AncestorsIterPtr::new(root_ptr, self.node_ptr())
669 .skip(1)
670 .map(|ptr| Node::new(self.col(), ptr))
671 }
672
673 /// Creates a **[parallel iterator]** starting from this node moving upwards until the root:
674 ///
675 /// * yields all ancestors of this node including this node,
676 /// * the first element is always this node, and
677 /// * the last element is always the root node of the tree.
678 ///
679 /// Please see [`ancestors`] for details, since `ancestors_par` is the parallelized counterpart.
680 /// * Parallel iterators can be used similar to regular iterators.
681 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
682 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
683 ///
684 /// [`ancestors`]: NodeRef::ancestors
685 /// [parallel iterator]: orx_parallel::ParIter
686 /// [`num_threads`]: orx_parallel::ParIter::num_threads
687 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
688 #[cfg(feature = "parallel")]
689 fn ancestors_par(&'a self) -> impl ParIter<Item = Node<'a, V, M, P>>
690 where
691 V::Item: Send + Sync,
692 {
693 self.ancestors().collect::<alloc::vec::Vec<_>>().into_par()
694 }
695
696 /// Returns true if this node is an ancestor of the node with the given `idx`;
697 /// false otherwise.
698 ///
699 /// Searches in ***O(D)*** where D is the depth of the tree.
700 ///
701 /// Note that the node is **not** an ancestor of itself.
702 ///
703 /// # Examples
704 ///
705 /// ```
706 /// use orx_tree::*;
707 ///
708 /// // 1
709 /// // ╱ ╲
710 /// // ╱ ╲
711 /// // 2 3
712 /// // ╱ ╲ ╱ ╲
713 /// // 4 5 6 7
714 ///
715 /// let mut tree = DynTree::new(1);
716 ///
717 /// let mut root = tree.root_mut();
718 /// let [id2, id3] = root.push_children([2, 3]);
719 ///
720 /// let mut n2 = tree.node_mut(id2);
721 /// let [id4, id5] = n2.push_children([4, 5]);
722 ///
723 /// let mut n3 = tree.node_mut(id3);
724 /// let [id6, id7] = n3.push_children([6, 7]);
725 ///
726 /// // ancestor tests
727 ///
728 /// assert!(tree.root().is_ancestor_of(id4));
729 /// assert!(tree.root().is_ancestor_of(id7));
730 ///
731 /// assert!(tree.node(id2).is_ancestor_of(id5));
732 /// assert!(tree.node(id3).is_ancestor_of(id6));
733 ///
734 /// // the other way around
735 /// assert!(!tree.node(id6).is_ancestor_of(id3));
736 ///
737 /// // a node is not an ancestor of itself
738 /// assert!(!tree.node(id6).is_ancestor_of(id6));
739 ///
740 /// // nodes belong to independent subtrees
741 /// assert!(!tree.node(id2).is_ancestor_of(id6));
742 /// ```
743 fn is_ancestor_of(&self, idx: NodeIdx<V>) -> bool {
744 let root_ptr = self.col().ends().get().expect("Tree is non-empty");
745 let descendant_ptr = idx.0.node_ptr();
746 let ancestor_ptr = self.node_ptr();
747 AncestorsIterPtr::new(root_ptr, descendant_ptr)
748 .skip(1) // a node is not an ancestor of itself
749 .any(|ptr| ptr == ancestor_ptr)
750 }
751
752 /// Returns the height of this node relative to the deepest leaf of the subtree rooted at this node.
753 ///
754 /// Equivalently, returns the maximum of depths of leaf nodes belonging to the subtree rooted at this node.
755 ///
756 /// If this is a leaf node, height will be 0 which is the depth of the root (itself).
757 ///
758 /// # Examples
759 ///
760 /// ```
761 /// use orx_tree::*;
762 ///
763 /// // 1
764 /// // ╱ ╲
765 /// // ╱ ╲
766 /// // 2 3
767 /// // ╱ ╲ ╱ ╲
768 /// // 4 5 6 7
769 /// // |
770 /// // 8
771 ///
772 /// let mut tree = DynTree::new(1);
773 ///
774 /// let mut root = tree.root_mut();
775 /// let [id2, id3] = root.push_children([2, 3]);
776 /// let [id4, _] = tree.node_mut(id2).push_children([4, 5]);
777 /// let [id6, _] = tree.node_mut(id3).push_children([6, 7]);
778 /// tree.node_mut(id6).push_child(8);
779 ///
780 /// assert_eq!(tree.root().height(), 3); // max depth of the tree
781 /// assert_eq!(tree.node(id2).height(), 1);
782 /// assert_eq!(tree.node(id3).height(), 2);
783 /// assert_eq!(tree.node(id4).height(), 0); // subtree with only the root
784 /// assert_eq!(tree.node(id6).height(), 1);
785 /// ```
786 fn height(&self) -> usize {
787 let mut traverser = Dfs::<OverDepthPtr>::new();
788 Dfs::<OverDepthPtr>::iter_ptr_with_storage(self.node_ptr(), traverser.storage_mut())
789 .map(|(depth, _)| depth)
790 .max()
791 .expect("the iterator is not empty")
792 }
793
794 // traversal
795
796 /// Creates a custom walk starting from this node such that:
797 ///
798 /// * the first element will be this node, say `n1`,
799 /// * the second element will be node `n2 = next_node(n1)`,
800 /// * the third element will be node `n3 = next_node(n2)`,
801 /// * ...
802 ///
803 /// The iteration will terminate as soon as the `next_node` returns `None`.
804 ///
805 /// # Examples
806 ///
807 /// In the following example we create a custom iterator that walks down the tree as follows:
808 ///
809 /// * if the current node is not the last of its siblings, the next node will be its next sibling;
810 /// * if the current node is the last of its siblings and if it has children, the next node will be its first child;
811 /// * otherwise, the iteration will terminate.
812 ///
813 /// This walk strategy is implemented by the `next_node` function, and `custom_walk` is called with this strategy.
814 ///
815 /// ```rust
816 /// use orx_tree::*;
817 ///
818 /// // 1
819 /// // ╱ ╲
820 /// // ╱ ╲
821 /// // 2 3
822 /// // ╱ ╲ ╱ ╲
823 /// // 4 5 6 7
824 /// // | | ╱ ╲
825 /// // 8 9 10 11
826 ///
827 /// fn next_node<'a, T>(node: DynNode<'a, T>) -> Option<DynNode<'a, T>> {
828 /// let sibling_idx = node.sibling_idx();
829 /// let is_last_sibling = sibling_idx == node.num_siblings() - 1;
830 ///
831 /// match is_last_sibling {
832 /// true => node.get_child(0),
833 /// false => match node.parent() {
834 /// Some(parent) => {
835 /// let child_idx = sibling_idx + 1;
836 /// parent.get_child(child_idx)
837 /// }
838 /// None => None,
839 /// },
840 /// }
841 /// }
842 ///
843 /// let mut tree = DynTree::new(1);
844 ///
845 /// let mut root = tree.root_mut();
846 /// let [id2, id3] = root.push_children([2, 3]);
847 /// let [id4, _] = tree.node_mut(id2).push_children([4, 5]);
848 /// tree.node_mut(id4).push_child(8);
849 /// let [id6, id7] = tree.node_mut(id3).push_children([6, 7]);
850 /// tree.node_mut(id6).push_child(9);
851 /// tree.node_mut(id7).push_children([10, 11]);
852 ///
853 /// let values: Vec<_> = tree.root().custom_walk(next_node).copied().collect();
854 /// assert_eq!(values, [1, 2, 3, 6, 7, 10, 11]);
855 ///
856 /// let values: Vec<_> = tree.node(id3).custom_walk(next_node).copied().collect();
857 /// assert_eq!(values, [3, 6, 7, 10, 11]);
858 /// ```
859 fn custom_walk<F>(&self, next_node: F) -> impl Iterator<Item = &'a V::Item>
860 where
861 F: Fn(Node<'a, V, M, P>) -> Option<Node<'a, V, M, P>>,
862 {
863 let iter_ptr = CustomWalkIterPtr::new(self.col(), Some(self.node_ptr()), next_node);
864 iter_ptr.map(|ptr| {
865 let node = unsafe { &*ptr.ptr() };
866 node.data()
867 .expect("node is returned by next_node and is active")
868 })
869 }
870
871 /// Creates a **[parallel iterator]** that yields references to data of all nodes belonging to the subtree rooted at this node.
872 ///
873 /// Please see [`custom_walk`] for details, since `custom_walk_par` is the parallelized counterpart.
874 /// * Parallel iterators can be used similar to regular iterators.
875 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
876 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
877 ///
878 /// [`custom_walk`]: NodeRef::custom_walk
879 /// [parallel iterator]: orx_parallel::ParIter
880 /// [`num_threads`]: orx_parallel::ParIter::num_threads
881 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
882 #[cfg(feature = "parallel")]
883 fn custom_walk_par<F>(&self, next_node: F) -> impl ParIter<Item = &'a V::Item>
884 where
885 F: Fn(Node<'a, V, M, P>) -> Option<Node<'a, V, M, P>>,
886 V::Item: Send + Sync,
887 {
888 self.custom_walk(next_node)
889 .collect::<alloc::vec::Vec<_>>()
890 .into_par()
891 }
892
893 /// Creates an iterator that yields references to data of all nodes belonging to the subtree rooted at this node.
894 ///
895 /// The order of the elements is determined by the generic [`Traverser`] parameter `T`.
896 /// Available implementations are:
897 /// * [`Bfs`] for breadth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search))
898 /// * [`Dfs`] for (pre-order) depth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Depth-first_search))
899 /// * [`PostOrder`] for post-order ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Post-order,_LRN))
900 ///
901 /// You may see the [walks](https://github.com/orxfun/orx-tree/blob/main/examples/walks.rs) example that demonstrates
902 /// different ways to walk the tree with traversal variants (`cargo run --example walks`).
903 ///
904 /// # See also
905 ///
906 /// See also [`walk_mut`] and [`into_walk`] for iterators over mutable references and owned (removed) values,
907 /// respectively.
908 ///
909 /// Note that tree traversing methods typically allocate a temporary data structure that is dropped once the
910 /// iterator is dropped.
911 /// In use cases where we repeatedly iterate using any of the **walk** methods over different nodes or different
912 /// trees, we can avoid the allocation by creating the traverser only once and using [`walk_with`], [`walk_mut_with`]
913 /// and [`into_walk_with`] methods instead.
914 /// These methods additionally allow for iterating over nodes rather than data; and yielding node depths and sibling
915 /// indices in addition to node data.
916 ///
917 /// [`Bfs`]: crate::Bfs
918 /// [`Dfs`]: crate::Dfs
919 /// [`PostOrder`]: crate::PostOrder
920 /// [`walk_mut`]: crate::NodeMut::walk_mut
921 /// [`into_walk`]: crate::NodeMut::into_walk
922 /// [`walk_with`]: crate::NodeRef::walk_with
923 /// [`walk_mut_with`]: crate::NodeMut::walk_mut_with
924 /// [`into_walk_with`]: crate::NodeMut::into_walk_with
925 ///
926 /// # Examples
927 ///
928 /// ```
929 /// use orx_tree::*;
930 ///
931 /// // 1
932 /// // ╱ ╲
933 /// // ╱ ╲
934 /// // 2 3
935 /// // ╱ ╲ ╱ ╲
936 /// // 4 5 6 7
937 /// // | | ╱ ╲
938 /// // 8 9 10 11
939 ///
940 /// let mut tree = DynTree::new(1);
941 ///
942 /// let mut root = tree.root_mut();
943 /// let [id2, id3] = root.push_children([2, 3]);
944 /// let [id4, _] = tree.node_mut(id2).push_children([4, 5]);
945 /// tree.node_mut(id4).push_child(8);
946 /// let [id6, id7] = tree.node_mut(id3).push_children([6, 7]);
947 /// tree.node_mut(id6).push_child(9);
948 /// tree.node_mut(id7).push_children([10, 11]);
949 ///
950 /// // walk over any subtree rooted at a selected node
951 /// // with different traversals
952 ///
953 /// let root = tree.root();
954 /// let bfs: Vec<_> = root.walk::<Bfs>().copied().collect();
955 /// assert_eq!(bfs, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
956 ///
957 /// let n3 = tree.node(id3);
958 /// let dfs: Vec<_> = n3.walk::<Dfs>().copied().collect();
959 /// assert_eq!(dfs, [3, 6, 9, 7, 10, 11]);
960 ///
961 /// let n2 = tree.node(id2);
962 /// let post_order: Vec<_> = n2.walk::<PostOrder>().copied().collect();
963 /// assert_eq!(post_order, [8, 4, 5, 2]);
964 /// ```
965 fn walk<T>(&'a self) -> impl Iterator<Item = &'a V::Item>
966 where
967 T: Traverser<OverData>,
968 Self: Sized,
969 {
970 T::iter_with_owned_storage::<V, M, P>(self)
971 }
972
973 /// Creates a **[parallel iterator]** that yields references to data of all nodes belonging to the subtree rooted at this node.
974 ///
975 /// Please see [`walk`] for details, since `walk_par` is the parallelized counterpart.
976 /// * Parallel iterators can be used similar to regular iterators.
977 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
978 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
979 ///
980 /// You may also see [walk_iterator](https://github.com/orxfun/orx-tree/blob/main/benches/walk_iterator.rs) benchmark to
981 /// see an example use case.
982 ///
983 /// [`walk`]: NodeRef::walk
984 /// [parallel iterator]: orx_parallel::ParIter
985 /// [`num_threads`]: orx_parallel::ParIter::num_threads
986 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
987 #[cfg(feature = "parallel")]
988 fn walk_par<T>(&'a self) -> impl ParIter<Item = &'a V::Item>
989 where
990 T: Traverser<OverData>,
991 Self: Sized,
992 V::Item: Send + Sync,
993 {
994 self.walk::<T>().collect::<alloc::vec::Vec<_>>().into_par()
995 }
996
997 /// Creates an iterator that traverses all nodes belonging to the subtree rooted at this node.
998 ///
999 /// The order of the elements is determined by the type of the `traverser` which implements [`Traverser`].
1000 /// Available implementations are:
1001 /// * [`Bfs`] for breadth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search))
1002 /// * [`Dfs`] for (pre-order) depth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Depth-first_search))
1003 /// * [`PostOrder`] for post-order ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Post-order,_LRN))
1004 ///
1005 /// You may see the [walks](https://github.com/orxfun/orx-tree/blob/main/examples/walks.rs) example that demonstrates
1006 /// different ways to walk the tree with traversal variants (`cargo run --example walks`).
1007 ///
1008 /// As opposed to [`walk`], this method does require internal allocation.
1009 /// Furthermore, it allows to iterate over nodes rather than data; and to attach node depths or sibling
1010 /// indices to the yield values.
1011 /// Please see the examples below.
1012 ///
1013 /// [`walk`]: crate::NodeRef::walk
1014 /// [`Bfs`]: crate::Bfs
1015 /// [`Dfs`]: crate::Dfs
1016 /// [`PostOrder`]: crate::PostOrder
1017 ///
1018 /// # Examples
1019 ///
1020 /// ## Examples - Repeated Iterations without Allocation
1021 ///
1022 /// ```
1023 /// use orx_tree::*;
1024 ///
1025 /// // 1
1026 /// // ╱ ╲
1027 /// // ╱ ╲
1028 /// // 2 3
1029 /// // ╱ ╲ ╱ ╲
1030 /// // 4 5 6 7
1031 /// // | | ╱ ╲
1032 /// // 8 9 10 11
1033 ///
1034 /// let mut tree = DynTree::new(1);
1035 ///
1036 /// let mut root = tree.root_mut();
1037 /// let [id2, id3] = root.push_children([2, 3]);
1038 ///
1039 /// let mut n2 = tree.node_mut(id2);
1040 /// let [id4, _] = n2.push_children([4, 5]);
1041 ///
1042 /// tree.node_mut(id4).push_child(8);
1043 ///
1044 /// let mut n3 = tree.node_mut(id3);
1045 /// let [id6, id7] = n3.push_children([6, 7]);
1046 ///
1047 /// tree.node_mut(id6).push_child(9);
1048 /// tree.node_mut(id7).push_children([10, 11]);
1049 ///
1050 /// // create the traverser 'dfs' only once, use it many times
1051 /// // to walk over references, mutable references or removed values
1052 /// // without additional allocation
1053 ///
1054 /// let mut dfs = Dfs::default();
1055 ///
1056 /// let root = tree.root();
1057 /// let values: Vec<_> = root.walk_with(&mut dfs).copied().collect();
1058 /// assert_eq!(values, [1, 2, 4, 8, 5, 3, 6, 9, 7, 10, 11]);
1059 ///
1060 /// let mut n7 = tree.node_mut(id7);
1061 /// for x in n7.walk_mut_with(&mut dfs) {
1062 /// *x += 100;
1063 /// }
1064 /// let values: Vec<_> = tree.get_root().unwrap().walk_with(&mut dfs).copied().collect();
1065 /// assert_eq!(values, [1, 2, 4, 8, 5, 3, 6, 9, 107, 110, 111]);
1066 ///
1067 /// let n3 = tree.node_mut(id3);
1068 /// let removed: Vec<_> = n3.into_walk_with(&mut dfs).collect();
1069 /// assert_eq!(removed, [3, 6, 9, 107, 110, 111]);
1070 ///
1071 /// let remaining: Vec<_> = tree.get_root().unwrap().walk_with(&mut dfs).copied().collect();
1072 /// assert_eq!(remaining, [1, 2, 4, 8, 5]);
1073 /// ```
1074 ///
1075 /// ## Examples - Yielding Different Items
1076 ///
1077 /// ```
1078 /// use orx_tree::*;
1079 ///
1080 /// // 1
1081 /// // ╱ ╲
1082 /// // ╱ ╲
1083 /// // 2 3
1084 /// // ╱ ╲ ╱ ╲
1085 /// // 4 5 6 7
1086 /// // | | ╱ ╲
1087 /// // 8 9 10 11
1088 ///
1089 /// let mut tree = DynTree::new(1);
1090 ///
1091 /// let mut root = tree.root_mut();
1092 /// let [id2, id3] = root.push_children([2, 3]);
1093 ///
1094 /// let mut n2 = tree.node_mut(id2);
1095 /// let [id4, _] = n2.push_children([4, 5]);
1096 ///
1097 /// tree.node_mut(id4).push_child(8);
1098 ///
1099 /// let mut n3 = tree.node_mut(id3);
1100 /// let [id6, id7] = n3.push_children([6, 7]);
1101 ///
1102 /// tree.node_mut(id6).push_child(9);
1103 /// tree.node_mut(id7).push_children([10, 11]);
1104 ///
1105 /// // create the traverser 'bfs' iterator
1106 /// // to walk over nodes rather than data
1107 ///
1108 /// let mut bfs = Bfs::default().over_nodes();
1109 /// // OR: Bfs::<OverNode>::new();
1110 ///
1111 /// let n7 = tree.node(id7);
1112 /// let mut iter = n7.walk_with(&mut bfs);
1113 /// let node = iter.next().unwrap();
1114 /// assert_eq!(node.num_children(), 2);
1115 /// assert_eq!(node.get_child(1).map(|x| *x.data()), Some(11));
1116 ///
1117 /// // or to additionally yield depth and/or sibling-idx
1118 ///
1119 /// let mut dfs = Dfs::default().with_depth().with_sibling_idx();
1120 /// // OR: Dfs::<OverDepthSiblingIdxData>::new()
1121 ///
1122 /// let n3 = tree.node(id3);
1123 /// let result: Vec<_> = n3
1124 /// .walk_with(&mut dfs)
1125 /// .map(|(depth, sibling_idx, data)| (depth, sibling_idx, *data))
1126 /// .collect();
1127 /// assert_eq!(
1128 /// result,
1129 /// [
1130 /// (0, 0, 3),
1131 /// (1, 0, 6),
1132 /// (2, 0, 9),
1133 /// (1, 1, 7),
1134 /// (2, 0, 10),
1135 /// (2, 1, 11)
1136 /// ]
1137 /// );
1138 /// ```
1139 fn walk_with<'t, T, O>(
1140 &'a self,
1141 traverser: &'t mut T,
1142 ) -> impl Iterator<Item = OverItem<'a, V, O, M, P>>
1143 where
1144 O: Over,
1145 T: Traverser<O>,
1146 Self: Sized,
1147 't: 'a,
1148 {
1149 traverser.iter(self)
1150 }
1151
1152 /// Creates a **[parallel iterator]** that traverses all nodes belonging to the subtree rooted at this node.
1153 ///
1154 /// Please see [`walk_with`] for details, since `walk_with_par` is the parallelized counterpart.
1155 /// * Parallel iterators can be used similar to regular iterators.
1156 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
1157 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
1158 ///
1159 /// [`walk_with`]: NodeRef::walk_with
1160 /// [parallel iterator]: orx_parallel::ParIter
1161 /// [`num_threads`]: orx_parallel::ParIter::num_threads
1162 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
1163 #[cfg(feature = "parallel")]
1164 fn walk_with_par<'t, T, O>(
1165 &'a self,
1166 traverser: &'t mut T,
1167 ) -> impl ParIter<Item = OverItem<'a, V, O, M, P>>
1168 where
1169 O: Over,
1170 T: Traverser<O>,
1171 Self: Sized,
1172 't: 'a,
1173 OverItem<'a, V, O, M, P>: Send + Sync,
1174 {
1175 self.walk_with(traverser)
1176 .collect::<alloc::vec::Vec<_>>()
1177 .into_par()
1178 }
1179
1180 /// Returns an iterator of paths from all leaves of the subtree rooted at
1181 /// this node **upwards** to this node.
1182 ///
1183 /// The iterator yields one path per leaf node.
1184 ///
1185 /// The order of the leaves, and hence the corresponding paths, is determined
1186 /// by the generic [`Traverser`] parameter `T`.
1187 ///
1188 /// # See also
1189 ///
1190 /// * [`paths_with`]: (i) to iterate using a cached traverser to minimize allocation
1191 /// for repeated traversals, or (ii) to iterate over nodes rather than only the data.
1192 ///
1193 /// [`paths_with`]: NodeRef::paths_with
1194 ///
1195 /// # Yields
1196 ///
1197 /// * `Iterator::Item` => `impl Iterator<Item = &'a V::Item> + Clone`
1198 ///
1199 /// Notice that each path iterator is cloneable; and hence, can cheaply be converted into
1200 /// an [`Iterable`] by [`into_iterable`] method. This allows iterating over each path multiple
1201 /// times without requiring to allocate and store the path nodes in a collection.
1202 ///
1203 /// [`Iterable`]: orx_iterable::Iterable
1204 /// [`into_iterable`]: orx_iterable::IntoCloningIterable::into_iterable
1205 ///
1206 /// # Examples
1207 ///
1208 /// ```
1209 /// use orx_tree::*;
1210 /// use orx_iterable::*;
1211 ///
1212 /// // 1
1213 /// // ╱ ╲
1214 /// // ╱ ╲
1215 /// // 2 3
1216 /// // ╱ ╲ ╱ ╲
1217 /// // 4 5 6 7
1218 /// // | | ╱ ╲
1219 /// // 8 9 10 11
1220 ///
1221 /// let mut tree = DynTree::new(1);
1222 ///
1223 /// let mut root = tree.root_mut();
1224 /// let [id2, id3] = root.push_children([2, 3]);
1225 ///
1226 /// let mut n2 = tree.node_mut(id2);
1227 /// let [id4, _] = n2.push_children([4, 5]);
1228 ///
1229 /// tree.node_mut(id4).push_child(8);
1230 ///
1231 /// let mut n3 = tree.node_mut(id3);
1232 /// let [id6, id7] = n3.push_children([6, 7]);
1233 ///
1234 /// tree.node_mut(id6).push_child(9);
1235 /// tree.node_mut(id7).push_children([10, 11]);
1236 ///
1237 /// // paths from all leaves to the root
1238 ///
1239 /// let root = tree.root();
1240 ///
1241 /// // sorted in the order of leaves by breadth-first:
1242 /// // 5, 8, 9, 10, 11
1243 /// let paths: Vec<_> = root
1244 /// .paths::<Bfs>()
1245 /// .map(|x| x.copied().collect::<Vec<_>>())
1246 /// .collect();
1247 ///
1248 /// assert_eq!(
1249 /// paths,
1250 /// [
1251 /// vec![5, 2, 1],
1252 /// vec![8, 4, 2, 1],
1253 /// vec![9, 6, 3, 1],
1254 /// vec![10, 7, 3, 1],
1255 /// vec![11, 7, 3, 1]
1256 /// ]
1257 /// );
1258 ///
1259 /// // paths from all leaves of subtree rooted at n3
1260 ///
1261 /// let n3 = tree.node(id3);
1262 ///
1263 /// let paths: Vec<_> = n3
1264 /// .paths::<Dfs>()
1265 /// .map(|x| x.copied().collect::<Vec<_>>())
1266 /// .collect();
1267 ///
1268 /// assert_eq!(paths, [vec![9, 6, 3], vec![10, 7, 3], vec![11, 7, 3]]);
1269 ///
1270 /// // Iterable: convert each path into Iterable paths
1271 /// let paths = root.paths::<Bfs>().map(|x| x.into_iterable().copied());
1272 ///
1273 /// // we can iterate over each path multiple times without needing to collect them into a Vec
1274 /// let max_label_path: Vec<_> = paths
1275 /// .filter(|path| path.iter().all(|x| x != 7)) // does not contain 7
1276 /// .max_by_key(|path| path.iter().sum::<i32>()) // has maximal sum of node labels
1277 /// .map(|path| path.iter().collect::<Vec<_>>()) // only collect the selected path
1278 /// .unwrap();
1279 /// assert_eq!(max_label_path, vec![9, 6, 3, 1]);
1280 /// ```
1281 fn paths<T>(&'a self) -> impl Iterator<Item = impl Iterator<Item = &'a V::Item> + Clone>
1282 where
1283 T: Traverser<OverData>,
1284 {
1285 let node_ptr = self.node_ptr();
1286 T::iter_ptr_with_owned_storage(node_ptr)
1287 .filter(|x: &NodePtr<V>| unsafe { &*x.ptr() }.next().is_empty())
1288 .map(move |x: NodePtr<V>| {
1289 let iter = AncestorsIterPtr::new(node_ptr, x);
1290 iter.map(|ptr| (unsafe { &*ptr.ptr() }).data().expect("active tree node"))
1291 })
1292 }
1293
1294 /// Creates a **[parallel iterator]** of paths from all leaves of the subtree rooted at this node **upwards** to this node.
1295 ///
1296 /// Please see [`paths`] for details, since `paths_par` is the parallelized counterpart.
1297 /// * Parallel iterators can be used similar to regular iterators.
1298 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
1299 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
1300 ///
1301 /// [`paths`]: NodeRef::paths
1302 /// [parallel iterator]: orx_parallel::ParIter
1303 /// [`num_threads`]: orx_parallel::ParIter::num_threads
1304 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
1305 ///
1306 /// You may also see [paths_iterator](https://github.com/orxfun/orx-tree/blob/main/benches/paths_iterator.rs) benchmark to
1307 /// see an example use case.
1308 ///
1309 /// # Examples
1310 ///
1311 /// In the following example, we find the best path with respect to a linear-in-time computation.
1312 /// The computation demonstrates the following features:
1313 ///
1314 /// * We use `paths_par` rather than `paths` to parallelize the computation of path values.
1315 /// * We configure the parallel computation by limiting the number of threads using the `num_threads`
1316 /// method. Note that this is an optional parameter with a default value of [`Auto`].
1317 /// * We start computation by converting each `path` iterator into an [`Iterable`] using hte `into_iterable`
1318 /// method. This is a cheap transformation which allows us to iterate over the path multiple times
1319 /// without requiring to allocate and store them in a collection.
1320 /// * We select our best path by the `max_by_key` call.
1321 /// * Lastly, we collect the best path. Notice that this is the only allocated path.
1322 ///
1323 /// [`Auto`]: orx_parallel::NumThreads::Auto
1324 /// [`Iterable`]: orx_iterable::Iterable
1325 ///
1326 /// ```rust
1327 /// use orx_tree::*;
1328 /// use orx_iterable::*;
1329 ///
1330 /// fn build_tree(n: usize) -> DynTree<String> {
1331 /// let mut tree = DynTree::new(0.to_string());
1332 /// let mut dfs = Traversal.dfs().over_nodes();
1333 /// while tree.len() < n {
1334 /// let root = tree.root();
1335 /// let x: Vec<_> = root.leaves_with(&mut dfs).map(|x| x.idx()).collect();
1336 /// for idx in x {
1337 /// let count = tree.len();
1338 /// let mut node = tree.node_mut(idx);
1339 /// let num_children = 4;
1340 /// for j in 0..num_children {
1341 /// node.push_child((count + j).to_string());
1342 /// }
1343 /// }
1344 /// }
1345 /// tree
1346 /// }
1347 ///
1348 /// fn compute_path_value<'a>(mut path: impl Iterator<Item = &'a String>) -> u64 {
1349 /// match path.next() {
1350 /// Some(first) => {
1351 /// let mut abs_diff = 0;
1352 /// let mut current = first.parse::<u64>().unwrap();
1353 /// for node in path {
1354 /// let next = node.parse::<u64>().unwrap();
1355 /// abs_diff += match next >= current {
1356 /// true => next - current,
1357 /// false => current - next,
1358 /// };
1359 /// current = next;
1360 /// }
1361 /// abs_diff
1362 /// }
1363 /// None => 0,
1364 /// }
1365 /// }
1366 ///
1367 /// let tree = build_tree(1024);
1368 ///
1369 /// let root = tree.root();
1370 /// let best_path: Vec<_> = root
1371 /// .paths_par::<Dfs>() // parallelize
1372 /// .num_threads(4) // configure parallel computation
1373 /// .map(|path| path.into_iterable()) // into-iterable for multiple iterations over each path without allocation
1374 /// .max_by_key(|path| compute_path_value(path.iter())) // find the best path
1375 /// .map(|path| path.iter().collect()) // collect only the best path
1376 /// .unwrap();
1377 ///
1378 /// let expected = [1364, 340, 84, 20, 4, 0].map(|x| x.to_string());
1379 /// assert_eq!(best_path, expected.iter().collect::<Vec<_>>());
1380 /// ```
1381 #[cfg(feature = "parallel")]
1382 fn paths_par<T>(&'a self) -> impl ParIter<Item = impl Iterator<Item = &'a V::Item> + Clone>
1383 where
1384 T: Traverser<OverData>,
1385 V::Item: Send + Sync,
1386 {
1387 let node_ptr = self.node_ptr();
1388 let node_ptrs: alloc::vec::Vec<_> = T::iter_ptr_with_owned_storage(node_ptr)
1389 .filter(|x: &NodePtr<V>| unsafe { &*x.ptr() }.next().is_empty())
1390 .collect();
1391 node_ptrs.into_par().map(move |x| {
1392 let iter = AncestorsIterPtr::new(node_ptr, x);
1393 iter.map(|ptr| (unsafe { &*ptr.ptr() }).data().expect("active tree node"))
1394 })
1395 }
1396
1397 /// Returns an iterator of paths from all leaves of the subtree rooted at
1398 /// this node **upwards** to this node.
1399 ///
1400 /// The iterator yields one path per leaf node.
1401 ///
1402 /// The order of the leaves, and hence the corresponding paths, is determined
1403 /// by explicit type of the [`Traverser`] argument `traverser`.
1404 ///
1405 /// # Yields
1406 ///
1407 /// * `Iterator::Item` => `impl Iterator<Item = &'a V::Item>`
1408 /// when `T: Traverser<OverData>`
1409 /// * `Iterator::Item` => `impl Iterator<Item = Node<_>>`
1410 /// when `T: Traverser<OverNode>`
1411 ///
1412 /// # Examples
1413 ///
1414 /// ```
1415 /// use orx_tree::*;
1416 ///
1417 /// // 1
1418 /// // ╱ ╲
1419 /// // ╱ ╲
1420 /// // 2 3
1421 /// // ╱ ╲ ╱ ╲
1422 /// // 4 5 6 7
1423 /// // | | ╱ ╲
1424 /// // 8 9 10 11
1425 ///
1426 /// let mut tree = DynTree::new(1);
1427 ///
1428 /// let mut root = tree.root_mut();
1429 /// let [id2, id3] = root.push_children([2, 3]);
1430 ///
1431 /// let mut n2 = tree.node_mut(id2);
1432 /// let [id4, _] = n2.push_children([4, 5]);
1433 ///
1434 /// tree.node_mut(id4).push_child(8);
1435 ///
1436 /// let mut n3 = tree.node_mut(id3);
1437 /// let [id6, id7] = n3.push_children([6, 7]);
1438 ///
1439 /// tree.node_mut(id6).push_child(9);
1440 /// tree.node_mut(id7).push_children([10, 11]);
1441 ///
1442 /// // create a depth first traverser and reuse it
1443 ///
1444 /// let mut dfs = Traversal.dfs(); // OverData by default
1445 ///
1446 /// // paths from leaves as data of the nodes
1447 ///
1448 /// let root = tree.root();
1449 /// let paths: Vec<_> = root
1450 /// .paths_with(&mut dfs)
1451 /// .map(|path_data| path_data.copied().collect::<Vec<_>>())
1452 /// .collect();
1453 ///
1454 /// assert_eq!(
1455 /// paths,
1456 /// [
1457 /// vec![8, 4, 2, 1],
1458 /// vec![5, 2, 1],
1459 /// vec![9, 6, 3, 1],
1460 /// vec![10, 7, 3, 1],
1461 /// vec![11, 7, 3, 1]
1462 /// ]
1463 /// );
1464 ///
1465 /// // paths of subtree rooted at n3; as nodes rather than data.
1466 ///
1467 /// let mut dfs = dfs.over_nodes(); // transform from OverData to OverNode
1468 ///
1469 /// let n3 = tree.node(id3);
1470 ///
1471 /// let paths: Vec<_> = n3
1472 /// .paths_with(&mut dfs)
1473 /// .map(|path_nodes| {
1474 /// path_nodes
1475 /// .map(|node| (*node.data(), node.depth()))
1476 /// .collect::<Vec<_>>()
1477 /// })
1478 /// .collect();
1479 ///
1480 /// assert_eq!(
1481 /// paths,
1482 /// [
1483 /// [(9, 3), (6, 2), (3, 1)],
1484 /// [(10, 3), (7, 2), (3, 1)],
1485 /// [(11, 3), (7, 2), (3, 1)]
1486 /// ]
1487 /// );
1488 /// ```
1489 fn paths_with<T, O>(
1490 &'a self,
1491 traverser: &'a mut T,
1492 ) -> impl Iterator<Item = impl Iterator<Item = <O as Over>::NodeItem<'a, V, M, P>> + Clone>
1493 where
1494 O: Over<Enumeration = Val>,
1495 T: Traverser<O>,
1496 {
1497 let node_ptr = self.node_ptr();
1498 T::iter_ptr_with_storage(node_ptr, TraverserCore::storage_mut(traverser))
1499 .filter(|x| {
1500 let ptr: &NodePtr<V> = O::Enumeration::node_data(x);
1501 unsafe { &*ptr.ptr() }.next().is_empty()
1502 })
1503 .map(move |x| {
1504 let ptr: &NodePtr<V> = O::Enumeration::node_data(&x);
1505 let iter = AncestorsIterPtr::new(node_ptr, *ptr);
1506 iter.map(|ptr: NodePtr<V>| {
1507 O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>(
1508 self.col(),
1509 ptr,
1510 )
1511 })
1512 })
1513 }
1514
1515 /// Creates a **[parallel iterator]** of paths from all leaves of the subtree rooted at this node **upwards** to this node.
1516 ///
1517 /// Please see [`paths_with`] for details, since `paths_with_par` is the parallelized counterpart.
1518 /// * Parallel iterators can be used similar to regular iterators.
1519 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
1520 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
1521 ///
1522 /// [`paths_with`]: NodeRef::paths_with
1523 /// [parallel iterator]: orx_parallel::ParIter
1524 /// [`num_threads`]: orx_parallel::ParIter::num_threads
1525 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
1526 ///
1527 /// # Examples
1528 ///
1529 /// In the following example, we find the best path with respect to a linear-in-time computation.
1530 /// The computation demonstrates the following features:
1531 ///
1532 /// * We use `paths_with_par` rather than `paths_with` to parallelize the computation of path values.
1533 /// * We configure the parallel computation by limiting the number of threads using the `num_threads`
1534 /// method. Note that this is an optional parameter with a default value of [`Auto`].
1535 /// * We start computation by converting each `path` iterator into an [`Iterable`] using hte `into_iterable`
1536 /// method. This is a cheap transformation which allows us to iterate over the path multiple times
1537 /// without requiring to allocate and store them in a collection.
1538 /// * We select our best path by the `max_by_key` call.
1539 /// * Lastly, we collect the best path. Notice that this is the only allocated path.
1540 ///
1541 /// [`Auto`]: orx_parallel::NumThreads::Auto
1542 /// [`Iterable`]: orx_iterable::Iterable
1543 ///
1544 /// ```rust
1545 /// use orx_tree::*;
1546 /// use orx_iterable::*;
1547 ///
1548 /// fn build_tree(n: usize) -> DynTree<String> {
1549 /// let mut tree = DynTree::new(0.to_string());
1550 /// let mut dfs = Traversal.dfs().over_nodes();
1551 /// while tree.len() < n {
1552 /// let root = tree.root();
1553 /// let x: Vec<_> = root.leaves_with(&mut dfs).map(|x| x.idx()).collect();
1554 /// for idx in x {
1555 /// let count = tree.len();
1556 /// let mut node = tree.node_mut(idx);
1557 /// let num_children = 4;
1558 /// for j in 0..num_children {
1559 /// node.push_child((count + j).to_string());
1560 /// }
1561 /// }
1562 /// }
1563 /// tree
1564 /// }
1565 ///
1566 /// fn compute_path_value<'a>(mut path: impl Iterator<Item = &'a String>) -> u64 {
1567 /// match path.next() {
1568 /// Some(first) => {
1569 /// let mut abs_diff = 0;
1570 /// let mut current = first.parse::<u64>().unwrap();
1571 /// for node in path {
1572 /// let next = node.parse::<u64>().unwrap();
1573 /// abs_diff += match next >= current {
1574 /// true => next - current,
1575 /// false => current - next,
1576 /// };
1577 /// current = next;
1578 /// }
1579 /// abs_diff
1580 /// }
1581 /// None => 0,
1582 /// }
1583 /// }
1584 ///
1585 /// let tree = build_tree(1024);
1586 /// let mut dfs = Traversal.dfs().over_nodes();
1587 ///
1588 /// let root = tree.root();
1589 /// let best_path: Vec<_> = root
1590 /// .paths_with_par(&mut dfs) // parallelize
1591 /// .num_threads(4) // configure parallel computation
1592 /// .map(|path| path.into_iterable()) // into-iterable for multiple iterations over each path without allocation
1593 /// .max_by_key(|path| compute_path_value(path.iter().map(|x| x.data()))) // find the best path
1594 /// .map(|path| path.iter().map(|x| x.data()).collect()) // collect only the best path
1595 /// .unwrap();
1596 ///
1597 /// let expected = [1364, 340, 84, 20, 4, 0].map(|x| x.to_string());
1598 /// assert_eq!(best_path, expected.iter().collect::<Vec<_>>());
1599 /// ```
1600 #[cfg(feature = "parallel")]
1601 fn paths_with_par<T, O>(
1602 &'a self,
1603 traverser: &'a mut T,
1604 ) -> impl ParIter<Item = impl Iterator<Item = <O as Over>::NodeItem<'a, V, M, P>> + Clone>
1605 where
1606 O: Over<Enumeration = Val>,
1607 T: Traverser<O>,
1608 V::Item: Send + Sync,
1609 Self: Sync,
1610 {
1611 let node_ptr = self.node_ptr();
1612
1613 let node_ptrs: alloc::vec::Vec<_> =
1614 T::iter_ptr_with_storage(node_ptr, TraverserCore::storage_mut(traverser))
1615 .filter(|x: &NodePtr<V>| unsafe { &*x.ptr() }.next().is_empty())
1616 .collect();
1617 node_ptrs.into_par().map(move |x| {
1618 let iter = AncestorsIterPtr::new(node_ptr, x);
1619 iter.map(|ptr: NodePtr<V>| {
1620 O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>(
1621 self.col(),
1622 ptr,
1623 )
1624 })
1625 })
1626 }
1627
1628 /// Clone the subtree rooted at this node as a separate tree.
1629 ///
1630 /// # Examples
1631 ///
1632 /// ```
1633 /// use orx_tree::*;
1634 ///
1635 /// // 0
1636 /// // ╱ ╲
1637 /// // ╱ ╲
1638 /// // 1 2
1639 /// // ╱ ╲ ╱ ╲
1640 /// // 3 4 5 6
1641 /// // | | ╱ ╲
1642 /// // 7 8 9 10
1643 ///
1644 /// let mut tree = DynTree::new(0);
1645 ///
1646 /// let mut root = tree.root_mut();
1647 /// let [id1, id2] = root.push_children([1, 2]);
1648 ///
1649 /// let mut n1 = tree.node_mut(id1);
1650 /// let [id3, _] = n1.push_children([3, 4]);
1651 ///
1652 /// tree.node_mut(id3).push_child(7);
1653 ///
1654 /// let mut n2 = tree.node_mut(id2);
1655 /// let [id5, id6] = n2.push_children([5, 6]);
1656 ///
1657 /// tree.node_mut(id5).push_child(8);
1658 /// tree.node_mut(id6).push_children([9, 10]);
1659 ///
1660 /// let bfs: Vec<_> = tree.root().walk::<Bfs>().copied().collect();
1661 /// assert_eq!(bfs, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1662 ///
1663 /// // clone the subtree rooted at node 2 into another tree
1664 /// // which might be a different tree type
1665 ///
1666 /// let clone: BinaryTree<i32> = tree.node(id2).clone_as_tree();
1667 ///
1668 /// let bfs: Vec<_> = clone.root().walk::<Bfs>().copied().collect();
1669 /// assert_eq!(bfs, [2, 5, 6, 8, 9, 10]);
1670 /// ```
1671 fn clone_as_tree<V2>(&'a self) -> Tree<V2, M, P>
1672 where
1673 V2: TreeVariant<Item = V::Item> + 'a,
1674 P::PinnedVec<V2>: Default,
1675 V::Item: Clone,
1676 {
1677 let mut tree = Tree::new_with_root(self.data().clone());
1678
1679 for child in self.children() {
1680 tree.root_mut().push_child_tree(child.as_cloned_subtree());
1681 }
1682
1683 tree
1684 }
1685
1686 // traversal shorthands
1687
1688 /// Returns an iterator of references to data of leaves of the subtree rooted at this node.
1689 ///
1690 /// The order of the elements is determined by the type of the `traverser` which implements [`Traverser`].
1691 /// Available implementations are:
1692 /// * [`Bfs`] for breadth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search))
1693 /// * [`Dfs`] for (pre-order) depth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Depth-first_search))
1694 /// * [`PostOrder`] for post-order ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Post-order,_LRN))
1695 ///
1696 /// Note that `leaves` is a shorthand of a chain of iterator methods over the more general [`walk_with`] method.
1697 /// This is demonstrated in the example below.
1698 ///
1699 /// [`walk_with`]: crate::NodeRef::walk_with
1700 /// [`Bfs`]: crate::Bfs
1701 /// [`Dfs`]: crate::Dfs
1702 /// [`PostOrder`]: crate::PostOrder
1703 ///
1704 /// # Examples
1705 ///
1706 /// ```
1707 /// use orx_tree::*;
1708 ///
1709 /// // 1
1710 /// // ╱ ╲
1711 /// // ╱ ╲
1712 /// // 2 3
1713 /// // ╱ ╲ ╱ ╲
1714 /// // 4 5 6 7
1715 /// // | | ╱ ╲
1716 /// // 8 9 10 11
1717 ///
1718 /// let mut tree = DynTree::new(1);
1719 ///
1720 /// let mut root = tree.root_mut();
1721 /// let [id2, id3] = root.push_children([2, 3]);
1722 ///
1723 /// let mut n2 = tree.node_mut(id2);
1724 /// let [id4, _] = n2.push_children([4, 5]);
1725 ///
1726 /// tree.node_mut(id4).push_child(8);
1727 ///
1728 /// let mut n3 = tree.node_mut(id3);
1729 /// let [id6, id7] = n3.push_children([6, 7]);
1730 ///
1731 /// tree.node_mut(id6).push_child(9);
1732 /// tree.node_mut(id7).push_children([10, 11]);
1733 ///
1734 /// // access the leaves in different orders that is determined by traversal
1735 ///
1736 /// let root = tree.root();
1737 ///
1738 /// let bfs_leaves: Vec<_> = root.leaves::<Bfs>().copied().collect();
1739 /// assert_eq!(bfs_leaves, [5, 8, 9, 10, 11]);
1740 ///
1741 /// let dfs_leaves: Vec<_> = root.leaves::<Dfs>().copied().collect();
1742 /// assert_eq!(dfs_leaves, [8, 5, 9, 10, 11]);
1743 ///
1744 /// // get the leaves from any node
1745 ///
1746 /// let n3 = tree.node(id3);
1747 /// let leaves: Vec<_> = n3.leaves::<PostOrder>().copied().collect();
1748 /// assert_eq!(leaves, [9, 10, 11]);
1749 ///
1750 /// // ALTERNATIVELY: get the leaves with walk_with
1751 ///
1752 /// let mut tr = Traversal.bfs().over_nodes(); // we need Node to filter leaves
1753 ///
1754 /// let bfs_leaves: Vec<_> = root
1755 /// .walk_with(&mut tr)
1756 /// .filter(|x| x.is_leaf())
1757 /// .map(|x| *x.data())
1758 /// .collect();
1759 /// assert_eq!(bfs_leaves, [5, 8, 9, 10, 11]);
1760 /// ```
1761 fn leaves<T>(&'a self) -> impl Iterator<Item = &'a V::Item>
1762 where
1763 T: Traverser<OverData>,
1764 {
1765 T::iter_ptr_with_owned_storage(self.node_ptr())
1766 .filter(|x: &NodePtr<V>| unsafe { &*x.ptr() }.next().is_empty())
1767 .map(|x: NodePtr<V>| {
1768 <OverData as Over>::Enumeration::from_element_ptr::<'a, V, M, P, &'a V::Item>(
1769 self.col(),
1770 x,
1771 )
1772 })
1773 }
1774
1775 /// Creates a **[parallel iterator]** of references to data of leaves of the subtree rooted at this node.
1776 ///
1777 /// Please see [`leaves`] for details, since `leaves_par` is the parallelized counterpart.
1778 /// * Parallel iterators can be used similar to regular iterators.
1779 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
1780 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
1781 ///
1782 /// [`leaves`]: NodeRef::leaves
1783 /// [parallel iterator]: orx_parallel::ParIter
1784 /// [`num_threads`]: orx_parallel::ParIter::num_threads
1785 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
1786 #[cfg(feature = "parallel")]
1787 fn leaves_par<T>(&'a self) -> impl ParIter<Item = &'a V::Item>
1788 where
1789 T: Traverser<OverData>,
1790 V::Item: Send + Sync,
1791 {
1792 self.leaves::<T>()
1793 .collect::<alloc::vec::Vec<_>>()
1794 .into_par()
1795 }
1796
1797 /// Returns an iterator of leaves of the subtree rooted at this node.
1798 ///
1799 /// The order of the elements is determined by the type of the `traverser` which implements [`Traverser`].
1800 /// Available implementations are:
1801 /// * [`Bfs`] for breadth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search))
1802 /// * [`Dfs`] for (pre-order) depth-first ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Depth-first_search))
1803 /// * [`PostOrder`] for post-order ([wikipedia](https://en.wikipedia.org/wiki/Tree_traversal#Post-order,_LRN))
1804 ///
1805 /// Note that `leaves` is a shorthand of a chain of iterator methods over the more general [`walk_with`] method.
1806 /// This is demonstrated in the example below.
1807 ///
1808 /// [`walk_with`]: crate::NodeRef::walk_with
1809 /// [`Bfs`]: crate::Bfs
1810 /// [`Dfs`]: crate::Dfs
1811 /// [`PostOrder`]: crate::PostOrder
1812 ///
1813 /// # Examples
1814 ///
1815 /// ```
1816 /// use orx_tree::*;
1817 ///
1818 /// // 1
1819 /// // ╱ ╲
1820 /// // ╱ ╲
1821 /// // 2 3
1822 /// // ╱ ╲ ╱ ╲
1823 /// // 4 5 6 7
1824 /// // | | ╱ ╲
1825 /// // 8 9 10 11
1826 ///
1827 /// let mut tree = DynTree::new(1);
1828 ///
1829 /// let mut root = tree.root_mut();
1830 /// let [id2, id3] = root.push_children([2, 3]);
1831 ///
1832 /// let mut n2 = tree.node_mut(id2);
1833 /// let [id4, _] = n2.push_children([4, 5]);
1834 ///
1835 /// tree.node_mut(id4).push_child(8);
1836 ///
1837 /// let mut n3 = tree.node_mut(id3);
1838 /// let [id6, id7] = n3.push_children([6, 7]);
1839 ///
1840 /// tree.node_mut(id6).push_child(9);
1841 /// tree.node_mut(id7).push_children([10, 11]);
1842 ///
1843 /// // access leaves with re-usable traverser
1844 ///
1845 /// let mut bfs = Traversal.bfs();
1846 /// assert_eq!(
1847 /// tree.root().leaves_with(&mut bfs).collect::<Vec<_>>(),
1848 /// [&5, &8, &9, &10, &11]
1849 /// );
1850 /// assert_eq!(
1851 /// tree.node(id3).leaves_with(&mut bfs).collect::<Vec<_>>(),
1852 /// [&9, &10, &11]
1853 /// );
1854 ///
1855 /// // access leaf nodes instead of data
1856 ///
1857 /// let mut dfs = Traversal.dfs().over_nodes();
1858 ///
1859 /// let root = tree.root();
1860 /// let mut leaves = root.leaves_with(&mut dfs);
1861 ///
1862 /// let leaf: Node<_> = leaves.next().unwrap();
1863 /// assert!(leaf.is_leaf());
1864 /// assert_eq!(leaf.data(), &8);
1865 /// assert_eq!(leaf.parent(), Some(tree.node(id4)));
1866 ///
1867 /// // add depth and/or sibling-idx to the iteration items
1868 ///
1869 /// let mut dfs = Traversal.dfs().over_nodes().with_depth().with_sibling_idx();
1870 /// let mut leaves = root.leaves_with(&mut dfs);
1871 /// let (depth, sibling_idx, leaf) = leaves.next().unwrap();
1872 /// assert_eq!(depth, 3);
1873 /// assert_eq!(sibling_idx, 0);
1874 /// assert_eq!(leaf.data(), &8);
1875 /// ```
1876 fn leaves_with<T, O>(
1877 &'a self,
1878 traverser: &'a mut T,
1879 ) -> impl Iterator<Item = OverItem<'a, V, O, M, P>>
1880 where
1881 O: Over,
1882 T: Traverser<O>,
1883 {
1884 T::iter_ptr_with_storage(self.node_ptr(), traverser.storage_mut())
1885 .filter(|x| {
1886 let ptr: &NodePtr<V> = O::Enumeration::node_data(x);
1887 unsafe { &*ptr.ptr() }.next().is_empty()
1888 })
1889 .map(|x| {
1890 O::Enumeration::from_element_ptr::<'a, V, M, P, O::NodeItem<'a, V, M, P>>(
1891 self.col(),
1892 x,
1893 )
1894 })
1895 }
1896
1897 /// Creates a **[parallel iterator]** of references to data of leaves of the subtree rooted at this node.
1898 ///
1899 /// Please see [`leaves_with`] for details, since `leaves_with_par` is the parallelized counterpart.
1900 /// * Parallel iterators can be used similar to regular iterators.
1901 /// * Parallel computation can be configured by using methods such as [`num_threads`] or [`chunk_size`] on the parallel iterator.
1902 /// * Parallel counterparts of the tree iterators are available with **parallel** feature.
1903 ///
1904 /// [`leaves_with`]: NodeRef::leaves_with
1905 /// [parallel iterator]: orx_parallel::ParIter
1906 /// [`num_threads`]: orx_parallel::ParIter::num_threads
1907 /// [`chunk_size`]: orx_parallel::ParIter::chunk_size
1908 #[cfg(feature = "parallel")]
1909 fn leaves_with_par<T, O>(
1910 &'a self,
1911 traverser: &'a mut T,
1912 ) -> impl ParIter<Item = OverItem<'a, V, O, M, P>>
1913 where
1914 O: Over,
1915 T: Traverser<O>,
1916 OverItem<'a, V, O, M, P>: Send + Sync,
1917 {
1918 self.leaves_with(traverser)
1919 .collect::<alloc::vec::Vec<_>>()
1920 .into_par()
1921 }
1922
1923 /// Returns an iterator of node indices.
1924 ///
1925 /// The order of the indices is determined by the generic [`Traverser`] parameter `T`.
1926 ///
1927 /// # See also
1928 ///
1929 /// Note that tree traversing methods typically allocate a temporary data structure that is dropped once the
1930 /// iterator is dropped.
1931 /// In use cases where we repeatedly iterate using any of the **walk** methods over different nodes or different
1932 /// trees, we can avoid the allocation by creating the traverser only once and using [`indices_with`] methods instead.
1933 /// This method additionally allow for yielding node depths and sibling indices in addition to node indices.
1934 ///
1935 /// [`indices_with`]: crate::NodeRef::indices_with
1936 ///
1937 /// # Examples
1938 ///
1939 /// ```
1940 /// use orx_tree::*;
1941 ///
1942 /// // 0
1943 /// // ╱ ╲
1944 /// // ╱ ╲
1945 /// // 1 2
1946 /// // ╱ ╲ ╱ ╲
1947 /// // 3 4 5 6
1948 /// // | | ╱ ╲
1949 /// // 7 8 9 10
1950 ///
1951 /// let mut a = DynTree::new(0);
1952 /// let [a1, a2] = a.root_mut().push_children([1, 2]);
1953 /// let [a3, _] = a.node_mut(a1).push_children([3, 4]);
1954 /// a.node_mut(a3).push_child(7);
1955 /// let [a5, a6] = a.node_mut(a2).push_children([5, 6]);
1956 /// a.node_mut(a5).push_child(8);
1957 /// a.node_mut(a6).push_children([9, 10]);
1958 ///
1959 /// // collect indices in breadth-first order
1960 ///
1961 /// let a0 = a.root();
1962 /// let bfs_indices: Vec<_> = a0.indices::<Bfs>().collect();
1963 ///
1964 /// assert_eq!(a.node(bfs_indices[0]).data(), &0);
1965 /// assert_eq!(a.node(bfs_indices[1]).data(), &1);
1966 /// assert_eq!(a.node(bfs_indices[2]).data(), &2);
1967 /// assert_eq!(a.node(bfs_indices[3]).data(), &3);
1968 ///
1969 /// // collect indices in depth-first order
1970 /// // we may also re-use a traverser
1971 ///
1972 /// let mut t = Traversal.dfs();
1973 ///
1974 /// let a0 = a.root();
1975 /// let dfs_indices: Vec<_> = a0.indices_with(&mut t).collect();
1976 ///
1977 /// assert_eq!(a.node(dfs_indices[0]).data(), &0);
1978 /// assert_eq!(a.node(dfs_indices[1]).data(), &1);
1979 /// assert_eq!(a.node(dfs_indices[2]).data(), &3);
1980 /// assert_eq!(a.node(dfs_indices[3]).data(), &7);
1981 /// ```
1982 fn indices<T>(&self) -> impl Iterator<Item = NodeIdx<V>>
1983 where
1984 T: Traverser<OverData>,
1985 V: 'static,
1986 {
1987 let node_ptr = self.node_ptr();
1988 let state = self.col().memory_state();
1989 T::iter_ptr_with_owned_storage(node_ptr)
1990 .map(move |x: NodePtr<V>| NodeIdx(orx_selfref_col::NodeIdx::new(state, x)))
1991 }
1992
1993 /// Returns an iterator of node indices.
1994 ///
1995 /// The order of the indices is determined by the generic [`Traverser`] parameter `T` of the given `traverser`.
1996 ///
1997 /// Depending on the traverser type, the iterator might yield:
1998 ///
1999 /// * NodeIdx
2000 /// * (depth, NodeIdx)
2001 /// * (sibling_idx, NodeIdx)
2002 /// * (depth, sibling_idx, NodeIdx)
2003 ///
2004 /// # See also
2005 ///
2006 /// Note that tree traversing methods typically allocate a temporary data structure that is dropped once the
2007 /// iterator is dropped.
2008 /// In use cases where we repeatedly iterate using any of the **walk** methods over different nodes or different
2009 /// trees, we can avoid the allocation by creating the traverser only once and using [`indices_with`] methods instead.
2010 /// This method additionally allow for yielding node depths and sibling indices in addition to node indices.
2011 ///
2012 /// [`indices_with`]: crate::NodeRef::indices_with
2013 fn indices_with<T, O>(
2014 &self,
2015 traverser: &mut T,
2016 ) -> impl Iterator<Item = <O::Enumeration as Enumeration>::Item<NodeIdx<V>>>
2017 where
2018 O: Over,
2019 T: Traverser<O>,
2020 V: 'static,
2021 Self: Sized,
2022 {
2023 let node_ptr = self.node_ptr();
2024 let state = self.col().memory_state();
2025 T::iter_ptr_with_storage(node_ptr, traverser.storage_mut()).map(move |x| {
2026 <O::Enumeration as Enumeration>::map_node_data(x, |ptr: NodePtr<V>| {
2027 NodeIdx(orx_selfref_col::NodeIdx::new(state, ptr))
2028 })
2029 })
2030 }
2031
2032 // subtree
2033
2034 /// Creates a subtree view including this node as the root and all of its descendants with their orientation relative
2035 /// to this node.
2036 ///
2037 /// Consuming the created subtree in methods such as [`push_child_tree`] or [`push_sibling_tree`] will create
2038 /// the same subtree structure in the target tree with cloned values.
2039 /// This subtree and the tree it belongs to remain unchanged.
2040 /// Please see **Append Subtree cloned-copied from another Tree** section of the examples of these methods.
2041 ///
2042 /// Otherwise, it has no impact on the tree.
2043 ///
2044 /// [`push_child_tree`]: crate::NodeMut::push_child_tree
2045 /// [`push_sibling_tree`]: crate::NodeMut::push_sibling_tree
2046 #[allow(clippy::wrong_self_convention)]
2047 fn as_cloned_subtree(self) -> ClonedSubTree<'a, V, M, P, Self>
2048 where
2049 V::Item: Clone,
2050 Self: Sized,
2051 {
2052 ClonedSubTree::new(self)
2053 }
2054
2055 /// Creates a subtree view including this node as the root and all of its descendants with their orientation relative
2056 /// to this node.
2057 ///
2058 /// Consuming the created subtree in methods such as [`push_child_tree`] or [`push_sibling_tree`] will create
2059 /// the same subtree structure in the target tree with copied values.
2060 /// This subtree and the tree it belongs to remain unchanged.
2061 /// Please see **Append Subtree cloned-copied from another Tree** section of the examples of these methods.
2062 ///
2063 /// Otherwise, it has no impact on the tree.
2064 ///
2065 /// [`push_child_tree`]: crate::NodeMut::push_child_tree
2066 /// [`push_sibling_tree`]: crate::NodeMut::push_sibling_tree
2067 #[allow(clippy::wrong_self_convention)]
2068 fn as_copied_subtree(self) -> CopiedSubTree<'a, V, M, P, Self>
2069 where
2070 V::Item: Copy,
2071 Self: Sized,
2072 {
2073 CopiedSubTree::new(self)
2074 }
2075}