Skip to content

Commit 29ca6e9

Browse files
committed
documentation revised
1 parent 654594c commit 29ca6e9

File tree

1 file changed

+38
-37
lines changed

1 file changed

+38
-37
lines changed

README.md

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,31 @@
66

77
A beautiful tree 🌳 with convenient and efficient growth, mutation and parallelizable traversal features.
88

9-
## Features
10-
11-
### Tree Variants
9+
## Tree Variants
1210

1311
[`Tree`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html) is generic over variants that define the way the children are stored:
1412

1513
* [`DynTree<T>`](https://docs.rs/orx-tree/latest/orx_tree/type.DynTree.html), or equivalently **Tree&lt;Dyn&lt;T&gt;&gt;**, is a tree where each node may contain references to any number of children stored as a vector.
16-
* [`DaryTree<D, T>`](https://docs.rs/orx-tree/latest/orx_tree/type.DaryTree.html), or equivalently **Tree&lt;DaryTree&lt;D, T&gt;&gt;**, is a tree where each node may contain at most **D** child references stored inlined as an array.
14+
* [`DaryTree<D, T>`](https://docs.rs/orx-tree/latest/orx_tree/type.DaryTree.html), or equivalently **Tree&lt;Dary&lt;D, T&gt;&gt;**, is a tree where each node may contain at most **D** child references stored inlined as an array.
1715
* [`BinaryTree<T>`](https://docs.rs/orx-tree/latest/orx_tree/type.BinaryTree.html) is simply a shorthand for **DaryTree&lt;2, T&gt;**.
1816

19-
### Recursive Nature of Trees
17+
## Recursive Nature of Trees
2018

2119
Note that [`Tree`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html) has only few methods which mainly allow access to the root or to any node using node indices. Since every node is the root of a subtree, the core tree functionalities are provided as methods of [`NodeRef`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html) and [`NodeMut`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html), which are immutable and mutable nodes, respectively.
2220

23-
### Traversals
21+
## Iterations
22+
23+
### Walks over the Tree
2424

25-
We can iterate over all nodes of a subtree in various ways. In other words, we can *walk* the nodes of any subtree using a generic parameter which defines the order of traversal.
25+
We can visit all nodes of the tree in various ways. The way we *walk*, or the order of visited nodes, is determined by a generic traversal parameter.
2626

27-
To illustrate, let `node` be any node of the tree. Then:
27+
To demonstrate, consider the following methods of a tree node:
2828

29-
* [`node.walk::<Bfs>()`](https://docs.rs/orx-tree/latest/orx_tree/traversal/struct.Bfs.html) creates an iterator that visits all the nodes belonging to the subtree rooted at the *node* in the breadth-first order.
30-
* [`node.walk_mut::<Dfs>()`](https://docs.rs/orx-tree/latest/orx_tree/traversal/struct.Dfs.html) creates a mutable iterator, this time in depth-first (pre-)order.
31-
* [`node_into_walk::<PostOrder>()`](https://docs.rs/orx-tree/latest/orx_tree/traversal/struct.PostOrder.html), on the other hand, takes the subtree rooted at the *node* out of the tree and yields the elements in post-order.
29+
* [`walk::<Bfs>()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.walk) creates an iterator that visits all the nodes belonging to the subtree rooted at the *node* in the breadth-first order.
30+
* [`walk_mut::<Dfs>()`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.walk_mut) creates a mutable iterator, this time in depth-first order.
31+
* [`into_walk::<PostOrder>()`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.into_walk), on the other hand, takes the subtree rooted at the *node* out of the tree and yields the elements in post-order.
3232

33-
We can iterate over the data of the nodes, or over the nodes themselves with access to children, parent, siblings, etc. Further, just like *enumerate* appends the iteration order in a regular iterator, we can append tree-specific values to the iteration elements. Specifically, we can add the depth and/or the sibling position of each yield node. These more specialized traversals can be created conveniently using the [`Traversal`](https://docs.rs/orx-tree/latest/orx_tree/traversal/struct.Traversal.html) builder type.
33+
Walk iterators might yield node values or nodes with access to children, parent, siblings, etc. Further, node depth and/or its position among its siblings might be added. These more specialized traversals can be created conveniently using the [`Traversal`](https://docs.rs/orx-tree/latest/orx_tree/traversal/struct.Traversal.html) builder type.
3434

3535
*You may see the [walks](https://github.com/orxfun/orx-tree/blob/main/examples/walks.rs) example that demonstrates different ways to walk the tree with traversal variants (`cargo run --example walks`).*
3636

@@ -61,42 +61,44 @@ assert_eq!(
6161
);
6262
```
6363

64-
### Special Iterators
64+
### Custom Walk
6565

66-
In addition to iterators over all nodes of a subtree, we can create specialized iterators as well:
66+
In addition to common traversal strategies, we can create a **custom iterator** by simply calling [`custom_walk(next_node)`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.custom_walk) where the argument `next_node` is a function with signature `Fn(Node) -> Option<Node>` defining the traversal strategy.
6767

68-
* [`node.leaves::<Bfs>()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.leaves) yields the leaf nodes in the subtree rooted at *node* in breadth-first order.
69-
* [`node.paths::<Dfs>()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.paths) yields all the paths or sequences of nodes connecting the *node* to all of its leaves in the depth-first order.
70-
* [`node.ancestors()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.ancestors) provides an upward iterator from the *node* to the root of the tree.
68+
### Special Iterators
69+
70+
In addition to walks over subtrees, the following iterators are useful in special use cases.
7171

72-
*You may see the [special iterators](https://github.com/orxfun/orx-tree/blob/main/examples/special_iterators.rs) example that demonstrates different ways to walk the tree with traversal variants (`cargo run --example special_iterators`).*
72+
* [`leaves::<Bfs>()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.leaves) returns leaf nodes in breadth-first order.
73+
* [`paths::<Dfs>()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.paths) returns all the paths or sequences of nodes connecting the *node* to all of its leaves in the depth-first order.
74+
* [`ancestors()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.ancestors) provides an upward iterator from the *node* to the root of the tree.
7375

74-
### Manual Iteration
76+
*You may see the [special iterators](https://github.com/orxfun/orx-tree/blob/main/examples/special_iterators.rs) example.*
7577

76-
We can also walk the tree freely using methods to traverse the links in different ways, such as:
78+
### Manual Traversals
7779

78-
* [`node.child(child_idx)`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.child), [`node.children()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.children), [`node.children_mut()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.children_mut), [`node.into_child_mut(child_idx)`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.into_child_mut)
79-
* [`node.parent()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.parent), [`node.into_parent_mut()`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.into_parent_mut), etc.
80+
Alternatively, we can move on nodes of the tree freely:
8081

81-
Another way to create a **custom iterator** is simply calling [`node.custom_walk(next_node)`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.custom_walk) where the argument `next_node` is a function with pseudo-signature `Fn(Node) -> Option<Node>` and defines the traversal strategy.
82+
* **** [`child(child_idx)`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.child), [`children()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.children), [`children_mut()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.children_mut), [`into_child_mut(child_idx)`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.into_child_mut)
83+
* **** [`parent()`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.parent), [`into_parent_mut()`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.into_parent_mut), etc.
8284

83-
*You may see the [manual iteration](https://github.com/orxfun/orx-tree/blob/main/examples/manual_iteration.rs) example that demonstrates different ways to walk the tree with traversal variants (`cargo run --example manual_iteration`).*
85+
*You may see [manual iteration](https://github.com/orxfun/orx-tree/blob/main/examples/manual_iteration.rs) and [mutable_recursive_traversal](https://github.com/orxfun/orx-tree/blob/main/examples/mutable_recursive_traversal.rs) examples*
8486

8587
### Arbitrary Order Iterators
8688

87-
The tree naturally implements [`Collection`](https://docs.rs/orx-iterable/latest/orx_iterable/trait.Collection.html) and [`CollectionMut`](https://docs.rs/orx-iterable/latest/orx_iterable/trait.CollectionMut.html) providing iterators via `iter` and `iter_mut` methods. Since the tree is not a linear data structure, these iterators yield elements in an arbitrary (but deterministic) order, which is useful in certain situations such as updating the values of the tree using a transformation or applying reductions.
89+
The tree naturally implements `IntoIterator`, [`Collection`](https://docs.rs/orx-iterable/latest/orx_iterable/trait.Collection.html) and [`CollectionMut`](https://docs.rs/orx-iterable/latest/orx_iterable/trait.CollectionMut.html) providing iterators via `into_iter`, `iter` and `iter_mut` methods. These iterators yield elements in an arbitrary but deterministic order.
8890

89-
### Parallelization Support
91+
## Parallelization
9092

91-
`Tree` aims to enable flexible and convenient parallel computation. Almost all iterators, traversals or walks mentioned above can be parallelized using the [orx-parallel](https://crates.io/crates/orx-parallel) feature (`cargo add orx-tree --features orx-parallel`).
93+
`Tree` aims to enable convenient parallel computation for all iterators, traversals or walks mentioned above using the [orx-parallel](https://crates.io/crates/orx-parallel) feature (see [features](#features) section). Parallel counterparts return a [`ParIter`](https://docs.rs/orx-parallel/latest/orx_parallel/trait.ParIter.html) rather than a sequential `Iterator`.
9294

93-
[`tree.par()`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html#method.par) and [`tree.into_par()`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html#method.into_par) return parallel iterators over all nodes of the tree. Examples can be found in [`demo_parallelization`](https://github.com/orxfun/orx-tree/blob/main/examples/demo_parallelization.rs) example. Importantly note that the tree defines its own concurrent iterators, and hence, allows for efficient computation, which is often not possible with generic implementations. In order to check the impact in performance, you may use the lightweight benchmark example [`bench_parallelization`](https://github.com/orxfun/orx-linked-list/blob/main/examples/bench_parallelization.rs):
95+
[`tree.par()`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html#method.par) and [`tree.into_par()`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html#method.into_par) return parallel iterators over all nodes of the tree. Examples can be found in [`demo_parallelization`](https://github.com/orxfun/orx-tree/blob/main/examples/demo_parallelization.rs) example. Importantly note that the tree defines its own concurrent iterators, and hence, allows for efficient computation, which is often not possible with generic implementations. In order to check the impact in performance, you may use the lightweight benchmark example [`bench_parallelization`](https://github.com/orxfun/orx-tree/blob/main/examples/bench_parallelization.rs):
9496

9597
* `Sequential computation over Tree : 18.96s`
9698
* `Parallelized over Tree using orx-parallel : 6.02s`
9799
* `Parallelized over Tree using rayon's par-bridge : 81.10s`
98100

99-
Furthermore, walks with different traversal strategies and special iterators can be parallelized. The following is a list of methods providing the corresponding parallel iterators. Notice that parallelization is achieved simply by adding **_par** suffix to names of the sequential counterparts.
101+
Remaining walks and traversals can be parallelized by simply by adding **_par** suffix to names of their sequential counterparts:
100102

101103
[`children_par`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.children_par) |
102104
[`ancestors_par`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.ancestors_par) |
@@ -108,7 +110,7 @@ Furthermore, walks with different traversal strategies and special iterators can
108110
[`leaves_par`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.leaves_par) |
109111
[`leaves_with_par`](https://docs.rs/orx-tree/latest/orx_tree/trait.NodeRef.html#method.leaves_with_par) |
110112

111-
### Constant Time Access to Nodes via Node Indices
113+
## Constant Time Access to Nodes via Node Indices
112114

113115
A [`NodeIdx`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeIdx.html) for a [`Tree`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html) is similar to `usize` for a slice in that it allows constant time access to the node it is created for.
114116

@@ -129,16 +131,15 @@ Here, `idx` does not have a lifetime attached to the `tree`, yet it refers to th
129131
* `another_tree.node(&idx)` is an out-of-bounds error.
130132
* `tree.node(&idx)` after removing the node from the tree, say by `tree.node_mut(&idx).prune()` call, is a removed-node error.
131133

132-
133-
### Cache Locality
134+
## Cache Locality
134135

135136
Nodes of the tree are stored in an underlying [`PinnedVec`](https://crates.io/crates/orx-pinned-vec) with pinned element guarantees. This allows for keeping the nodes close to each other improving cache locality while still providing with constant time mutation methods.
136137

137-
### Convenient Mutations
138+
## Convenient Mutations
138139

139140
The tree aims to make every move on the tree possible, convenient and efficient.
140141

141-
#### Growth & Move Subtrees Around
142+
### Growth & Move Subtrees Around
142143

143144
The following methods demonstrate downward growth by adding descendants to a node:
144145

@@ -158,7 +159,7 @@ Note that all the growth methods return the indices of the created nodes allowin
158159

159160
Additionally, the tree provides methods for special moves such as [`swap_subtrees`](https://docs.rs/orx-tree/latest/orx_tree/struct.Tree.html#method.swap_subtrees) to swap components of the same tree.
160161

161-
#### Removals
162+
### Removals
162163

163164
We can take out a node from the tree, while connecting its parent to its children via the [`take_out`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.take_out) method.
164165

@@ -170,9 +171,9 @@ Alternatively, we can turn a mutable node into an [`into_walk`](https://docs.rs/
170171
* We can iterate over the removed nodes in the order of the generic traversal parameter and use the data however we need.
171172
* Or we can attach the removed subtree at a desired position of another tree by passing it to methods such as [`push_child_tree(subtree)`](https://docs.rs/orx-tree/latest/orx_tree/struct.NodeMut.html#method.push_child_tree).
172173

173-
## Features
174+
# Features
174175

175-
* **orx-parallel**: Tree allows efficient parallel processing through [concurrent iterators](https://crates.io/crates/orx-concurrent-iter) and [parallel iterators](https://crates.io/crates/orx-parallel). See [parallelization section](#parallelization-support) for details. This feature is added as default and requires **std**. Therefore, please use `cargo add orx-tree --no-default-features` for **no-std** use cases.
176+
* **orx-parallel**: Tree allows efficient parallel processing through [concurrent iterators](https://crates.io/crates/orx-concurrent-iter) and [parallel iterators](https://crates.io/crates/orx-parallel). See [parallelization section](#parallelization) for details. This feature is added as default and requires **std**. Therefore, please use `cargo add orx-tree --no-default-features` for **no-std** use cases.
176177

177178
* **serde**: Tree implements `Serialize` and `Deserialize` traits; the "serde" feature needs to be added when required. It uses a linearized representation of the tree as a [`DepthFirstSequence`](https://docs.rs/orx-tree/latest/orx_tree/struct.DepthFirstSequence.html). You may find de-serialization examples in the corresponding [test file](https://github.com/orxfun/orx-tree/blob/main/tests/serde.rs).
178179

0 commit comments

Comments
 (0)