@frostpillar/frostpillar-btree 0.2.5 → 0.2.7

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,15 @@
1
+ import type { BranchNode, BTreeNode, LeafEntry, LeafNode, NodeKey } from './types.js';
2
+ export declare const createLeafNode: <TKey, TValue>(entries: LeafEntry<TKey, TValue>[], parent: BranchNode<TKey, TValue> | null) => LeafNode<TKey, TValue>;
3
+ export declare const createBranchNode: <TKey, TValue>(children: BTreeNode<TKey, TValue>[], parent: BranchNode<TKey, TValue> | null) => BranchNode<TKey, TValue>;
4
+ export declare const leafEntryCount: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => number;
5
+ export declare const leafEntryAt: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, i: number) => LeafEntry<TKey, TValue>;
6
+ export declare const leafShiftEntry: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => LeafEntry<TKey, TValue> | undefined;
7
+ export declare const leafPopEntry: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => LeafEntry<TKey, TValue> | undefined;
8
+ export declare const leafUnshiftEntry: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, entry: LeafEntry<TKey, TValue>) => void;
9
+ export declare const leafRemoveAt: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, logicalIndex: number) => void;
10
+ export declare const leafInsertAt: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, logicalIndex: number, entry: LeafEntry<TKey, TValue>) => void;
11
+ export declare const leafCompact: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => void;
12
+ export declare const branchCompact: <TKey, TValue>(branch: BranchNode<TKey, TValue>) => void;
13
+ export declare const branchChildCount: <TKey, TValue>(branch: BranchNode<TKey, TValue>) => number;
14
+ export declare const branchInsertAt: <TKey, TValue>(branch: BranchNode<TKey, TValue>, logicalIndex: number, child: BTreeNode<TKey, TValue>, key: NodeKey<TKey>) => void;
15
+ export declare const branchRemoveAt: <TKey, TValue>(branch: BranchNode<TKey, TValue>, physIndex: number) => void;
@@ -1,3 +1,7 @@
1
1
  import { type BTreeEntry, type BTreeState, type RangeBounds } from './types.js';
2
+ export declare function isEmptyRange<TKey>(compare: (a: TKey, b: TKey) => number, startKey: TKey, endKey: TKey, options?: RangeBounds): boolean;
2
3
  export declare const countRangeEntries: <TKey, TValue>(state: BTreeState<TKey, TValue>, startKey: TKey, endKey: TKey, options?: RangeBounds) => number;
3
- export declare const rangeQueryEntries: <TKey, TValue>(state: BTreeState<TKey, TValue>, startKey: TKey, endKey: TKey, options?: RangeBounds) => BTreeEntry<TKey, TValue>[];
4
+ /** Single-pass range query that produces public entries (via freezeEntry) inline. */
5
+ export declare const rangeQueryPublicEntries: <TKey, TValue>(state: BTreeState<TKey, TValue>, startKey: TKey, endKey: TKey, options?: RangeBounds) => BTreeEntry<TKey, TValue>[];
6
+ /** Streaming range iteration — invokes callback for each entry without array allocation. */
7
+ export declare const forEachRangeEntries: <TKey, TValue>(state: BTreeState<TKey, TValue>, startKey: TKey, endKey: TKey, callback: (entry: BTreeEntry<TKey, TValue>) => void, options?: RangeBounds) => void;
@@ -0,0 +1,4 @@
1
+ import { type BTreeNode, type BTreeState, type BranchNode } from './types.js';
2
+ export declare const updateMinKeyInAncestors: <TKey, TValue>(node: BTreeNode<TKey, TValue>) => void;
3
+ export declare const removeChildFromBranch: <TKey, TValue>(branch: BranchNode<TKey, TValue>, childIndex: number) => void;
4
+ export declare const rebalanceAfterBranchRemoval: <TKey, TValue>(state: BTreeState<TKey, TValue>, branch: BranchNode<TKey, TValue>) => void;
@@ -1,4 +1,7 @@
1
- import { type BTreeNode, type BTreeState, type LeafNode } from './types.js';
2
- declare const updateMinKeyInAncestors: <TKey, TValue>(node: BTreeNode<TKey, TValue>) => void;
1
+ import { type BTreeState, type LeafNode } from './types.js';
2
+ import { updateMinKeyInAncestors } from './rebalance-branch.js';
3
3
  export { updateMinKeyInAncestors };
4
+ /** Applies the lazy divisor to a minimum-occupancy value. */
5
+ export declare const applyLazyThreshold: (min: number) => number;
6
+ export declare const leafRebalanceThreshold: <TKey, TValue>(state: BTreeState<TKey, TValue>) => number;
4
7
  export declare const rebalanceAfterLeafRemoval: <TKey, TValue>(state: BTreeState<TKey, TValue>, leaf: LeafNode<TKey, TValue>) => void;
