File: README.md

package info (click to toggle)
rust-rctree 0.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 120 kB
  • sloc: makefile: 2
file content (100 lines) | stat: -rw-r--r-- 4,017 bytes parent folder | download
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# rctree
[![Build Status](https://travis-ci.org/RazrFalcon/rctree.svg?branch=master)](https://travis-ci.org/RazrFalcon/rctree)
[![Crates.io](https://img.shields.io/crates/v/rctree.svg)](https://crates.io/crates/rctree)
[![Documentation](https://docs.rs/rctree/badge.svg)](https://docs.rs/rctree)

*rctree* is a "DOM-like" tree implemented using reference counting.

### Origin

This a fork of the [rust-forest](https://github.com/SimonSapin/rust-forest) rctree.

### Details

"DOM-like" here means that data structures can be used to represent
the parsed content of an HTML or XML document,
like [*the* DOM](https://dom.spec.whatwg.org/) does,
but don't necessarily have the exact same API as the DOM.
That is:

* A tree is made up of nodes.
* Each node has zero or more *child* nodes, which are ordered.
* Each node has a no more than one *parent*, the node that it is a *child* of.
* A node without a *parent* is called a *root*.
* As a consequence, each node may also have *siblings*: its *parent*'s other *children*, if any.
* From any given node, access to its
  parent, previous sibling, next sibling, first child, and last child (if any)
  can take no more than *O(1)* time.
* Each node also has data associated to it,
  which for the purpose of this project is purely generic.
  For an HTML document, the data would be either the text of a text node,
  or the name and attributes of an element node.
* The tree is mutable:
  nodes (with their sub-trees) can be inserted or removed anywhere in the tree.

The lifetime of nodes is managed through *reference counting*.
To avoid reference cycles which would cause memory leaks, the tree is *asymmetric*:
each node holds optional *strong references* to its next sibling and first child,
but only optional *weak references* to its parent, previous sibling, and last child.

Nodes are destroyed as soon as there is no strong reference left to them.
The structure is such that holding a reference to the root
is sufficient to keep the entire tree alive.
However, if for example the only reference that exists from outside the tree
is one that you use to traverse it,
you will not be able to go back "up" the tree to ancestors and previous siblings after going "down",
as those nodes will have been destroyed.

Weak references to destroyed nodes are treated as if they were not set at all.
(E.g. a node can become a root when its parent is destroyed.)

Since nodes are *aliased* (have multiple references to them),
[`RefCell`](http://doc.rust-lang.org/std/cell/index.html) is used for interior mutability.

Advantages:

* A single `Node` user-visible type to manipulate the tree, with methods.
* Memory is freed as soon as it becomes unused (if parts of the tree are removed).

Disadvantages:

* The tree can only be accessed from the thread is was created in.
* Any tree manipulation, including read-only traversals,
  requires incrementing and decrementing reference counts,
  which causes run-time overhead.
* Nodes are allocated individually, which may cause memory fragmentation and hurt performance.

### Differences

* `NodeRef` -> `Node`.
* All nodes has a root node reference that can be accessed at *O(1)*.
* Added `make_copy`, `make_deep_copy`, `has_children` and `root` methods.
* `Node` implements `PartialEq` now.
* Used `std` features like `Rc::ptr_eq`, `Ref` and `RefMut` instead of handwritten one.
* `borrow_mut`, `detach`, `append`, `prepend`, `insert_after`, `insert_before`,
  `make_copy` and `make_deep_copy` are marked as `mut`.
* `append`, `prepend`, `insert_after` and `insert_before` methods will panic if
  the provided child/sibling is the same the same node.

### Usage

Dependency: [Rust](https://www.rust-lang.org/) >= 1.17

#### As source

The library consists of a single file which you can copy to your project.

This is a preferable solution since you can tweak the crate for your needs.

#### As crate

Add this to your `Cargo.toml`:

```toml
[dependencies]
rctree = "0.2"
```

### License

*rctree* is licensed under the **MIT**.