1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use crateParRecIter;
use crateId;
use cratedefault_runner;
/// Creates an infallible parallel iterator for dynamically expanding recursive workloads.
///
/// Unlike flat sources such as slices or ranges, recursive workloads discover new items while
/// existing items are being processed. `initial_elements` provides the starting frontier, and
/// `extend` is called for each visited item to produce its children or follow-up work.
///
/// Despite parallel execution, recursive traversal can be deterministic. With
/// [`IterationOrder::Ordered`] (the default), order-sensitive operations use breadth-first order,
/// level by level and left-to-right following input and child generation order.
///
/// # Example
///
/// ```
/// use orx_parallel::*;
///
/// // A small rooted tree represented as adjacency lists.
/// // Node 0 is the root.
/// let children: Vec<Vec<usize>> = vec![
/// vec![1, 2], // children of 0
/// vec![3, 4], // children of 1
/// vec![5], // children of 2
/// vec![],
/// vec![],
/// vec![],
/// ];
///
/// let visited: Vec<_> = par_recursive([0usize], |node| children[*node].iter().copied())
/// .map(|x| 2 * x + 1)
/// .collect();
///
/// // Ordered traversal is deterministic and breadth-first by default.
/// assert_eq!(visited, vec![1, 3, 5, 7, 9, 11]);
/// ```
///
/// [`IterationOrder::Ordered`]: crate::IterationOrder::Ordered