UNPKG

@rimbu/sorted

Version:

Immutable SortedMap and SortedSet implementations for TypeScript

114 lines (91 loc) 2.79 kB
import { RSetBase } from '@rimbu/collection-types/set-custom'; import { Comp } from '@rimbu/common'; import type { SortedSet } from '@rimbu/sorted/set'; import { SortedSetBuilder, SortedSetEmpty, SortedSetInner, SortedSetLeaf, SortedSetNode, } from '@rimbu/sorted/set-custom'; export class SortedSetContext<UT> extends RSetBase.ContextBase<UT, SortedSet.Types> implements SortedSet.Context<UT> { readonly maxEntries: number; readonly minEntries: number; readonly _empty: SortedSet<any>; constructor( readonly blockSizeBits: number, readonly comp: Comp<UT> ) { super(); this.maxEntries = 1 << this.blockSizeBits; this.minEntries = this.maxEntries >>> 1; this._empty = Object.freeze(new SortedSetEmpty<any>(this)); } readonly typeTag = 'SortedSet'; isNonEmptyInstance(source: any): source is any { return source instanceof SortedSetNode; } isValidValue(value: any): value is UT { return this.comp.isComparable(value); } readonly builder = <T extends UT>(): SortedSetBuilder<T> => { return new SortedSetBuilder(this as unknown as SortedSetContext<T>); }; createBuilder<T extends UT>(source?: SortedSet<T>): SortedSetBuilder<T> { return new SortedSetBuilder(this as unknown as SortedSetContext<T>, source); } findIndex(value: UT, entries: readonly UT[]): number { let start = 0; let end = entries.length - 1; while (start <= end) { const mid = (start + end) >>> 1; const midEntry = entries[mid]; const comp = this.comp.compare(value, midEntry); if (comp < 0) end = mid - 1; else if (comp > 0) start = mid + 1; else return mid; } return -(start + 1); } leaf(entries: readonly UT[]): SortedSetLeaf<UT> { return new SortedSetLeaf(this as unknown as SortedSetContext<UT>, entries); } inner( entries: readonly UT[], children: readonly SortedSetNode<UT>[], size: number ): SortedSetInner<UT> { return new SortedSetInner( this as unknown as SortedSetContext<UT>, entries, children, size ); } isSortedSetEmpty(obj: any): obj is SortedSetEmpty { return obj instanceof SortedSetEmpty; } isSortedSetLeaf<T>(obj: any): obj is SortedSetLeaf<T> { return obj instanceof SortedSetLeaf; } isSortedSetInner<T>(obj: any): obj is SortedSetInner<T> { return obj instanceof SortedSetInner; } isSortedSetNode<T>(obj: any): obj is SortedSetNode<T> { return obj instanceof SortedSetNode; } } export function createSortedSetContext<UT>(options?: { comp?: Comp<UT>; blockSizeBits?: number; }): SortedSet.Context<UT> { return Object.freeze( new SortedSetContext<UT>( options?.blockSizeBits ?? 5, options?.comp ?? Comp.defaultComp() ) ); }