UNPKG

@rimbu/sorted

Version:

Immutable SortedMap and SortedSet implementations for TypeScript

403 lines (402 loc) 19 kB
import { EmptyBase, NonEmptyBase } from '@rimbu/collection-types/map-custom'; import { IndexRange, OptLazy, TraverseState } from '@rimbu/common'; import { Stream } from '@rimbu/stream'; /** * Base implementation used for empty sorted collections.<br/> * <br/> * Provides the index‑based operations used by `SortedMap` / `SortedSet` * instances when they are empty and always returns the given fallback value. */ export declare class SortedEmpty extends EmptyBase { min<O>(otherwise?: OptLazy<O>): O; max<O>(otherwise?: OptLazy<O>): O; getAtIndex<O>(index: number, otherwise?: OptLazy<O>): O; take(): any; drop(): any; sliceIndex(): any; } /** * Abstract base class for non‑empty sorted collections.<br/> * <br/> * It exposes the common index‑based operations and structural mutation * helpers shared by the sorted map and set node implementations. * @typeparam E - the stored entry type * @typeparam TS - the concrete non‑empty node type */ export declare abstract class SortedNonEmptyBase<E, TS extends SortedNonEmptyBase<E, TS>> extends NonEmptyBase<E> { abstract getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O; abstract get entries(): readonly E[]; abstract takeInternal(amount: number): TS; abstract dropInternal(amount: number): TS; abstract mutateSplitRight(index?: number): [E, TS]; abstract mutateGiveToLeft(left: TS, toLeft: E): [E, TS]; abstract mutateGiveToRight(right: TS, toRight: E): [E, TS]; abstract mutateGetFromLeft(left: TS, toMe: E): [E, TS]; abstract mutateGetFromRight(right: TS, toMe: E): [E, TS]; abstract mutateJoinLeft(left: TS, entry: E): void; abstract mutateJoinRight(right: TS, entry: E): void; abstract deleteMin(): [E, TS]; abstract deleteMax(): [E, TS]; get mutateEntries(): E[]; } /** * Describes the mutable surface of a leaf node used by the helper * functions that transform B‑tree leaves. * @typeparam TS - the concrete leaf type * @typeparam E - the stored entry type */ export interface LeafMutateSource<TS extends LeafMutateSource<TS, E>, E> { mutateEntries: E[]; entries: readonly E[]; copy(entries: readonly E[]): TS; } /** * Removes and returns the minimum entry from the given leaf node while * returning the updated leaf. * @param source - the leaf node to operate on */ export declare function leafDeleteMin<S extends LeafMutateSource<S, E>, E>(source: S): [E, S]; /** * Removes and returns the maximum entry from the given leaf node while * returning the updated leaf. * @param source - the leaf node to operate on */ export declare function leafDeleteMax<S extends LeafMutateSource<S, E>, E>(source: S): [E, S]; /** * Splits the given leaf node into two nodes and returns the promoted * separator entry together with the newly created right node.<br/> * <br/> * The split position can be customised through the optional `index`. * @param source - the leaf node to split * @param index - (optional) the split index, defaults to the middle entry */ export declare function leafMutateSplitRight<S extends LeafMutateSource<S, E>, E>(source: S, index?: number): [E, S]; /** * Moves the given `toLeft` entry from `source` to the left sibling and * returns the separator entry that should be stored in the parent node. * @param source - the leaf that donates an entry to the left sibling * @param left - the left sibling leaf to receive the entry * @param toLeft - the entry that must end up in the left sibling */ export declare function leafMutateGiveToLeft<S extends LeafMutateSource<S, E>, E>(source: S, left: S, toLeft: E): [E, S]; /** * Moves the given `toRight` entry from `source` to the right sibling and * returns the separator entry that should be stored in the parent node. * @param source - the leaf that donates an entry to the right sibling * @param right - the right sibling leaf to receive the entry * @param toRight - the entry that must end up in the right sibling */ export declare function leafMutateGiveToRight<S extends LeafMutateSource<S, E>, E>(source: S, right: S, toRight: E): [E, S]; /** * Pulls an entry from the left sibling into `source` and returns the * separator entry that should be stored in the parent node. * @param source - the leaf receiving an entry * @param left - the left sibling leaf to donate an entry * @param toMe - the entry that must end up in `source` */ export declare function leafMutateGetFromLeft<S extends LeafMutateSource<S, E>, E>(source: S, left: S, toMe: E): [E, S]; /** * Pulls an entry from the right sibling into `source` and returns the * separator entry that should be stored in the parent node. * @param source - the leaf receiving an entry * @param right - the right sibling leaf to donate an entry * @param toMe - the entry that must end up in `source` */ export declare function leafMutateGetFromRight<S extends LeafMutateSource<S, E>, E>(source: S, right: S, toMe: E): [E, S]; /** * Joins the given left sibling leaf and `source` into a single leaf by * inserting the given separator `entry` between them. * @param source - the right leaf that will absorb the left sibling * @param left - the left sibling leaf to merge * @param entry - the separator entry from the parent */ export declare function leafMutateJoinLeft<S extends LeafMutateSource<S, E>, E>(source: S, left: S, entry: E): void; /** * Joins the given right sibling leaf and `source` into a single leaf by * inserting the given separator `entry` between them. * @param source - the left leaf that will absorb the right sibling * @param right - the right sibling leaf to merge * @param entry - the separator entry from the parent */ export declare function leafMutateJoinRight<S extends LeafMutateSource<S, E>, E>(source: S, right: S, entry: E): void; /** * Describes the minimal interface required from an inner B‑tree node * used by the helper functions that transform inner nodes. * @typeparam E - the stored entry type */ export interface InnerChild<E> { readonly size: number; getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O; stream(options?: { reversed?: boolean; }): Stream<E>; streamSliceIndex(range: IndexRange, options?: { reversed?: boolean; }): Stream<E>; readonly entries: readonly E[]; takeInternal(amount: number): InnerChild<E>; dropInternal(amount: number): InnerChild<E>; deleteMin(): [E, InnerChild<E>]; deleteMax(): [E, InnerChild<E>]; mutateGiveToLeft(left: InnerChild<E>, toLeft: E): [E, InnerChild<E>]; mutateGiveToRight(right: InnerChild<E>, toRight: E): [E, InnerChild<E>]; mutateSplitRight(index?: number): [E, InnerChild<E>]; mutateJoinLeft(left: InnerChild<E>, entry: E): void; mutateJoinRight(right: InnerChild<E>, entry: E): void; mutateGetFromLeft(left: InnerChild<E>, toMe: E): [E, InnerChild<E>]; mutateGetFromRight(right: InnerChild<E>, toMe: E): [E, InnerChild<E>]; } /** * Describes the mutable surface of an inner node used by the inner * transformation helper functions. * @typeparam TS - the concrete inner node type * @typeparam E - the stored entry type */ export interface InnerMutateSource<TS extends InnerMutateSource<TS, E>, E> { readonly context: { readonly minEntries: number; readonly maxEntries: number; inner(entries: readonly E[], children: readonly InnerChild<E>[], size: number): TS; }; size: number; entries: readonly E[]; mutateEntries: E[]; children: readonly InnerChild<E>[]; mutateChildren: InnerChild<E>[]; stream(options?: { reversed?: boolean; }): Stream.NonEmpty<E>; copy(entries?: readonly E[], children?: readonly InnerChild<E>[], size?: number): TS; addInternal(entry: E): TS; normalizeDownsizeChild(childIndex: number, newChild: InnerChild<E>, newSize: number): TS; normalizeIncreaseChild(childIndex: number, newChild: InnerChild<E>, newSize: number): TS; } /** * Removes and returns the minimum entry from the left‑most child of the * given inner node and returns the updated node. * @param source - the inner node to operate on */ export declare function innerDeleteMin<S extends InnerMutateSource<S, E>, E>(source: S): [E, S]; /** * Removes and returns the maximum entry from the right‑most child of the * given inner node and returns the updated node. * @param source - the inner node to operate on */ export declare function innerDeleteMax<S extends InnerMutateSource<S, E>, E>(source: S): [E, S]; /** * Splits the given inner node into two nodes and returns the promoted * separator entry together with the new right node.<br/> * <br/> * The split position can be customised through the optional `index`. * @param source - the inner node to split * @param index - (optional) the split index, defaults to the middle entry */ export declare function innerMutateSplitRight<S extends InnerMutateSource<S, E>, E>(source: S, index?: number): [E, S]; /** * Moves the given `toLeft` entry and its child from `source` to the left * sibling and returns the separator entry that should be stored in the * parent node. * @param source - the inner node donating an entry to the left sibling * @param left - the left sibling node to receive the entry and child * @param toLeft - the entry that must end up in the left sibling */ export declare function innerMutateGiveToLeft<S extends InnerMutateSource<S, E>, E>(source: S, left: S, toLeft: E): [E, S]; /** * Moves the given `toRight` entry and its child from `source` to the right * sibling and returns the separator entry that should be stored in the * parent node. * @param source - the inner node donating an entry to the right sibling * @param right - the right sibling node to receive the entry and child * @param toRight - the entry that must end up in the right sibling */ export declare function innerMutateGiveToRight<S extends InnerMutateSource<S, E>, E>(source: S, right: S, toRight: E): [E, S]; /** * Pulls an entry and child from the left sibling into `source` and returns * the separator entry that should be stored in the parent node. * @param source - the inner node receiving the entry and child * @param left - the left sibling node to donate the entry and child * @param toMe - the entry that must end up in `source` */ export declare function innerMutateGetFromLeft<S extends InnerMutateSource<S, E>, E>(source: S, left: S, toMe: E): [E, S]; /** * Pulls an entry and child from the right sibling into `source` and returns * the separator entry that should be stored in the parent node. * @param source - the inner node receiving the entry and child * @param right - the right sibling node to donate the entry and child * @param toMe - the entry that must end up in `source` */ export declare function innerMutateGetFromRight<S extends InnerMutateSource<S, E>, E>(source: S, right: S, toMe: E): [E, S]; /** * Joins the given left sibling inner node and `source` into a single node by * inserting the given separator `entry` between them. * @param source - the right inner node that will absorb the left sibling * @param left - the left sibling node to merge * @param entry - the separator entry from the parent */ export declare function innerMutateJoinLeft<S extends InnerMutateSource<S, E>, E>(source: S, left: S, entry: E): void; /** * Joins the given right sibling inner node and `source` into a single node by * inserting the given separator `entry` between them. * @param source - the left inner node that will absorb the right sibling * @param right - the right sibling node to merge * @param entry - the separator entry from the parent */ export declare function innerMutateJoinRight<S extends InnerMutateSource<S, E>, E>(source: S, right: S, entry: E): void; /** * Normalises the given child after it has decreased in size so that it * satisfies the minimum entry constraint of the B‑tree.<br/> * <br/> * Depending on the neighbouring children this may rotate entries between * nodes or perform a split. * @param source - the inner node that contains the child * @param childIndex - the index of the child within `source` * @param newChild - the updated child node * @param newSize - the new total size for `source` */ export declare function innerNormalizeDownsizeChild<S extends InnerMutateSource<S, E>, E>(source: S, childIndex: number, newChild: InnerChild<E>, newSize: number): S; /** * Normalises the given child after it has increased in size so that it * satisfies the maximum entry constraint of the B‑tree.<br/> * <br/> * Depending on the neighbouring children this may rotate entries between * nodes or merge nodes together. * @param source - the inner node that contains the child * @param childIndex - the index of the child within `source` * @param newChild - the updated child node * @param newSize - the new total size for `source` */ export declare function innerNormalizeIncreaseChild<S extends InnerMutateSource<S, E>, E>(source: S, childIndex: number, newChild: InnerChild<E>, newSize: number): S; /** * Returns the index of the element in the sources element array, or a tuple with the child index and the index within the child * @param source the collection to operate on * @param index the index to find */ export declare function innerGetSubIndex(source: InnerMutateSource<any, any>, index: number): number | [number, number]; /** * Returns the entry at the given `index` from the B‑tree represented by the * given inner node, or the provided fallback value if the index is out of * bounds.<br/> * <br/> * Negative indices are interpreted from the end of the collection. * @param source - the inner node to read from * @param index - the (possibly negative) index to look up * @param otherwise - (default: undefined) fallback value when out of bounds */ export declare function innerGetAtIndex<E, O>(source: InnerMutateSource<any, E>, index: number, otherwise?: OptLazy<O>): E | O; /** * Returns a new inner node containing only the first `amount` of entries * and children of the given `source` node.<br/> * <br/> * The amount must be between `1` and `source.size - 1`. * @param source - the inner node to operate on * @param amount - the amount of entries to keep */ export declare function innerTakeInternal<S extends InnerMutateSource<S, E>, E>(source: S, amount: number): S; /** * Returns a new inner node containing all entries and children of the given * `source` node except for the first `amount` entries.<br/> * <br/> * The amount must be between `1` and `source.size - 1`. * @param source - the inner node to operate on * @param amount - the amount of entries to drop */ export declare function innerDropInternal<S extends InnerMutateSource<S, E>, E>(source: S, amount: number): S; /** * Returns a `Stream` of entries of the given inner node limited to the * provided index `range`.<br/> * <br/> * When `reversed` is true, the stream iterates the selected range in * reverse order. * @param source - the inner node to stream from * @param range - the index range to include * @param reversed - (default: false) when true reverses the stream order */ export declare function innerStreamSliceIndex<E>(source: InnerMutateSource<any, E>, range: IndexRange, reversed?: boolean): Stream<E>; /** * Abstract base class for mutable sorted builders used by the sorted map * and set implementations.<br/> * <br/> * It encapsulates the shared tree‑based logic for computing `min`, `max`, * index‑based access and traversal while allowing concrete builders to plug * in their own entry and child representations. * @typeparam E - the entry type stored in the builder */ export declare abstract class SortedBuilder<E> { abstract get context(): { minEntries: number; maxEntries: number; }; abstract source?: undefined | { min<O>(otherwise?: OptLazy<O>): E | O; max<O>(otherwise?: OptLazy<O>): E | O; getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O; forEach(f: (entry: E, index: number, halt: () => void) => void, options?: { state?: TraverseState; }): void; }; abstract _entries?: undefined | E[]; abstract _children?: undefined | SortedBuilder<E>[]; abstract get children(): SortedBuilder<E>[]; abstract set children(value: SortedBuilder<E>[]); abstract size: number; abstract prepareMutate(): void; abstract createNew(source?: undefined | unknown, entries?: undefined | E[], children?: undefined | SortedBuilder<E>[], size?: undefined | number): SortedBuilder<E>; _lock: number; /** * Throws an error when the builder is mutated while it is being iterated, * for example from within {@link SortedBuilder.forEach}. */ checkLock(): void; get entries(): E[]; set entries(value: E[]); get hasChildren(): boolean; get isEmpty(): boolean; /** * Returns the minimum entry of the builder, or the given fallback value * if the builder is empty. * @param otherwise - (default: undefined) fallback value when empty */ min<O>(otherwise?: OptLazy<O>): E | O; /** * Returns the maximum entry of the builder, or the given fallback value * if the builder is empty. * @param otherwise - (default: undefined) fallback value when empty */ max<O>(otherwise?: OptLazy<O>): E | O; /** * Returns the entry at the given `index`, or the provided fallback value * when the index is out of bounds.<br/> * <br/> * Negative indices are interpreted from the end of the builder. * @param index - the (possibly negative) index to look up * @param otherwise - (default: undefined) fallback value when out of bounds */ getAtIndex<O>(index: number, otherwise?: OptLazy<O>): E | O; /** * Calls the given function `f` for every entry in the builder in key * sort‑order, passing in the entry, its zero‑based index and a `halt` * function that can be used to stop iteration early. * @param f - the callback function to invoke for each entry * @param options - (optional) traversal options including a custom state */ forEach(f: (entry: E, index: number, halt: () => void) => void, options?: { state?: TraverseState; }): void; /** * Restores the builder invariants after mutations by splitting the root * node when it grows beyond the configured maximum block size. */ normalize(): void; normalizeChildIncrease(childIndex: number): void; normalizeChildDecrease(childIndex: number): void; /** * Removes and returns the minimum entry from the builder while keeping * the internal B‑tree structure valid. */ deleteMin(): E; /** * Removes and returns the maximum entry from the builder while keeping * the internal B‑tree structure valid. */ deleteMax(): E; }