moonbitstack/moonstl/tree does not have a README file

    ArenaTree

    pub struct ArenaTree[T] {
    values : Array[T?]
    generations : Array[UInt]
    free : Array[Int]
    parents : Array[Int]
    first_child : Array[Int]
    last_child : Array[Int]
    previous : Array[Int]
    next : Array[Int]
    root : Int
    len : Int
    }

    A tree whose nodes live in one arena and are reached by id: a node knows its parent, its first and last child, and its two siblings, so every step of a walk is a field read and no pointer chases the allocator. Children are kept in insertion order, and sort_children reorders them by their own values.

    test {
    let tree : @tree.ArenaTree[String] = @tree.ArenaTree::new()
    let root = tree.add("root")
    let a = tree.add_child(root, "a")
    let _ = tree.add_child(root, "b")
    let _ = tree.add_child(a, "a1")
    assert_true(tree.length() == 4)
    assert_true(tree.children(root).length() == 2)
    assert_true(tree.descendants(root).to_array().length() == 3)
    assert_true(tree.remove(a) == Some("a"))
    assert_true(tree.length() == 2)
    }

    ArenaTree::add

    fn[T] ArenaTree::add(self : ArenaTree[T], value : T) -> TreeId

    Adds a detached node, which becomes a root of its own.

    ArenaTree::add_child

    fn[T] ArenaTree::add_child(self : ArenaTree[T], parent : TreeId, value : T) -> TreeId

    Adds a child at the end of parent's children and returns its id; a parent that is no longer in the tree yields the null id.

    ArenaTree::ancestors

    fn[T] ArenaTree::ancestors(self : ArenaTree[T], id : TreeId) -> Iter[TreeId]

    The root first, then each ancestor up to it.

    ArenaTree::children

    fn[T] ArenaTree::children(self : ArenaTree[T], id : TreeId) -> Array[TreeId]

    The ids of the children, in order.

    ArenaTree::clear

    fn[T] ArenaTree::clear(self : ArenaTree[T]) -> Unit

    Removes every node; the ids issued before it name nothing afterwards.

    ArenaTree::contains

    fn[T] ArenaTree::contains(self : ArenaTree[T], id : TreeId) -> Bool

    Whether id names a node.

    ArenaTree::copy

    fn[T] ArenaTree::copy(self : ArenaTree[T]) -> ArenaTree[T]

    A copy that owns its arrays: an edit to either tree leaves the other alone, and an id names the same node in both.

    ArenaTree::descendants

    fn[T] ArenaTree::descendants(self : ArenaTree[T], id : TreeId) -> Iter[TreeId]

    The children of a node, and their children, depth first and left to right.

    ArenaTree::detach

    fn[T] ArenaTree::detach(self : ArenaTree[T], id : TreeId) -> ArenaTree[T]?

    Cuts a subtree loose and returns it as a tree of its own. The copy owns its nodes, so the ids of the returned tree are its own; the original keeps its ids. The cost is the size of the subtree, because the nodes are rebuilt.

    ArenaTree::first_child

    fn[T] ArenaTree::first_child(self : ArenaTree[T], id : TreeId) -> TreeId?

    The first child of id, or None when it has none.

    ArenaTree::get

    fn[T] ArenaTree::get(self : ArenaTree[T], id : TreeId) -> T?

    The value behind id, or None when the id names nothing.

    ArenaTree::insert_after

    fn[T] ArenaTree::insert_after(self : ArenaTree[T], sibling : TreeId, value : T) -> TreeId

    Adds a sibling just after sibling and returns its id; a sibling that is no longer in the tree yields the null id.

    ArenaTree::insert_before

    fn[T] ArenaTree::insert_before(self : ArenaTree[T], sibling : TreeId, value : T) -> TreeId

    Adds a sibling just before sibling and returns its id; a sibling that is no longer in the tree yields the null id.

    ArenaTree::is_empty

    fn[T] ArenaTree::is_empty(self : ArenaTree[T]) -> Bool

    Whether the tree holds no node.

    ArenaTree::length

    fn[T] ArenaTree::length(self : ArenaTree[T]) -> Int

    The number of nodes.

    ArenaTree::new

    fn[T] ArenaTree::new() -> ArenaTree[T]

    An empty tree.

    ArenaTree::next_sibling

    fn[T] ArenaTree::next_sibling(self : ArenaTree[T], id : TreeId) -> TreeId?

    The sibling after id, or None when it is the last child.

    ArenaTree::parent

    fn[T] ArenaTree::parent(self : ArenaTree[T], id : TreeId) -> TreeId?

    The parent of id, or None when it is the root or names nothing.

    ArenaTree::postorder

    fn[T] ArenaTree::postorder(self : ArenaTree[T], id : TreeId) -> Iter[TreeId]

    The subtree in postorder: every child before its parent.

    ArenaTree::preorder

    fn[T] ArenaTree::preorder(self : ArenaTree[T], id : TreeId) -> Iter[TreeId]

    The whole tree in preorder, the node itself first.

    ArenaTree::prepend_child

    fn[T] ArenaTree::prepend_child(self : ArenaTree[T], parent : TreeId, value : T) -> TreeId

    Adds a child at the front of parent's children and returns its id; a parent that is no longer in the tree yields the null id.

    ArenaTree::previous_sibling

    fn[T] ArenaTree::previous_sibling(self : ArenaTree[T], id : TreeId) -> TreeId?

    The sibling before id, or None when it is the first child.

    ArenaTree::remove

    fn[T] ArenaTree::remove(self : ArenaTree[T], id : TreeId) -> T?

    Removes the node and everything below it, returning the value that was on it.

    ArenaTree::set

    fn[T] ArenaTree::set(self : ArenaTree[T], id : TreeId, value : T) -> Bool

    Replaces the value behind id and reports whether the id named a node.

    ArenaTree::siblings

    fn[T] ArenaTree::siblings(self : ArenaTree[T], id : TreeId) -> Array[TreeId]

    The siblings of a node, the node itself included, in order.

    ArenaTree::sort_children

    fn[T] ArenaTree::sort_children(self : ArenaTree[T], id : TreeId, cmp : (T, T) -> Int) -> Unit

    Reorders the children of id by their own values, keeping the links intact.

    DisjointSet

    pub struct DisjointSet {
    parents : Array[Int]
    sizes : Array[Int]
    sets : Int
    }

    Union-find over 0 ..< n: every set is a tree whose root carries its size, and find halves the path on the way up so repeated queries flatten the structure without a second pass. Union by size keeps the trees shallow, which together with path halving makes the amortised cost of an operation inverse Ackermann — effectively constant.

    test {
    let sets : @tree.DisjointSet = @tree.DisjointSet::new()
    let a = sets.add()
    let b = sets.add()
    let c = sets.add()
    assert_true(sets.union(a, b))
    assert_true(sets.connected(a, b))
    assert_true(!sets.connected(a, c))
    assert_true(sets.set_count() == 2)
    }

    DisjointSet::add

    fn DisjointSet::add(self : DisjointSet) -> Int

    Adds a singleton set and returns its index.

    DisjointSet::clear

    fn DisjointSet::clear(self : DisjointSet) -> Unit

    Removes every element, leaving a union-find with none.

    DisjointSet::component_size

    fn DisjointSet::component_size(self : DisjointSet, element : Int) -> Int

    The size of the set that holds element.

    DisjointSet::connected

    fn DisjointSet::connected(self : DisjointSet, a : Int, b : Int) -> Bool

    Whether two elements are in the same set; an element that was never added is in no set.

    DisjointSet::copy

    fn DisjointSet::copy(self : DisjointSet) -> DisjointSet

    An independent copy. Both sides own their own arrays, so a union or an added element in one leaves the other as it was, and the path that find flattens is flattened in one of them only.

    DisjointSet::find

    fn DisjointSet::find(self : DisjointSet, element : Int) -> Int

    The representative of the set that holds element, with the path halved on the way.

    DisjointSet::is_empty

    fn DisjointSet::is_empty(self : DisjointSet) -> Bool

    Whether no element has been added.

    DisjointSet::length

    fn DisjointSet::length(self : DisjointSet) -> Int

    The number of elements, not of sets.

    DisjointSet::new

    A union-find with no element in it.

    DisjointSet::set_count

    fn DisjointSet::set_count(self : DisjointSet) -> Int

    How many sets the elements are split into.

    DisjointSet::set_size

    fn DisjointSet::set_size(self : DisjointSet, root : Int) -> Int

    The size of the set whose representative is root, which is what a caller that already holds a root avoids a second find with.

    DisjointSet::to_sets

    fn DisjointSet::to_sets(self : DisjointSet) -> Array[Array[Int]]

    Every set as the array of its members, representatives first.

    DisjointSet::union

    fn DisjointSet::union(self : DisjointSet, a : Int, b : Int) -> Bool

    Joins the sets of two elements and reports whether they were apart.

    DisjointSetMap

    pub struct DisjointSetMap[K] {
    indices : Map[K, Int]
    sets : DisjointSet
    keys : Array[K]
    }

    Union-find over keys of any type: the key is interned to an index on first use, and the union-find runs on the indices.

    test {
    let sets : @tree.DisjointSetMap[String] = @tree.DisjointSetMap::new()
    assert_true(sets.union("a", "b"))
    assert_true(sets.connected("a", "b"))
    assert_true(!sets.connected("a", "c"))
    }

    DisjointSetMap::clear

    fn[K] DisjointSetMap::clear(self : DisjointSetMap[K]) -> Unit

    Removes every key, leaving a union-find with none.

    DisjointSetMap::component_size

    fn[K : Hash + Eq] DisjointSetMap::component_size(self : DisjointSetMap[K], key : K) -> Int

    The size of the set that holds key, zero when the key was never seen.

    DisjointSetMap::connected

    fn[K : Hash + Eq] DisjointSetMap::connected(self : DisjointSetMap[K], a : K, b : K) -> Bool

    Whether two keys are in the same set; a key that was never interned is in no set.

    DisjointSetMap::copy

    fn[K] DisjointSetMap::copy(self : DisjointSetMap[K]) -> DisjointSetMap[K]

    An independent copy: the keys and the union-find under them are both new, so a union on either side leaves the other as it was.

    DisjointSetMap::find

    fn[K : Hash + Eq] DisjointSetMap::find(self : DisjointSetMap[K], key : K) -> K?

    The key that represents the set holding key, or None when the key was never interned.

    DisjointSetMap::intern

    fn[K : Hash + Eq] DisjointSetMap::intern(self : DisjointSetMap[K], key : K) -> Int

    The index of a key, adding it as a singleton the first time it is seen.

    DisjointSetMap::is_empty

    fn[K] DisjointSetMap::is_empty(self : DisjointSetMap[K]) -> Bool

    Whether no key has been interned.

    DisjointSetMap::length

    fn[K] DisjointSetMap::length(self : DisjointSetMap[K]) -> Int

    How many keys have been interned.

    DisjointSetMap::new

    fn[K : Hash + Eq] DisjointSetMap::new() -> DisjointSetMap[K]

    A union-find over keys, with no key interned yet.

    DisjointSetMap::set_count

    fn[K] DisjointSetMap::set_count(self : DisjointSetMap[K]) -> Int

    How many sets the keys are split into.

    DisjointSetMap::to_sets

    fn[K] DisjointSetMap::to_sets(self : DisjointSetMap[K]) -> Array[Array[K]]

    Every set as the array of its members.

    DisjointSetMap::union

    fn[K : Hash + Eq] DisjointSetMap::union(self : DisjointSetMap[K], a : K, b : K) -> Bool

    Joins the sets of two keys, interning either if it is new, and reports whether they were apart.

    Fenwick

    pub struct Fenwick[T] {
    tree : Array[T]
    values : Array[T]
    length_ : Int
    }

    A Fenwick tree: tree[i] holds the sum of the i & -i elements that end at i, so a prefix sum reads one path to zero and an update writes one path to the end. Both are O(log n) with small constants, which is why it beats a segment tree for sums that only ever grow at a point.

    test {
    let fenwick : @tree.Fenwick[Int32] = @tree.Fenwick::new(length=5)
    fenwick.add(0, 3)
    fenwick.add(2, 4)
    assert_true(fenwick.prefix_sum(3) == 7)
    assert_true(fenwick.range_sum(1, 3) == 4)
    let _ = fenwick.set(0, 10)
    assert_true(fenwick.get(0) == Some(10))
    assert_true(fenwick.lower_bound(5) == Some(0))
    }

    Fenwick::add

    fn[T : Add] Fenwick::add(self : Fenwick[T], index : Int, delta : T) -> Unit

    Adds delta at index, which is the one point update a Fenwick tree supports.

    Fenwick::from_array

    fn[T : Add + Sub + Default] Fenwick::from_array(values : ArrayView[T]) -> Fenwick[T]

    A Fenwick tree over the values written out, with the prefix sums ready.

    Fenwick::get

    fn[T] Fenwick::get(self : Fenwick[T], index : Int) -> T?

    The value at index, or None past the last one.

    Fenwick::length

    fn[T] Fenwick::length(self : Fenwick[T]) -> Int

    How many positions the tree covers.

    Fenwick::lower_bound

    fn[T : Sub + Compare + Eq] Fenwick::lower_bound(self : Fenwick[T], target : T) -> Int?

    The first index whose prefix sum is strictly greater than target, which is how a Fenwick tree answers "where does this weight get spent" while every value stays non-negative. None when the whole tree does not reach it.

    Fenwick::new

    fn[T : Default] Fenwick::new(length~ : Int) -> Fenwick[T]

    A Fenwick tree of length zeros.

    Fenwick::prefix_sum

    fn[T : Add + Default] Fenwick::prefix_sum(self : Fenwick[T], end : Int) -> T

    The sum of the first end elements.

    Fenwick::range_sum

    fn[T : Add + Sub + Default] Fenwick::range_sum(self : Fenwick[T], start : Int, end : Int) -> T

    The sum of [start, end).

    Fenwick::set

    fn[T : Add + Sub] Fenwick::set(self : Fenwick[T], index : Int, value : T) -> Bool

    Replaces the value at index by adding the difference, so the prefix sums stay right.

    IntervalKey

    pub(all) struct IntervalKey[K] {
    index : Int
    generation : UInt
    } derive(Eq, Hash,
    Debug
    )

    A handle to one interval of an IntervalTree. Like a slot key, it carries the generation of the slot it was handed out for, so a handle to a removed interval reads as absent instead of reaching a later one.

    IntervalKey::equal

    fn[K : Eq] IntervalKey::equal(IntervalKey[K], IntervalKey[K]) -> Bool

    IntervalKey::hash

    fn[K : Hash] IntervalKey::hash(self : IntervalKey[K]) -> Int

    IntervalKey::hash_combine

    fn[K : Hash] IntervalKey::hash_combine(IntervalKey[K], Hasher) -> Unit

    IntervalKey::not_equal

    fn[K : Eq] IntervalKey::not_equal(x : IntervalKey[K], y : IntervalKey[K]) -> Bool

    IntervalTree

    pub struct IntervalTree[K, V] {
    cmp : (K, K) -> Int
    starts : Array[K?]
    ends : Array[K?]
    values : Array[V?]
    generations : Array[UInt]
    free : Array[Int]
    order : Array[Int]
    max_ends : Array[K?]
    len : Int
    }

    Intervals over a key type, kept sorted by start with a running maximum of the ends. That prefix maximum is what a point query walks back through: once a prefix can no longer reach the point, no interval before it can either, so the scan stops. Intervals are half-open, [start, end).

    test {
    let tree : @tree.IntervalTree[Int32, String] = @tree.IntervalTree::new()
    let _ = tree.insert(start=0, end=10, "a")
    let _ = tree.insert(start=5, end=15, "b")
    assert_true(tree.query_point(7).length() == 2)
    assert_true(tree.query_point(12).length() == 1)
    assert_true(tree.query_point(20).length() == 0)
    }

    IntervalTree::clear

    fn[K, V] IntervalTree::clear(self : IntervalTree[K, V]) -> Unit

    Removes every interval; the keys issued before it name nothing afterwards.

    IntervalTree::copy

    fn[K, V] IntervalTree::copy(self : IntervalTree[K, V]) -> IntervalTree[K, V]

    A copy that owns its arrays: a change to either tree leaves the other alone, and a key names the same interval in both.

    IntervalTree::get

    fn[K, V] IntervalTree::get(self : IntervalTree[K, V], key : IntervalKey[K]) -> (K, K, V)?

    The interval key names — its start, its end and its value — or None when the key names nothing.

    IntervalTree::insert

    fn[K, V] IntervalTree::insert(self : IntervalTree[K, V], start~ : K, end~ : K, value : V) -> IntervalKey[K]

    Adds the interval from start up to end, holding value, and returns the key that names it.

    IntervalTree::is_empty

    fn[K, V] IntervalTree::is_empty(self : IntervalTree[K, V]) -> Bool

    Whether the tree holds no interval.

    IntervalTree::iter

    fn[K, V] IntervalTree::iter(self : IntervalTree[K, V]) -> Iter[(K, K, V)]

    The intervals in start order.

    IntervalTree::length

    fn[K, V] IntervalTree::length(self : IntervalTree[K, V]) -> Int

    How many intervals the tree holds.

    IntervalTree::new

    fn[K : Compare + Eq, V] IntervalTree::new() -> IntervalTree[K, V]

    An empty tree of intervals ordered by start.

    IntervalTree::new_by

    fn[K, V] IntervalTree::new_by(cmp~ : (K, K) -> Int) -> IntervalTree[K, V]

    An empty tree of intervals ordered by cmp over their starts.

    IntervalTree::query_overlap

    fn[K, V] IntervalTree::query_overlap(self : IntervalTree[K, V], start~ : K, end~ : K) -> Array[(K, K, V)]

    Every interval that meets [start, end).

    IntervalTree::query_point

    fn[K, V] IntervalTree::query_point(self : IntervalTree[K, V], point : K) -> Array[(K, K, V)]

    Every interval that covers point.

    IntervalTree::remove

    fn[K, V] IntervalTree::remove(self : IntervalTree[K, V], key : IntervalKey[K]) -> (K, K, V)?

    Removes the interval key names and returns it.

    LazySegmentTree

    pub struct LazySegmentTree[T, F] {
    op : (T, T) -> T
    identity : T
    apply : (F, T, Int) -> T
    compose : (F, F) -> F
    none : F
    size : Int
    nodes : Array[T]
    tags : Array[F]
    }

    A segment tree that also accepts a range update: a tag is applied to a whole cover of a range and pushed down only when a later query or a partial update has to look inside. apply says what a tag does to an aggregate, compose merges an older tag into a newer one, and none is the tag that does nothing.

    test {
    let tree : @tree.LazySegmentTree[Int32, Int32] = @tree.LazySegmentTree::from_array(
    [1, 1, 1, 1],
    op=(a, b) => a + b,
    identity=0,
    apply=(tag, value, span) => value + tag * span,
    compose=(older, newer) => older + newer,
    none=0,
    )
    tree.range_update(1, 3, 5)
    assert_true(tree.query(0, 4) == 14)
    assert_true(tree.query(1, 2) == 6)
    }

    LazySegmentTree::from_array

    fn[T, F] LazySegmentTree::from_array(values : ArrayView[T], op~ : (T, T) -> T, identity~ : T, apply~ : (F, T, Int) -> T, compose~ : (F, F) -> F, none~ : F) -> LazySegmentTree[T, F]

    A tree over the values written out, with the range update the other arguments describe.

    LazySegmentTree::get

    fn[T, F] LazySegmentTree::get(self : LazySegmentTree[T, F], index : Int) -> T?

    The value at index after the updates that cover it, or None past the last leaf.

    LazySegmentTree::new

    fn[T, F] LazySegmentTree::new(length~ : Int, op~ : (T, T) -> T, identity~ : T, apply~ : (F, T, Int) -> T, compose~ : (F, F) -> F, none~ : F) -> LazySegmentTree[T, F]

    An empty tree of length leaves, each holding identity, ready for range updates.

    LazySegmentTree::query

    fn[T, F] LazySegmentTree::query(self : LazySegmentTree[T, F], start : Int, end : Int) -> T

    The combination of the leaves from start up to end, with the updates that cover them already applied.

    LazySegmentTree::range_update

    fn[T, F] LazySegmentTree::range_update(self : LazySegmentTree[T, F], start : Int, end : Int, tag : F) -> Unit

    Applies update to every leaf from start up to end, leaving the answer to any later query correct.

    LazySegmentTree::set

    fn[T, F] LazySegmentTree::set(self : LazySegmentTree[T, F], index : Int, value : T) -> Bool

    Replaces the value at index, keeping the updates that cover it.

    OrderStatisticTree

    pub struct OrderStatisticTree[T] {
    cmp : (T, T) -> Int
    keys : Array[T?]
    left : Array[Int]
    right : Array[Int]
    sizes : Array[Int]
    priorities : Array[UInt64]
    root : Int
    len : Int
    seed : UInt64
    }

    A search tree that also answers by position: every node carries the size of its subtree, so select and rank walk one path instead of counting. Duplicates are not stored. The shape is that of a treap, which is what keeps the depth logarithmic without rebalancing after every insert.

    test {
    let tree : @tree.OrderStatisticTree[Int32] = @tree.OrderStatisticTree::new()
    for value in [5, 1, 9, 3] {
    let _ = tree.insert(value)
    }
    assert_true(tree.select(0) == Some(1))
    assert_true(tree.select(3) == Some(9))
    assert_true(tree.rank(5) == 2)
    assert_true(tree.count_range(2, 9) == 2)
    }

    OrderStatisticTree::clear

    fn[T] OrderStatisticTree::clear(self : OrderStatisticTree[T]) -> Unit

    Removes every key.

    OrderStatisticTree::contains

    fn[T] OrderStatisticTree::contains(self : OrderStatisticTree[T], key : T) -> Bool

    Whether key is in the tree.

    OrderStatisticTree::copy

    A copy that owns its arrays: a change to either tree leaves the other alone.

    OrderStatisticTree::count_less

    fn[T] OrderStatisticTree::count_less(self : OrderStatisticTree[T], key : T) -> Int

    How many keys in the tree are smaller than key.

    OrderStatisticTree::count_range

    fn[T] OrderStatisticTree::count_range(self : OrderStatisticTree[T], start : T, end : T) -> Int

    The number of elements in [start, end), both ends compared by the tree's own comparator.

    OrderStatisticTree::first

    fn[T] OrderStatisticTree::first(self : OrderStatisticTree[T]) -> T?

    The smallest key, or None when the tree is empty.

    OrderStatisticTree::insert

    fn[T] OrderStatisticTree::insert(self : OrderStatisticTree[T], key : T) -> Bool

    Adds key and reports whether it was new; a key already in the tree is left alone.

    OrderStatisticTree::is_empty

    fn[T] OrderStatisticTree::is_empty(self : OrderStatisticTree[T]) -> Bool

    Whether the tree holds no key.

    OrderStatisticTree::iter

    fn[T] OrderStatisticTree::iter(self : OrderStatisticTree[T]) -> Iter[T]

    The keys ascending.

    OrderStatisticTree::last

    fn[T] OrderStatisticTree::last(self : OrderStatisticTree[T]) -> T?

    The largest key, or None when the tree is empty.

    OrderStatisticTree::length

    fn[T] OrderStatisticTree::length(self : OrderStatisticTree[T]) -> Int

    How many keys the tree holds.

    OrderStatisticTree::new

    An empty tree ordered ascending by the element's own order.

    OrderStatisticTree::new_by

    fn[T] OrderStatisticTree::new_by(cmp~ : (T, T) -> Int) -> OrderStatisticTree[T]

    An empty tree ordered by cmp, which reports the smaller of two elements as negative.

    OrderStatisticTree::range

    fn[T] OrderStatisticTree::range(self : OrderStatisticTree[T], start : T, end : T) -> Iter[T]

    The keys from start up to end, ascending.

    OrderStatisticTree::rank

    fn[T] OrderStatisticTree::rank(self : OrderStatisticTree[T], key : T) -> Int

    The number of elements smaller than key.

    OrderStatisticTree::remove

    fn[T] OrderStatisticTree::remove(self : OrderStatisticTree[T], key : T) -> Bool

    Removes key and reports whether it was there.

    OrderStatisticTree::select

    fn[T] OrderStatisticTree::select(self : OrderStatisticTree[T], index : Int) -> T?

    The element at position index, counting from zero.

    OrderStatisticTree::to_array

    fn[T] OrderStatisticTree::to_array(self : OrderStatisticTree[T]) -> Array[T]

    The keys ascending, as a new array.

    SegmentTree

    pub struct SegmentTree[T] {
    op : (T, T) -> T
    identity : T
    size : Int
    nodes : Array[T]
    }

    A range aggregate over a fixed array: the leaves are the elements, an inner node is op of its two children, and a query combines the O(log n) nodes that cover a half-open range. The operation has to be associative, and identity has to leave the other operand alone, which is what lets a query start from nothing.

    test {
    let tree : @tree.SegmentTree[Int32] = @tree.SegmentTree::from_array(
    [3, 1, 4, 1, 5],
    op=(a, b) => a + b,
    identity=0,
    )
    assert_true(tree.query(0, 3) == 8)
    assert_true(tree.query_all() == 14)
    let _ = tree.set(1, 10)
    assert_true(tree.query(0, 3) == 17)
    assert_true(tree.first_where(x => x >= 17) == Some(2))
    }

    SegmentTree::copy

    fn[T] SegmentTree::copy(self : SegmentTree[T]) -> SegmentTree[T]

    A copy that owns its nodes and the combining function: a change to either tree leaves the other alone.

    SegmentTree::first_where

    fn[T] SegmentTree::first_where(self : SegmentTree[T], predicate : (T) -> Bool) -> Int?

    The first position whose prefix aggregate satisfies predicate, or None. The descent relies on the predicate holding for a prefix once it holds for a smaller one, which is what makes a segment tree able to answer "where does this threshold get crossed" in O(log n).

    SegmentTree::from_array

    fn[T] SegmentTree::from_array(values : ArrayView[T], op~ : (T, T) -> T, identity~ : T) -> SegmentTree[T]

    A tree over the values written out, combining them with op at construction.

    SegmentTree::get

    fn[T] SegmentTree::get(self : SegmentTree[T], index : Int) -> T?

    The value at index, or None past the last leaf.

    SegmentTree::length

    fn[T] SegmentTree::length(self : SegmentTree[T]) -> Int

    How many leaves the tree covers.

    SegmentTree::new

    fn[T] SegmentTree::new(length~ : Int, op~ : (T, T) -> T, identity~ : T) -> SegmentTree[T]

    A tree over length positions, every one of them identity.

    SegmentTree::query

    fn[T] SegmentTree::query(self : SegmentTree[T], start : Int, end : Int) -> T

    The aggregate over [start, end), identity when the range is empty.

    SegmentTree::query_all

    fn[T] SegmentTree::query_all(self : SegmentTree[T]) -> T

    The combination of every leaf, which is the answer to query(0, length).

    SegmentTree::set

    fn[T] SegmentTree::set(self : SegmentTree[T], index : Int, value : T) -> Bool

    Replaces the value at index and brings the nodes above it up to date; reports whether the index was in range.

    SegmentTree::to_array

    fn[T] SegmentTree::to_array(self : SegmentTree[T]) -> Array[T]

    The leaves in order, as a new array.

    SkipList

    pub struct SkipList[T] {
    cmp : (T, T) -> Int
    options : SkipListOptions
    values : Array[T?]
    nexts : Array[Array[Int]]
    spans : Array[Array[Int]]
    len : Int
    rng : UInt64
    }

    A probabilistic ordered set. A node takes part in one level with probability p and in the next with p again, so a search skips most of the list at the top and refines as it descends; every level also stores how many nodes it spans, which is what makes rank and select a single descent. The shape is drawn from the seed, so a run replays exactly.

    test {
    let list : @tree.SkipList[Int32] = @tree.SkipList::new()
    for value in [5, 1, 9, 3] {
    let _ = list.insert(value)
    }
    assert_true(list.to_array() == [1, 3, 5, 9])
    assert_true(list.rank(5) == 2)
    assert_true(list.select(2) == Some(5))
    }

    SkipList::clear

    fn[T] SkipList::clear(self : SkipList[T]) -> Unit

    Removes every element, leaving the list at its initial height.

    SkipList::contains

    fn[T] SkipList::contains(self : SkipList[T], value : T) -> Bool

    Whether value is in the list.

    SkipList::first

    fn[T] SkipList::first(self : SkipList[T]) -> T?

    The smallest element, or None when the list is empty.

    SkipList::insert

    fn[T] SkipList::insert(self : SkipList[T], value : T) -> Bool

    Adds value and reports whether it was new.

    SkipList::is_empty

    fn[T] SkipList::is_empty(self : SkipList[T]) -> Bool

    Whether the list holds no element.

    SkipList::iter

    fn[T] SkipList::iter(self : SkipList[T]) -> Iter[T]

    The elements ascending.

    SkipList::last

    fn[T] SkipList::last(self : SkipList[T]) -> T?

    The largest element, or None when the list is empty.

    SkipList::length

    fn[T] SkipList::length(self : SkipList[T]) -> Int

    How many elements the list holds.

    SkipList::new

    fn[T : Compare + Eq] SkipList::new(skip_list_options? : SkipListOptions) -> SkipList[T]

    An empty list ordered ascending by the element's own order, with the level and density skip_list_options sets.

    SkipList::new_by

    fn[T] SkipList::new_by(cmp~ : (T, T) -> Int, skip_list_options? : SkipListOptions) -> SkipList[T]

    An empty list ordered by cmp, with the level and density skip_list_options sets.

    SkipList::range

    fn[T] SkipList::range(self : SkipList[T], start : T, end : T) -> Iter[T]

    The elements between start and end, both included by the list's own comparator.

    SkipList::rank

    fn[T] SkipList::rank(self : SkipList[T], value : T) -> Int

    The number of elements smaller than value.

    SkipList::remove

    fn[T] SkipList::remove(self : SkipList[T], value : T) -> Bool

    Removes value and reports whether it was there.

    SkipList::select

    fn[T] SkipList::select(self : SkipList[T], index : Int) -> T?

    The element at position index, counting from zero.

    SkipList::to_array

    fn[T] SkipList::to_array(self : SkipList[T]) -> Array[T]

    The elements ascending, as a new array.

    SkipListOptions

    pub(all) struct SkipListOptions {
    probability : Double
    max_level : Int
    seed : Int
    } derive(Eq,
    Debug
    )

    The shape of a skip list: how often a node is promoted to the next level, the highest level it may reach, and the seed its coin flips come from. The probability of 0.25 is what Redis uses, which keeps the level count low while keeping the paths short.

    SkipListOptions::equal

    SkipListOptions::not_equal

    fn SkipListOptions::not_equal(x : SkipListOptions, y : SkipListOptions) -> Bool

    Treap

    pub struct Treap[K, V] {
    cmp : (K, K) -> Int
    keys : Array[K?]
    values : Array[V?]
    left : Array[Int]
    right : Array[Int]
    priorities : Array[UInt64]
    root : Int
    len : Int
    seed : UInt64
    }

    A map held as a treap: the keys are kept in order, each node carries a random priority that keeps the tree balanced, and split and merge cut and join in one path. range walks the keys in order between two bounds.

    test {
    let tree : @tree.Treap[Int32, String] = @tree.Treap::new()
    let _ = tree.set(2, "b")
    let _ = tree.set(1, "a")
    let _ = tree.set(3, "c")
    assert_true(tree.get(2) == Some("b"))
    assert_true(tree.to_array() == [(1, "a"), (2, "b"), (3, "c")])
    assert_true(tree.remove(2) == Some("b"))
    }

    Treap::clear

    fn[K, V] Treap::clear(self : Treap[K, V]) -> Unit

    Removes every entry.

    Treap::contains

    fn[K, V] Treap::contains(self : Treap[K, V], key : K) -> Bool

    Whether key has a value.

    Treap::first

    fn[K, V] Treap::first(self : Treap[K, V]) -> (K, V)?

    The entry with the smallest key, or None when the tree is empty.

    Treap::get

    fn[K, V] Treap::get(self : Treap[K, V], key : K) -> V?

    The value under key, or None.

    Treap::is_empty

    fn[K, V] Treap::is_empty(self : Treap[K, V]) -> Bool

    Whether the tree holds no entry.

    Treap::iter

    fn[K, V] Treap::iter(self : Treap[K, V]) -> Iter[(K, V)]

    The entries in key order.

    Treap::last

    fn[K, V] Treap::last(self : Treap[K, V]) -> (K, V)?

    The entry with the largest key, or None when the tree is empty.

    Treap::length

    fn[K, V] Treap::length(self : Treap[K, V]) -> Int

    How many entries the tree holds.

    Treap::merge

    fn[K, V] Treap::merge(self : Treap[K, V], other : Treap[K, V]) -> Unit

    Joins two trees whose key ranges do not interleave.

    Treap::new

    fn[K : Compare + Eq, V] Treap::new() -> Treap[K, V]

    An empty tree ordered ascending by the key's own order.

    Treap::new_by

    fn[K, V] Treap::new_by(cmp~ : (K, K) -> Int) -> Treap[K, V]

    An empty tree ordered by cmp, which reports the smaller of two keys as negative.

    Treap::range

    fn[K, V] Treap::range(self : Treap[K, V], start : K, end : K) -> Iter[(K, V)]

    The entries whose key is from start up to end, in key order.

    Treap::remove

    fn[K, V] Treap::remove(self : Treap[K, V], key : K) -> V?

    Removes key and returns the value it held.

    Treap::set

    fn[K, V] Treap::set(self : Treap[K, V], key : K, value : V) -> V?

    Stores value under key and returns the value it replaced.

    Treap::split

    fn[K, V] Treap::split(self : Treap[K, V], key : K) -> (Treap[K, V], Treap[K, V])

    Splits the tree at key into the part below it and the part at or above it.

    Treap::to_array

    fn[K, V] Treap::to_array(self : Treap[K, V]) -> Array[(K, V)]

    The entries in key order, as a new array.

    TreeId

    pub(all) struct TreeId {
    index : Int
    generation : UInt
    } derive(Eq, Hash,
    Debug
    )

    A handle to one node of an ArenaTree: the slot the node occupies and the generation of that slot when the handle was handed out, so a handle to a removed node reads as absent rather than reaching whoever took the slot.

    TreeId::equal

    fn TreeId::equal(TreeId, TreeId) -> Bool

    TreeId::hash

    fn TreeId::hash(self : TreeId) -> Int

    TreeId::hash_combine

    fn TreeId::hash_combine(TreeId, Hasher) -> Unit

    TreeId::not_equal

    fn TreeId::not_equal(x : TreeId, y : TreeId) -> Bool

    TreeId::to_repr

    skip_list_options

    let skip_list_options : SkipListOptions

    The preset: a quarter of the nodes climb to the next level, and thirty-two levels cover 4^32 entries.