@rimbu/sorted
Version:
Immutable SortedMap and SortedSet implementations for TypeScript
108 lines (85 loc) • 2.64 kB
text/typescript
import { RMapBase } from '@rimbu/collection-types/map-custom';
import { Comp } from '@rimbu/common';
import type { SortedMap } from '@rimbu/sorted/map';
import {
SortedMapEmpty,
SortedMapNode,
SortedMapLeaf,
SortedMapInner,
SortedMapBuilder,
} from '@rimbu/sorted/map-custom';
export class SortedMapContext<UK>
extends RMapBase.ContextBase<UK, SortedMap.Types>
implements SortedMap.Context<UK>
{
readonly maxEntries: number;
readonly minEntries: number;
readonly _empty: SortedMap<any, any>;
constructor(
readonly blockSizeBits: number,
readonly comp: Comp<UK>
) {
super();
this.maxEntries = 1 << blockSizeBits;
this.minEntries = this.maxEntries >>> 1;
this._empty = Object.freeze(new SortedMapEmpty<any, any>(this));
}
readonly typeTag = 'SortedMap';
isNonEmptyInstance(source: any): source is any {
return source instanceof SortedMapNode;
}
readonly builder = <K extends UK, V>(): SortedMapBuilder<K, V> => {
return new SortedMapBuilder(this as any);
};
createBuilder<K extends UK, V>(
source?: SortedMap<K, V>
): SortedMapBuilder<K, V> {
return new SortedMapBuilder(this as any, source);
}
isValidKey(key: any): key is UK {
return this.comp.isComparable(key);
}
findIndex(key: UK, entries: readonly (readonly [UK, unknown])[]): 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(key, midEntry[0]);
if (comp < 0) end = mid - 1;
else if (comp > 0) start = mid + 1;
else return mid;
}
return -(start + 1);
}
leaf<V>(entries: readonly (readonly [UK, V])[]): SortedMapLeaf<UK, V> {
return new SortedMapLeaf<UK, V>(this, entries);
}
inner<V>(
entries: readonly (readonly [UK, V])[],
children: readonly SortedMapNode<UK, V>[],
size: number
): SortedMapInner<UK, V> {
return new SortedMapInner(this, entries, children, size);
}
isSortedMapEmpty(obj: any): obj is SortedMapEmpty {
return obj instanceof SortedMapEmpty;
}
isSortedMapLeaf<K, V>(obj: any): obj is SortedMapLeaf<K, V> {
return obj instanceof SortedMapLeaf;
}
isSortedMapInner<K, V>(obj: any): obj is SortedMapInner<K, V> {
return obj instanceof SortedMapInner;
}
}
export function createSortedMapContext<UK>(options?: {
comp?: Comp<UK>;
blockSizeBits?: number;
}): SortedMap.Context<UK> {
return Object.freeze(
new SortedMapContext<UK>(
options?.blockSizeBits ?? 5,
options?.comp ?? Comp.defaultComp()
)
);
}