UNPKG

@perma/map

Version:

Immutable hash maps implemented as hash array papped tries

98 lines 4.75 kB
import type { BitField, Uint32 } from "./bitfield/api.js"; import type { Path } from "./path/api.js"; export interface Config<Bits = unknown, BitMap = Bits> { /** * Number of bits of the hash to use for child index calculation at each level * of the tree such that the root node takes the first `bitWidth` bits of the * hash to calculate an index and as we move lower in the tree, we move along * the hash by `depth x bitWidth` bits. This also determines branching factor * of the tree beacuse each node will contain index for `2 ** bitWidth` * children. * * When omitted `bitWidth` of `5` is used which results in trees with branching * factor of 32, allowing us to use various space and computation optimizations * while still fitting large amounts of entries in relatively shallow tree ( * around `33,554,432` entries in a tree that is just 6 levels deep) */ bitWidth: Uint32; /** * Configuration used by the HAMT to calculate tree path from the key. It used * for building an index and traversal. It can be configured so that e.g 32 * branching factor is used in which case it will be highly optimized. */ Path: Path<Bits>; /** * Configuration used by the HAMT to represent child index (datamap & nodemap), * which is configurable allowing us to highly optimizing 32 barnch factor by * representing them as a single 32 bit integer as opposed to `Uint8Array`. */ BitField: BitField<BitMap>; } export interface HAMT<T = unknown, K extends string = string, C extends Config = Config> { readonly root: BitmapIndexedNode<T, K, C>; readonly config: C; } export interface PersistentHashMap<T = unknown, K extends string = string, C extends Config = Config> extends HAMT<T, K, C> { readonly size: number; entries(): IterableIterator<[K, T]>; keys(): IterableIterator<K>; values(): IterableIterator<T>; [Symbol.iterator](): IterableIterator<[K, T]>; clone(): PersistentHashMap<T, K, C>; empty(): PersistentHashMap<T, K, C>; has(key: K): boolean; get(key: K): T | undefined; set<R extends string>(key: R, value: T): PersistentHashMap<T, K | R, C>; delete(key: K): PersistentHashMap<T, K, C>; createBuilder(): HashMapBuilder<T, K, C>; } export interface HashMapBuilder<T = unknown, K extends string = string, C extends Config = Config> extends HAMT<T, K, C> { readonly size: number; set<R extends string>(key: R, value: T): HashMapBuilder<T, K | R, C>; delete(key: K): HashMapBuilder<T, K, C>; build(): PersistentHashMap<T, K, C>; } export interface Node<T = unknown, K extends string = string, C extends Config = Config> { edit: Edit | null; children: Children<T, K, C>; config: C; lookup<X>(shift: Uint32, path: ReturnType<C["Path"]["from"]>, key: K, notFound: X): T | X; associate<R extends string>(edit: Edit | null, depth: Uint32, path: ReturnType<C["Path"]["from"]>, key: K | R, value: T, leafAdded: { value: boolean; }): Node<T, K | R, C>; dissociate(edit: Edit | null, depth: Uint32, path: ReturnType<C["Path"]["from"]>, key: K, removedLeaf: { value: boolean; }): Node<T, K, C>; entries(): IterableIterator<[K, T]>; keys(): IterableIterator<K>; values(): IterableIterator<T>; fork(edit?: Edit | null): Node<T, K, C>; nodeArity: number; dataArity: number; } export interface BitmapIndexedNode<T = unknown, K extends string = string, C extends Config = Config> extends Node<T, K, C> { datamap: ReturnType<C["BitField"]["empty"]>; nodemap: ReturnType<C["BitField"]["empty"]>; associate<R extends string>(edit: Edit | null, depth: Uint32, path: ReturnType<C["Path"]["from"]>, key: K | R, value: T, leafAdded: { value: boolean; }): BitmapIndexedNode<T, K | R, C>; dissociate(edit: Edit | null, depth: Uint32, path: ReturnType<C["Path"]["from"]>, key: K, removedLeaf: { value: boolean; }): BitmapIndexedNode<T, K, C>; fork(edit?: Edit | null): BitmapIndexedNode<T, K, C>; } export interface HashCollisionNode<T extends unknown = unknown, K extends string = string, C extends Config = Config> extends Node<T, K, C> { config: C; count: number; children: CollisionEntries<T, K>; nodeArity: 0; fork(edit?: Edit | null): HashCollisionNode<T, K, C>; } export declare type CollisionEntries<T, K> = [K, T] | [K, T, K, T] | [K, T, K, T, K, T, ...Array<K | T>]; export interface Children<T = unknown, K extends string = string, C extends Config = Config> extends Array<K | T | Node<T, K, C>> { } export declare type usize = number; export interface Edit { } export type { BitField, Uint32, Path }; //# sourceMappingURL=api.d.ts.map