@frostpillar/frostpillar-btree 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ import { type BTreeEntry, type BTreeStats, type EntryId, type RangeBounds } from '../InMemoryBTree.js';
2
+ import type { ConcurrentInMemoryBTreeConfig } from './types.js';
3
+ export declare class ConcurrentInMemoryBTree<TKey, TValue> {
4
+ private readonly store;
5
+ private readonly maxRetries;
6
+ private readonly maxSyncMutationsPerBatch;
7
+ private readonly duplicateKeys;
8
+ private readonly configFingerprint;
9
+ private readonly readMode;
10
+ private readonly tree;
11
+ private currentVersion;
12
+ private operationQueue;
13
+ private initSeen;
14
+ constructor(config: ConcurrentInMemoryBTreeConfig<TKey, TValue>);
15
+ sync(): Promise<void>;
16
+ private syncUnlocked;
17
+ private applyMutationLocal;
18
+ private runExclusive;
19
+ private readOp;
20
+ /**
21
+ * Appends a mutation to the shared store using optimistic concurrency and,
22
+ * on success, applies the same mutation locally in this method.
23
+ *
24
+ * The `evaluate` callback is called against the current (synced) local tree to
25
+ * decide whether and what mutation to append. If the store append fails due to a
26
+ * concurrent write, the tree is re-synced and `evaluate` is invoked again.
27
+ *
28
+ * The callback MUST be a pure function: it must not produce side effects and must
29
+ * return the same logical result for equivalent tree states, because it may be
30
+ * called multiple times across retries.
31
+ *
32
+ */
33
+ private appendMutationAndApplyUnlocked;
34
+ put(key: TKey, value: TValue): Promise<EntryId>;
35
+ remove(key: TKey): Promise<BTreeEntry<TKey, TValue> | null>;
36
+ removeById(entryId: EntryId): Promise<BTreeEntry<TKey, TValue> | null>;
37
+ updateById(entryId: EntryId, value: TValue): Promise<BTreeEntry<TKey, TValue> | null>;
38
+ popFirst(): Promise<BTreeEntry<TKey, TValue> | null>;
39
+ get(key: TKey): Promise<TValue | null>;
40
+ hasKey(key: TKey): Promise<boolean>;
41
+ findFirst(key: TKey): Promise<BTreeEntry<TKey, TValue> | null>;
42
+ findLast(key: TKey): Promise<BTreeEntry<TKey, TValue> | null>;
43
+ range(startKey: TKey, endKey: TKey, options?: RangeBounds): Promise<BTreeEntry<TKey, TValue>[]>;
44
+ snapshot(): Promise<BTreeEntry<TKey, TValue>[]>;
45
+ size(): Promise<number>;
46
+ assertInvariants(): Promise<void>;
47
+ getStats(): Promise<BTreeStats>;
48
+ peekFirst(): Promise<BTreeEntry<TKey, TValue> | null>;
49
+ peekLast(): Promise<BTreeEntry<TKey, TValue> | null>;
50
+ popLast(): Promise<BTreeEntry<TKey, TValue> | null>;
51
+ peekById(entryId: EntryId): Promise<BTreeEntry<TKey, TValue> | null>;
52
+ count(startKey: TKey, endKey: TKey, options?: RangeBounds): Promise<number>;
53
+ nextHigherKey(key: TKey): Promise<TKey | null>;
54
+ nextLowerKey(key: TKey): Promise<TKey | null>;
55
+ getPairOrNextLower(key: TKey): Promise<BTreeEntry<TKey, TValue> | null>;
56
+ }
@@ -0,0 +1,27 @@
1
+ import type { BTreeMutation, ConcurrentInMemoryBTreeConfig, ReadMode } from './types.js';
2
+ import type { BTreeEntry, EntryId } from '../InMemoryBTree.js';
3
+ export declare const computeConfigFingerprint: <TKey>(config: ConcurrentInMemoryBTreeConfig<TKey, unknown>) => string;
4
+ export type MutationResult<TKey, TValue, TMutation extends BTreeMutation<TKey, TValue>> = TMutation extends {
5
+ type: 'init';
6
+ } ? null : TMutation extends {
7
+ type: 'put';
8
+ } ? EntryId : TMutation extends {
9
+ type: 'remove';
10
+ } ? BTreeEntry<TKey, TValue> | null : TMutation extends {
11
+ type: 'removeById';
12
+ } ? BTreeEntry<TKey, TValue> | null : TMutation extends {
13
+ type: 'updateById';
14
+ } ? BTreeEntry<TKey, TValue> | null : TMutation extends {
15
+ type: 'popFirst';
16
+ } ? BTreeEntry<TKey, TValue> | null : TMutation extends {
17
+ type: 'popLast';
18
+ } ? BTreeEntry<TKey, TValue> | null : never;
19
+ export type AnyMutationResult<TKey, TValue> = EntryId | BTreeEntry<TKey, TValue> | null;
20
+ export declare const assertNeverMutation: (mutation: never) => never;
21
+ export declare const normalizeMaxRetries: (value: number | undefined) => number;
22
+ export declare const normalizeMaxSyncMutationsPerBatch: (value: number | undefined) => number;
23
+ export declare const normalizeReadMode: (value: ReadMode | undefined) => ReadMode;
24
+ export declare function assertAppendVersionContract(expectedVersion: bigint, appendResult: unknown): asserts appendResult is {
25
+ applied: boolean;
26
+ version: bigint;
27
+ };
@@ -0,0 +1,2 @@
1
+ export { ConcurrentInMemoryBTree } from './ConcurrentInMemoryBTree.js';
2
+ export type { BTreeMutation, ConcurrentInMemoryBTreeConfig, ReadMode, SharedTreeLog, SharedTreeStore, } from './types.js';
@@ -0,0 +1,41 @@
1
+ import type { EntryId, InMemoryBTreeConfig } from '../InMemoryBTree.js';
2
+ export type BTreeMutation<TKey, TValue> = {
3
+ type: 'init';
4
+ configFingerprint: string;
5
+ } | {
6
+ type: 'put';
7
+ key: TKey;
8
+ value: TValue;
9
+ } | {
10
+ type: 'remove';
11
+ key: TKey;
12
+ } | {
13
+ type: 'removeById';
14
+ entryId: EntryId;
15
+ } | {
16
+ type: 'updateById';
17
+ entryId: EntryId;
18
+ value: TValue;
19
+ } | {
20
+ type: 'popFirst';
21
+ } | {
22
+ type: 'popLast';
23
+ };
24
+ export interface SharedTreeLog<TKey, TValue> {
25
+ version: bigint;
26
+ mutations: BTreeMutation<TKey, TValue>[];
27
+ }
28
+ export interface SharedTreeStore<TKey, TValue> {
29
+ getLogEntriesSince(version: bigint): Promise<SharedTreeLog<TKey, TValue>>;
30
+ append(expectedVersion: bigint, mutations: BTreeMutation<TKey, TValue>[]): Promise<{
31
+ applied: boolean;
32
+ version: bigint;
33
+ }>;
34
+ }
35
+ export type ReadMode = 'strong' | 'local';
36
+ export interface ConcurrentInMemoryBTreeConfig<TKey, TValue> extends InMemoryBTreeConfig<TKey> {
37
+ store: SharedTreeStore<TKey, TValue>;
38
+ maxRetries?: number;
39
+ maxSyncMutationsPerBatch?: number;
40
+ readMode?: ReadMode;
41
+ }