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