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