|
4 | 4 | [][crate]
|
5 | 5 | [][tests]
|
6 | 6 |
|
7 |
| -Vec-backed ID-tree. |
| 7 | +`ego-tree` is a Rust crate that provides a Vec-backed ID-tree implementation. It offers a flexible and efficient way to create and manipulate tree structures in Rust, with a focus on performance and ease of use. |
8 | 8 |
|
9 | 9 | `ego-tree` is on [Crates.io][crate] and [GitHub][github].
|
10 | 10 |
|
| 11 | +## Design Philosophy |
| 12 | + |
| 13 | +The design of `ego-tree` is centered around the following principles: |
| 14 | + |
| 15 | +1. **Efficiency**: The tree structure is backed by a Vec, allowing for fast, cache-friendly operations and efficient memory usage. |
| 16 | + |
| 17 | +2. **Flexibility**: Nodes can have any number of children, allowing for the representation of various tree structures. |
| 18 | + |
| 19 | +3. **Stability**: Node references remain valid even after modifying the tree structure, thanks to the use of stable NodeId indices. |
| 20 | + |
| 21 | +4. **Safety**: The API is designed to prevent common errors, such as creating cycles or detaching the root node. |
| 22 | + |
| 23 | +5. **Ergonomics**: The crate provides both low-level operations and high-level conveniences like the `tree!` macro for easy tree construction. |
| 24 | + |
| 25 | +## Key Design Choices |
| 26 | + |
| 27 | +### Vec-Backed Structure |
| 28 | + |
| 29 | +Unlike traditional pointer-based trees, `ego-tree` uses a Vec to store all nodes. This design choice offers several advantages: |
| 30 | + |
| 31 | +- Improved cache locality, potentially leading to better performance |
| 32 | +- Simplified memory management |
| 33 | +- Easier serialization and deserialization |
| 34 | +- Constant-time access to any node by its ID |
| 35 | + |
| 36 | +### Node IDs |
| 37 | + |
| 38 | +Nodes are identified by `NodeId`s, which are wrappers around indices into the underlying Vec. This approach allows for: |
| 39 | + |
| 40 | +- Stable references to nodes, even as the tree structure changes |
| 41 | +- Efficient node lookup (O(1) time complexity) |
| 42 | +- Compact representation of relationships between nodes |
| 43 | + |
| 44 | +### Immutable and Mutable Node References |
| 45 | + |
| 46 | +The crate provides both `NodeRef` (immutable) and `NodeMut` (mutable) types for working with nodes. This separation allows for: |
| 47 | + |
| 48 | +- Clear distinction between read-only and modifying operations |
| 49 | +- Prevention of multiple mutable references to the same node, enforcing Rust's borrowing rules |
| 50 | +- Efficient implementation of various tree traversal iterators |
| 51 | + |
| 52 | +### Orphan Nodes |
| 53 | + |
| 54 | +Nodes can be detached from the tree but not removed entirely. This design choice: |
| 55 | + |
| 56 | +- Simplifies certain tree manipulation algorithms |
| 57 | +- Allows for temporary detachment and reattachment of subtrees |
| 58 | +- Maintains the validity of NodeIds, even for detached nodes |
| 59 | + |
| 60 | +### Rich Iterator Support |
| 61 | + |
| 62 | +The crate provides a variety of iterator types for traversing the tree in different ways. This design: |
| 63 | + |
| 64 | +- Allows for efficient and idiomatic tree traversal |
| 65 | +- Supports various algorithms and use cases without sacrificing performance |
| 66 | +- Leverages Rust's powerful iterator ecosystem |
| 67 | + |
| 68 | +## Use Cases |
| 69 | + |
| 70 | +`ego-tree` is well-suited for applications that require: |
| 71 | + |
| 72 | +- Efficient representation and manipulation of hierarchical data structures |
| 73 | +- Frequent traversal and modification of tree structures |
| 74 | +- Stable references to tree nodes across operations |
| 75 | +- Serialization and deserialization of tree structures |
| 76 | + |
| 77 | +Some potential use cases include: |
| 78 | + |
| 79 | +- DOM-like structures for document processing |
| 80 | +- File system representations |
| 81 | +- Organizational hierarchies |
| 82 | +- Game scene graphs |
| 83 | +- Abstract syntax trees for compilers or interpreters |
| 84 | + |
| 85 | +## Getting Started |
| 86 | + |
| 87 | +Add this to your `Cargo.toml`: |
| 88 | + |
| 89 | +```toml |
| 90 | +[dependencies] |
| 91 | +ego-tree = "0.6.2" |
| 92 | +``` |
| 93 | + |
| 94 | +Basic usage: |
| 95 | + |
| 96 | +```rust |
| 97 | +use ego_tree::Tree; |
| 98 | + |
| 99 | +let mut tree = Tree::new(1); |
| 100 | +let mut root = tree.root_mut(); |
| 101 | +root.append(2); |
| 102 | +let mut child = root.append(3); |
| 103 | +child.append(4); |
| 104 | +child.append(5); |
| 105 | +``` |
| 106 | + |
| 107 | +For more detailed usage examples and API documentation, please refer to the [documentation](https://docs.rs/ego-tree). |
| 108 | + |
| 109 | +## License |
| 110 | + |
| 111 | +This project is licensed under the ISC License. |
| 112 | + |
| 113 | +## Contributing |
| 114 | + |
| 115 | +Contributions are welcome! Please feel free to submit a Pull Request. |
| 116 | + |
| 117 | +## Credits |
| 118 | + |
| 119 | +`ego-tree` is created and maintained by the team of [rust-scraper](https://github.com/rust-scraper). |
| 120 | + |
11 | 121 | [crate]: https://crates.io/crates/ego-tree
|
12 | 122 | [github]: https://github.com/rust-scraper/ego-tree
|
13 | 123 | [tests]: https://github.com/rust-scraper/ego-tree/actions/workflows/test.yml
|
0 commit comments