@@ -1,4 +1,4 @@
1
- import { type BTreeState, type DuplicateKeyPolicy, type InMemoryBTreeConfig, type KeyComparator } from './types.js';
1
+ import { type BTreeState, type DeleteRebalancePolicy, type DuplicateKeyPolicy, type InMemoryBTreeConfig, type KeyComparator } from './types.js';
2
2
  export interface BTreeJSON<TKey, TValue> {
3
3
  version: number;
4
4
  config: {
@@ -7,10 +7,12 @@ export interface BTreeJSON<TKey, TValue> {
7
7
  duplicateKeys: DuplicateKeyPolicy;
8
8
  enableEntryIdLookup: boolean;
9
9
  autoScale: boolean;
10
+ deleteRebalancePolicy?: DeleteRebalancePolicy;
10
11
  };
11
12
  entries: [TKey, TValue][];
12
13
  }
13
14
  export declare const buildConfigFromState: <TKey, TValue>(state: BTreeState<TKey, TValue>) => InMemoryBTreeConfig<TKey>;
14
15
  export declare const serializeToJSON: <TKey, TValue>(state: BTreeState<TKey, TValue>) => BTreeJSON<TKey, TValue>;
15
16
  export declare const validateBTreeJSON: <TKey, TValue>(json: BTreeJSON<TKey, TValue>) => void;
17
+ export declare const validateBTreeJSONSortOrder: <TKey, TValue>(json: BTreeJSON<TKey, TValue>, compareKeys: KeyComparator<TKey>) => void;
16
18
  export declare const buildConfigFromJSON: <TKey>(json: BTreeJSON<TKey, unknown>, compareKeys: KeyComparator<TKey>) => InMemoryBTreeConfig<TKey>;
@@ -0,0 +1,3 @@
1
+ import { type BTreeState, type BranchNode, type LeafNode } from './types.js';
2
+ export declare const splitLeaf: <TKey, TValue>(state: BTreeState<TKey, TValue>, leaf: LeafNode<TKey, TValue>) => void;
3
+ export declare const splitBranch: <TKey, TValue>(state: BTreeState<TKey, TValue>, branch: BranchNode<TKey, TValue>) => void;
@@ -0,0 +1,7 @@
1
+ import { type BTreeEntry, type BTreeState } from './types.js';
2
+ /** Collect all entries into a pre-allocated array, frozen for safe external use. */
3
+ export declare const snapshotEntries: <TKey, TValue>(state: BTreeState<TKey, TValue>) => BTreeEntry<TKey, TValue>[];
4
+ /** Collect all internal entries (no freeze) for internal use (clone, serialize). */
5
+ export declare const collectInternalEntries: <TKey, TValue>(state: BTreeState<TKey, TValue>) => BTreeEntry<TKey, TValue>[];
6
+ /** Iterate all entries, invoking callback with frozen entries. */
7
+ export declare const forEachEntry: <TKey, TValue>(state: BTreeState<TKey, TValue>, callback: (entry: BTreeEntry<TKey, TValue>) => void, thisArg?: unknown) => void;
@@ -6,11 +6,19 @@ export declare const NODE_LEAF: 0;
6
6
  export declare const NODE_BRANCH: 1;
7
7
  export type KeyComparator<TKey> = (left: TKey, right: TKey) => number;
8
8
  export type DuplicateKeyPolicy = 'allow' | 'reject' | 'replace';
9
+ export type DeleteRebalancePolicy = 'standard' | 'lazy';
10
+ /**
11
+ * Defines the inclusivity of the lower and upper bounds for a key range scan.
12
+ * Both bounds default to `'inclusive'` when omitted.
13
+ */
9
14
  export interface RangeBounds {
15
+ /** Lower bound type. Defaults to `'inclusive'` when omitted. */
10
16
  lowerBound?: 'inclusive' | 'exclusive';
17
+ /** Upper bound type. Defaults to `'inclusive'` when omitted. */
11
18
  upperBound?: 'inclusive' | 'exclusive';
12
19
  }
13
20
  export declare const normalizeDuplicateKeyPolicy: (value: DuplicateKeyPolicy | undefined) => DuplicateKeyPolicy;
21
+ export declare const normalizeDeleteRebalancePolicy: (value: DeleteRebalancePolicy | undefined) => DeleteRebalancePolicy;
14
22
  export type EntryId = number & {
15
23
  readonly __brand: 'EntryId';
16
24
  };
@@ -29,6 +37,18 @@ export interface LeafEntry<TKey, TValue> {
29
37
  key: TKey;
30
38
  value: TValue;
31
39
  }
40
+ /**
41
+ * Freezes and returns an internal entry for safe exposure via the public API.
42
+ * Idempotent: re-freezing an already-frozen object is a no-op in V8.
43
+ * All entries are frozen at creation via createEntry, so this is a zero-allocation cast.
44
+ */
45
+ export declare const freezeEntry: <TKey, TValue>(entry: LeafEntry<TKey, TValue>) => BTreeEntry<TKey, TValue>;
46
+ /**
47
+ * Creates a frozen LeafEntry with a canonical property order.
48
+ * All entry creation MUST go through this function to guarantee a single
49
+ * V8 hidden class across all entries in the tree.
50
+ */
51
+ export declare const createEntry: <TKey, TValue>(key: TKey, entryId: EntryId, value: TValue) => LeafEntry<TKey, TValue>;
32
52
  export interface LeafNode<TKey, TValue> {
33
53
  kind: typeof NODE_LEAF;
34
54
  entries: LeafEntry<TKey, TValue>[];
@@ -61,6 +81,7 @@ export interface BTreeState<TKey, TValue> {
61
81
  minBranchChildren: number;
62
82
  entryKeys: Map<EntryId, TKey> | null;
63
83
  autoScale: boolean;
84
+ deleteRebalancePolicy: DeleteRebalancePolicy;
64
85
  _nextAutoScaleThreshold: number;
65
86
  /** @internal Shared return object for navigation functions — never store a reference across calls. */
66
87
  _cursor: {
@@ -75,6 +96,7 @@ export interface InMemoryBTreeConfig<TKey> {
75
96
  duplicateKeys?: DuplicateKeyPolicy;
76
97
  enableEntryIdLookup?: boolean;
77
98
  autoScale?: boolean;
99
+ deleteRebalancePolicy?: DeleteRebalancePolicy;
78
100
  }
79
101
  export interface BTreeStats {
80
102
  height: number;
@@ -85,29 +107,4 @@ export interface BTreeStats {
85
107
  export declare const isLeafNode: <TKey, TValue>(node: BTreeNode<TKey, TValue>) => node is LeafNode<TKey, TValue>;
86
108
  export declare const writeMinKeyTo: <TKey, TValue>(node: BTreeNode<TKey, TValue>, target: NodeKey<TKey>) => boolean;
87
109
  export declare const normalizeNodeCapacity: (value: number | undefined, field: string, defaultValue: number) => number;
88
- export declare const createLeafNode: <TKey, TValue>(entries: LeafEntry<TKey, TValue>[], parent: BranchNode<TKey, TValue> | null) => LeafNode<TKey, TValue>;
89
- export declare const createBranchNode: <TKey, TValue>(children: BTreeNode<TKey, TValue>[], parent: BranchNode<TKey, TValue> | null) => BranchNode<TKey, TValue>;
90
- /** Number of logical entries in the leaf */
91
- export declare const leafEntryCount: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => number;
92
- /** Get logical entry at index i (0-based from the logical start) */
93
- export declare const leafEntryAt: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, i: number) => LeafEntry<TKey, TValue>;
94
- /** Remove and return the first logical entry. O(1) amortized — increments offset and compacts when dead slots reach half. */
95
- export declare const leafShiftEntry: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => LeafEntry<TKey, TValue> | undefined;
96
- /** Remove and return the last logical entry. O(1) — pops from the backing array tail. */
97
- export declare const leafPopEntry: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => LeafEntry<TKey, TValue> | undefined;
98
- /** Prepend entry to logical start. Falls back to unshift if no gap, otherwise fills gap. */
99
- export declare const leafUnshiftEntry: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, entry: LeafEntry<TKey, TValue>) => void;
100
- /** Remove logical entry at index. Shifts the smaller side to halve average cost. */
101
- export declare const leafRemoveAt: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, logicalIndex: number) => void;
102
- /** Insert entry at logical index. Uses entryOffset gap when inserting in the first half. */
103
- export declare const leafInsertAt: <TKey, TValue>(leaf: LeafNode<TKey, TValue>, logicalIndex: number, entry: LeafEntry<TKey, TValue>) => void;
104
- /** Compact the backing array — remove dead slots before entryOffset. Call before splits/merges. */
105
- export declare const leafCompact: <TKey, TValue>(leaf: LeafNode<TKey, TValue>) => void;
106
- /** Compact branch arrays — remove dead slots before childOffset, keeping a small gap. */
107
- export declare const branchCompact: <TKey, TValue>(branch: BranchNode<TKey, TValue>) => void;
108
- /** Number of logical children in the branch. */
109
- export declare const branchChildCount: <TKey, TValue>(branch: BranchNode<TKey, TValue>) => number;
110
- /** Insert a child at a logical index. Shifts the smaller side to halve average cost. */
111
- export declare const branchInsertAt: <TKey, TValue>(branch: BranchNode<TKey, TValue>, logicalIndex: number, child: BTreeNode<TKey, TValue>, key: NodeKey<TKey>) => void;
112
- /** Remove a child at a physical index. Shifts the smaller side. */
113
- export declare const branchRemoveAt: <TKey, TValue>(branch: BranchNode<TKey, TValue>, physIndex: number) => void;
110
+ export { createLeafNode, createBranchNode, leafEntryCount, leafEntryAt, leafShiftEntry, leafPopEntry, leafUnshiftEntry, leafRemoveAt, leafInsertAt, leafCompact, branchCompact, branchChildCount, branchInsertAt, branchRemoveAt, } from './node-ops.js';