skew_forest/
lib.rs

1//! An implementation of skew-binary random access lists.
2//! 
3//! Skew-binary random access lists are a persistent list data structure. They allow logarithmic
4//! time random access. Most notably, online lowest common ancestors can be implemented in
5//! logarithmic time in the length of the path.
6//! 
7//! These lists are *persistent*, i.e. they allow preserving the old version of itself when mutated
8//! Eg. consider a simple list like this:
9//! 
10//! ```text
11//! A - B - C - D    List: ABCD
12//! ```
13//! 
14//! If, after B, we clone the list and append `E` and `F`, we will get the resulting structure:
15//! 
16//! ```text
17//! A - B - C - D    First list: ABCD
18//!       \ 
19//!         E - F    Second list: ABEF
20//! ```
21//! 
22//! Here we can see how `A` and `B` will be shared among the two lists. Thus the "lists" in skew-
23//! binary random access lists can really be seen as paths in a tree instead. To emphasize this,
24//! this implmentations refers to skew-binary random access lists as paths, or more specifically
25//! as the `SkewPath` type.
26//! 
27//! Since we want to be able to share nodes, the paths themselves do not own the nodes. Instead, the
28//! paths are indexes into a structure that *does* own the nodes. This structure, the `SkewForest`,
29//! encapsulates the shared graph of the paths.
30//! 
31//! # Topology
32//! 
33//! An additional wrinkle is that the `SkewForest` and `SkewPath` in this implementation does not
34//! store any actual values. They *only* store the path topology, i.e. the sequence of node indexes
35//! that forms the nodes of a path. When `push` operation is called on a `SkewPath` the index of the
36//! node is returned.
37//! 
38//! To actually associate a value with a node, a `SkewMap` can be constructed to map these indices
39//! to values.
40//! 
41//! # Example
42//! 
43//! The example below demonstrates creating two lists as shown above.
44//! 
45//! ```
46//! use skew_forest::{SkewForest, SkewPath, SkewPathNode, SkewMap};
47//!
48//! let mut forest = SkewForest::default();
49//! let mut path_a = SkewPath::<[SkewPathNode; 8]>::default();
50//! 
51//! // Push A and B onto `path_a`
52//! let node_a = forest.push(&mut path_a);
53//! let node_b = forest.push(&mut path_a);
54//! 
55//! // Clone A to B
56//! let mut path_b = path_a.clone();
57//! 
58//! // Push C and D onto `path_a`
59//! let node_c = forest.push(&mut path_a);
60//! let node_d = forest.push(&mut path_a);
61//! 
62//! // Push E and F onto `path_b`
63//! let node_e = forest.push(&mut path_b);
64//! let node_f = forest.push(&mut path_b);
65//! 
66//! // Check that `path_a` matches ABCD
67//! assert_eq!(
68//!     forest.iter(&path_a).collect::<Vec<_>>(),
69//!     vec![node_a, node_b, node_c, node_d],
70//! );
71//! 
72//! // Check that `path_b` matches ABCD
73//! assert_eq!(
74//!     forest.iter(&path_b).collect::<Vec<_>>(),
75//!     vec![node_a, node_b, node_e, node_f],
76//! );
77//! ```
78
79mod bits;
80mod forest;
81mod map;
82
83pub use forest::*;
84pub use map::*;