digitree
    Preparing search index...

    Class BTree<TKey, TEntry>

    Represents a lightweight B+(ish)Tree (data at leaves, but no linked list of leaves). Allows for efficient storage and retrieval of data in a sorted manner.

    Type Parameters

    • TKey

      The type of keys used for indexing the entries. This might be an element of TEntry, or TEntry itself.

    • TEntry

      The type of entries stored in the B-tree.

    Index

    Constructors

    • Type Parameters

      • TKey
      • TEntry

      Parameters

      • OptionalkeyFromEntry: (entry: TEntry) => TKey = ...

        a function to extract the key from an entry. The default assumes the key is the entry itself.

      • Optionalcompare: (a: TKey, b: TKey) => number = ...

        a comparison function for keys. The default uses < and > operators.

      • Optionaloptions: BTreeOptions

        optional per-tree tuning of the freeze / comparator-check safety costs. See BTreeOptions.

      Returns BTree<TKey, TEntry>

    Accessors

    • get size(): number

      The total number of entries in the tree (an alias for the no-arg getCount). O(1) - reads the stored count, maintained per mutation.

      Returns number

    Methods

    • Enables for (const entry of tree) and [...tree] - each element is a distinct entry in ascending key order (an alias for entries with no range).

      Returns IterableIterator<TEntry>

    • Iterates forward over live cursors, starting from the given path (inclusive) to the end. With no argument, starts from first (the whole tree, ascending).

      WARNING: this yields the SAME cursor object every step, mutated in place - so it is a cursor-level tool, not a collection. Spreading it ([...tree.ascending()]) or .mapping it gives N references to one path parked off the end, and reading them afterwards is all-undefined; read tree.at(path) INSIDE the loop, and path.clone() any cursor you need to retain. For the common "give me the entries" case prefer entries/keys, which yield distinct values and sidestep this entirely. WARNING: mutation during iteration invalidates the cursor and the next step will throw.

      Parameters

      Returns IterableIterator<Path<TKey, TEntry>>

    • Empties the tree, invalidating every outstanding path (a subsequent use throws InvalidPathError). The tree stays usable afterward: getCount is 0 and insert works again. This is the intended way to empty a tree in place, rather than deleting every entry or discarding the instance.

      Returns void

    • Invokes user-provided comperator to compare two keys. Inner-loop code, so this doesn't do backflips to iron out ES's idiosyncrasies (undefined quirks, infinity, nulls, etc.), but does ensure deterministic comparison.

      The antisymmetry check (a second, reversed compare) runs on every comparison when the tree was constructed with { checkComparator: true }; otherwise it runs only for the first BTree.SampleCheckCount comparisons (a cheap sample), then drops off the hot path entirely. A subtly-inconsistent comparator that only misbehaves deep in a large tree can therefore slip past the default sample — use { checkComparator: true } for the exhaustive (historical) check.

      If you want to eak out more performance at the risk of corruption, you can override this method and omit the consistency check.

      Parameters

      Returns number

    • Deletes the entry at the given path. The on property of the path will be cleared.

      Parameters

      Returns boolean

      true if the delete succeeded (the key was found); false otherwise.

    • Iterates backward over live cursors, starting from the given path (inclusive) to the start. With no argument, starts from last (the whole tree, descending).

      WARNING: same aliasing caveat as ascending - one reused, mutated cursor per step. Read inside the loop, clone() to retain, and prefer entries/keys when you just want the values. WARNING: mutation during iteration invalidates the cursor and the next step will throw.

      Parameters

      Returns IterableIterator<Path<TKey, TEntry>>

    • Yields each entry in the tree (or in range if given) directly - the safe, aliasing-free default for reading. No argument iterates the whole tree ascending; a KeyRange delegates to range (honoring direction and inclusive/exclusive bounds identically). Each yielded value is a distinct entry, so [...tree.entries()] and .map work as expected. WARNING: mutation during iteration invalidates the underlying cursor and the next step will throw.

      Parameters

      Returns IterableIterator<TEntry>

    • Attempts to find the given key

      Parameters

      Returns Path<TKey, TEntry>

      Path to the key or the "crack" before it. If on is true on the resulting path, the key was found. If on is false, next() and prior() can attempt to move to the nearest match.

    • Retrieves the entry for the given key. Use find instead for a path to the key, the nearest match, or as a basis for navigation.

      Parameters

      Returns undefined | TEntry

      the entry for the given key if found; undefined otherwise.

    • Number of entries in the tree. With no argument, O(1): returns the stored count.

      Parameters

      • Optionalfrom: { ascending?: boolean; path: Path<TKey, TEntry> }

        if provided, the count is a partial count that walks from the given path (inclusive) - O(n/af) where af is average fill. If ascending is false, the count starts from the end of the tree. Ascending is true by default. This overload cannot be answered from the stored count and always walks.

      Returns number

    • Adds a value to the tree. Be sure to check the result, as the tree does not allow duplicate keys. Added entries are frozen to ensure immutability

      Parameters

      Returns Path<TKey, TEntry>

      path to the new (on = true) or conflicting (on = false) row.

    • Inserts or updates depending on the existence of the given key, using callbacks to generate the new value.

      Parameters

      • newEntry: TEntry

        the new entry to insert if the key doesn't exist.

      • getUpdated: (existing: TEntry) => TEntry

        a callback to generate an updated entry if the key does exist. WARNING: mutation in this callback will cause merge to error.

      Returns [path: Path<TKey, TEntry>, wasUpdate: boolean]

      path to new entry and whether an update or insert attempted. If getUpdated callback returns a row that is already present, the resulting path will not be on.

    • Updates the entry at the given path to the given value. Deletes and inserts if the key changes.

      Parameters

      Returns [path: Path<TKey, TEntry>, wasUpdate: boolean]

      path to resulting entry and whether it was an update (as opposed to an insert). * on = true if update/insert succeeded. * wasUpdate = true if updated; false if inserted. * Returned path is on entry * on = false if the insert failed: newEntry's new key already present; returned path is "near" the existing entry (wasUpdate = false)

      PathNotOnEntryError if the given path is not positioned on an entry (on === false).

    • Inserts the entry if it doesn't exist, or updates it if it does. The entry is frozen to ensure immutability.

      Parameters

      Returns Path<TKey, TEntry>

      path to the new entry. on = true if existing; on = false if new.

    • Builds a tree in a single bottom-up pass from already-sorted, duplicate-free input. O(n) - versus the O(n log n) of repeated insert - and packs nodes near capacity rather than the roughly half-full nodes that natural splits leave behind. The result is indistinguishable from a tree built by inserting the same entries (same structural invariants, same query answers) and is returned fresh at version 0.

      The input must be strictly ascending by compare. It is validated - and, unless disabled, frozen - in one linear pass; the first out-of-order or duplicate pair throws UnsortedInputError and nothing is returned (the partially-built work is discarded). Note the shared pass means that on the throw path the entries before the offending pair have already been frozen in place; the discarded tree is unreachable but those caller-owned objects stay frozen. Pass { freeze: false } if that side-effect matters.

      Parameter order and defaults mirror the constructor (keyFromEntry, then compare, then options), so a trusted load can pass { freeze: false } to skip freezing.

      Type Parameters

      • TKey
      • TEntry

      Parameters

      • sorted: Iterable<TEntry>

        any iterable of entries, strictly ascending by compare (array, generator, Set, ...).

      • OptionalkeyFromEntry: (entry: TEntry) => TKey
      • Optionalcompare: (a: TKey, b: TKey) => number
      • Optionaloptions: BTreeOptions

      Returns BTree<TKey, TEntry>