btree-core 3.2.1

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.
Files changed (42) hide show
  1. package/LICENSE +23 -0
  2. package/b+tree.d.ts +429 -0
  3. package/b+tree.js +1545 -0
  4. package/b+tree.min.js +1 -0
  5. package/extended/bulkLoad.d.ts +14 -0
  6. package/extended/bulkLoad.js +113 -0
  7. package/extended/bulkLoad.min.js +1 -0
  8. package/extended/decompose.d.ts +1 -0
  9. package/extended/decompose.js +680 -0
  10. package/extended/decompose.min.js +1 -0
  11. package/extended/diffAgainst.d.ts +23 -0
  12. package/extended/diffAgainst.js +254 -0
  13. package/extended/diffAgainst.min.js +1 -0
  14. package/extended/forEachKeyInBoth.d.ts +19 -0
  15. package/extended/forEachKeyInBoth.js +73 -0
  16. package/extended/forEachKeyInBoth.min.js +1 -0
  17. package/extended/forEachKeyNotIn.d.ts +18 -0
  18. package/extended/forEachKeyNotIn.js +87 -0
  19. package/extended/forEachKeyNotIn.min.js +1 -0
  20. package/extended/index.d.ts +133 -0
  21. package/extended/index.js +200 -0
  22. package/extended/index.min.js +1 -0
  23. package/extended/intersect.d.ts +16 -0
  24. package/extended/intersect.js +44 -0
  25. package/extended/intersect.min.js +1 -0
  26. package/extended/parallelWalk.d.ts +1 -0
  27. package/extended/parallelWalk.js +188 -0
  28. package/extended/parallelWalk.min.js +1 -0
  29. package/extended/shared.d.ts +1 -0
  30. package/extended/shared.js +64 -0
  31. package/extended/shared.min.js +1 -0
  32. package/extended/subtract.d.ts +16 -0
  33. package/extended/subtract.js +35 -0
  34. package/extended/subtract.min.js +1 -0
  35. package/extended/union.d.ts +16 -0
  36. package/extended/union.js +36 -0
  37. package/extended/union.min.js +1 -0
  38. package/interfaces.d.ts +307 -0
  39. package/package.json +122 -0
  40. package/readme.md +420 -0
  41. package/sorted-array.d.ts +22 -0
  42. package/sorted-array.js +71 -0
package/readme.md ADDED
@@ -0,0 +1,420 @@
1
+ # btree-core
2
+
3
+ A high-performance, type-safe B+ tree indexing engine for JavaScript and TypeScript.
4
+
5
+ `btree-core` is a modern in-memory indexing library designed for applications that require fast key-based access, scalable data management, and predictable performance. Built on a B+ tree architecture, it delivers logarithmic-time lookups, inserts, updates, and deletions while providing powerful APIs for querying, indexing, traversal, and bulk data operations.
6
+
7
+ Unlike traditional hash-based structures such as `Map`, `btree-core` is optimized for workloads where efficient indexing and range-based access are essential. Its architecture enables applications to maintain large datasets with consistent performance characteristics while supporting advanced operations such as structural sharing, persistent updates, tree diffing, and bulk loading.
8
+
9
+ Whether you're building a search engine, analytics platform, caching layer, database component, event store, recommendation system, or custom indexing solution, `btree-core` provides the performance and flexibility required for modern data-intensive applications.
10
+
11
+ ---
12
+
13
+ ## Why btree-core?
14
+
15
+ Most JavaScript applications rely on `Map` for key-value storage. While `Map` provides excellent average-case lookup performance, it lacks indexing capabilities and does not support efficient range-based operations.
16
+
17
+ `btree-core` fills this gap by providing a dedicated indexing structure built specifically for large-scale in-memory data management.
18
+
19
+ ### Benefits
20
+
21
+ * High-performance B+ tree implementation
22
+ * Strong TypeScript support
23
+ * Efficient key-based indexing
24
+ * O(log n) lookup, insertion, update, and deletion
25
+ * Fast range-based access patterns
26
+ * Structural sharing for efficient cloning
27
+ * Persistent operations for immutable workflows
28
+ * Memory-efficient node organization
29
+ * Advanced diffing and comparison utilities
30
+ * Bulk loading and batch operations
31
+ * Custom comparator support
32
+ * Zero runtime dependencies
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ npm install btree-core
40
+ ```
41
+
42
+ Using Yarn:
43
+
44
+ ```bash
45
+ yarn add btree-core
46
+ ```
47
+
48
+ Using pnpm:
49
+
50
+ ```bash
51
+ pnpm add btree-core
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quick Start
57
+
58
+ ```ts
59
+ import BTree from 'btree-core';
60
+
61
+ const users = new BTree<number, string>();
62
+
63
+ users.set(1001, 'Alice');
64
+ users.set(1002, 'Bob');
65
+ users.set(1003, 'Charlie');
66
+
67
+ console.log(users.get(1002));
68
+ // Bob
69
+
70
+ console.log(users.has(1003));
71
+ // true
72
+
73
+ users.delete(1001);
74
+
75
+ console.log(users.size);
76
+ // 2
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Core Concepts
82
+
83
+ ### Efficient Indexing
84
+
85
+ `btree-core` stores data using a balanced B+ tree structure.
86
+
87
+ This allows operations such as:
88
+
89
+ * Lookup
90
+ * Insert
91
+ * Update
92
+ * Delete
93
+ * Range scans
94
+ * Neighbor searches
95
+
96
+ to execute efficiently even as datasets grow to hundreds of thousands or millions of entries.
97
+
98
+ ### Predictable Performance
99
+
100
+ Most operations execute in logarithmic time:
101
+
102
+ | Operation | Complexity |
103
+ | ----------- | ------------ |
104
+ | Lookup | O(log n) |
105
+ | Insert | O(log n) |
106
+ | Update | O(log n) |
107
+ | Delete | O(log n) |
108
+ | Clone | O(1) |
109
+ | Range Query | O(log n + k) |
110
+
111
+ Where `k` is the number of returned results.
112
+
113
+ ### Structural Sharing
114
+
115
+ Tree cloning is performed using structural sharing.
116
+
117
+ ```ts
118
+ const tree1 = new BTree();
119
+ tree1.set(1, 'A');
120
+
121
+ const tree2 = tree1.clone();
122
+
123
+ tree2.set(2, 'B');
124
+ ```
125
+
126
+ Large portions of both trees remain shared internally until modifications occur, minimizing memory usage.
127
+
128
+ ---
129
+
130
+ # Features
131
+
132
+ ## Type-Safe API
133
+
134
+ Written entirely in TypeScript with bundled type definitions.
135
+
136
+ ```ts
137
+ const index = new BTree<number, User>();
138
+ ```
139
+
140
+ No additional type packages are required.
141
+
142
+ ---
143
+
144
+ ## Familiar Map-Like Interface
145
+
146
+ Developers familiar with JavaScript's built-in `Map` can adopt `btree-core` immediately.
147
+
148
+ ```ts
149
+ tree.set(key, value);
150
+ tree.get(key);
151
+ tree.has(key);
152
+ tree.delete(key);
153
+ tree.clear();
154
+ ```
155
+
156
+ Supported iteration methods:
157
+
158
+ ```ts
159
+ tree.keys();
160
+ tree.values();
161
+ tree.entries();
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Custom Comparators
167
+
168
+ Create indexes over complex objects by supplying a comparator.
169
+
170
+ ```ts
171
+ const users = new BTree<User, UserData>(
172
+ undefined,
173
+ (a, b) => {
174
+ if (a.department !== b.department) {
175
+ return a.department.localeCompare(b.department);
176
+ }
177
+
178
+ return a.id - b.id;
179
+ }
180
+ );
181
+ ```
182
+
183
+ This allows indexing by any application-specific ordering strategy.
184
+
185
+ ---
186
+
187
+ ## Range Queries
188
+
189
+ Efficiently access subsets of indexed data.
190
+
191
+ ```ts
192
+ const records = tree.getRange(
193
+ 1000,
194
+ 5000,
195
+ true
196
+ );
197
+ ```
198
+
199
+ Range queries are particularly useful for:
200
+
201
+ * Analytics
202
+ * Search systems
203
+ * Reporting tools
204
+ * Time-series applications
205
+ * Event streams
206
+
207
+ ---
208
+
209
+ ## Neighbor Search
210
+
211
+ Find adjacent indexed entries.
212
+
213
+ ```ts
214
+ tree.nextHigherKey(key);
215
+ tree.nextHigherPair(key);
216
+
217
+ tree.nextLowerKey(key);
218
+ tree.nextLowerPair(key);
219
+ ```
220
+
221
+ Useful for:
222
+
223
+ * Pagination
224
+ * Ranking systems
225
+ * Scheduling engines
226
+ * Navigation structures
227
+
228
+ ---
229
+
230
+ ## Bulk Operations
231
+
232
+ Load large datasets efficiently.
233
+
234
+ ```ts
235
+ tree.setPairs(entries);
236
+ ```
237
+
238
+ Or use:
239
+
240
+ ```ts
241
+ BTreeEx.bulkLoad(entries, 32);
242
+ ```
243
+
244
+ for maximum loading performance.
245
+
246
+ ---
247
+
248
+ ## Persistent Operations
249
+
250
+ Persistent APIs return modified copies without mutating the original tree.
251
+
252
+ ```ts
253
+ const tree2 = tree1.with(
254
+ userId,
255
+ user
256
+ );
257
+
258
+ const tree3 = tree2.without(
259
+ userId
260
+ );
261
+ ```
262
+
263
+ These operations are ideal for:
264
+
265
+ * Immutable state management
266
+ * Event sourcing
267
+ * Snapshot systems
268
+ * Undo/redo functionality
269
+
270
+ ---
271
+
272
+ ## Tree Diffing
273
+
274
+ Compare large indexes efficiently.
275
+
276
+ ```ts
277
+ treeA.diffAgainst(
278
+ treeB,
279
+ onlyInA,
280
+ onlyInB,
281
+ changed
282
+ );
283
+ ```
284
+
285
+ Shared subtrees are skipped automatically, dramatically reducing comparison costs.
286
+
287
+ ---
288
+
289
+ ## Union and Intersection
290
+
291
+ Combine or compare indexed datasets.
292
+
293
+ ```ts
294
+ treeA.union(treeB);
295
+
296
+ treeA.intersect(treeB);
297
+
298
+ treeA.subtract(treeB);
299
+ ```
300
+
301
+ Useful for:
302
+
303
+ * Synchronization
304
+ * Data reconciliation
305
+ * Merge operations
306
+ * Distributed systems
307
+
308
+ ---
309
+
310
+ ## Memory Efficiency
311
+
312
+ The tree actively balances node utilization and minimizes unnecessary allocations.
313
+
314
+ Additional optimizations include:
315
+
316
+ * Shared subtrees
317
+ * Compact node layouts
318
+ * Lazy copy-on-write updates
319
+ * Efficient set-style storage
320
+
321
+ These characteristics make `btree-core` suitable for large in-memory datasets.
322
+
323
+ ---
324
+
325
+ # Supported Key Types
326
+
327
+ By default, keys may be:
328
+
329
+ * Number
330
+ * String
331
+ * Date
332
+ * Arrays of numbers
333
+ * Arrays of strings
334
+
335
+ Objects may also be used if they provide:
336
+
337
+ ```ts
338
+ valueOf()
339
+ ```
340
+
341
+ or when a custom comparator is supplied.
342
+
343
+ ---
344
+
345
+ # Use Cases
346
+
347
+ `btree-core` is well suited for:
348
+
349
+ ### Search Engines
350
+
351
+ Maintain efficient indexes for document retrieval and query execution.
352
+
353
+ ### Analytics Systems
354
+
355
+ Perform fast aggregation and range-based scans across large datasets.
356
+
357
+ ### Time-Series Platforms
358
+
359
+ Store and query timestamped events efficiently.
360
+
361
+ ### Caching Layers
362
+
363
+ Build advanced caches with predictable lookup performance.
364
+
365
+ ### Database Components
366
+
367
+ Use as the foundation for secondary indexes and query planners.
368
+
369
+ ### Recommendation Engines
370
+
371
+ Maintain ranked datasets and neighbor relationships.
372
+
373
+ ### Event Sourcing
374
+
375
+ Leverage immutable operations and structural sharing for snapshots and history tracking.
376
+
377
+ ### Real-Time Applications
378
+
379
+ Support frequent updates while maintaining efficient indexed access.
380
+
381
+ ---
382
+
383
+ # Extended Functionality
384
+
385
+ Import the extended API:
386
+
387
+ ```ts
388
+ import BTreeEx from 'btree-core/extended';
389
+ ```
390
+
391
+ Or individual algorithms:
392
+
393
+ ```ts
394
+ import diffAgainst from 'btree-core/extended/diffAgainst';
395
+ ```
396
+
397
+ The extended package includes:
398
+
399
+ * Tree diffing
400
+ * Union operations
401
+ * Intersection operations
402
+ * Dataset subtraction
403
+ * Shared-key iteration
404
+ * Bulk loading utilities
405
+
406
+ ---
407
+
408
+ # Performance Philosophy
409
+
410
+ `btree-core` is designed around a simple principle:
411
+
412
+ > Fast indexed access with predictable performance and minimal memory overhead.
413
+
414
+ Rather than optimizing exclusively for small datasets, the library is engineered to scale efficiently as data volumes grow, making it suitable for long-lived applications, backend services, analytics workloads, and performance-critical systems.
415
+
416
+ ---
417
+
418
+ # License
419
+
420
+ MIT License.
@@ -0,0 +1,22 @@
1
+ import { IMap } from './interfaces';
2
+ /** A super-inefficient sorted list for testing purposes */
3
+ export default class SortedArray<K = any, V = any> implements IMap<K, V> {
4
+ a: [K, V][];
5
+ cmp: (a: K, b: K) => number;
6
+ constructor(entries?: [K, V][], compare?: (a: K, b: K) => number);
7
+ get size(): number;
8
+ get(key: K, defaultValue?: V): V | undefined;
9
+ set(key: K, value: V, overwrite?: boolean): boolean;
10
+ has(key: K): boolean;
11
+ delete(key: K): boolean;
12
+ clear(): void;
13
+ getArray(): [K, V][];
14
+ minKey(): K | undefined;
15
+ maxKey(): K | undefined;
16
+ forEach(callbackFn: (v: V, k: K, list: SortedArray<K, V>) => void): void;
17
+ [Symbol.iterator](): IterableIterator<[K, V]>;
18
+ entries(): IterableIterator<[K, V]>;
19
+ keys(): IterableIterator<K>;
20
+ values(): IterableIterator<V>;
21
+ indexOf(key: K, failXor: number): number;
22
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /** A super-inefficient sorted list for testing purposes */
4
+ var SortedArray = /** @class */ (function () {
5
+ function SortedArray(entries, compare) {
6
+ this.cmp = compare || (function (a, b) { return a < b ? -1 : a > b ? 1 : a === b ? 0 : a - b; });
7
+ this.a = [];
8
+ if (entries !== undefined)
9
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
10
+ var e = entries_1[_i];
11
+ this.set(e[0], e[1]);
12
+ }
13
+ }
14
+ Object.defineProperty(SortedArray.prototype, "size", {
15
+ get: function () { return this.a.length; },
16
+ enumerable: false,
17
+ configurable: true
18
+ });
19
+ SortedArray.prototype.get = function (key, defaultValue) {
20
+ var pair = this.a[this.indexOf(key, -1)];
21
+ return pair === undefined ? defaultValue : pair[1];
22
+ };
23
+ SortedArray.prototype.set = function (key, value, overwrite) {
24
+ var i = this.indexOf(key, -1);
25
+ if (i <= -1)
26
+ this.a.splice(~i, 0, [key, value]);
27
+ else
28
+ this.a[i] = [key, value];
29
+ return i <= -1;
30
+ };
31
+ SortedArray.prototype.has = function (key) {
32
+ return this.indexOf(key, -1) >= 0;
33
+ };
34
+ SortedArray.prototype.delete = function (key) {
35
+ var i = this.indexOf(key, -1);
36
+ if (i > -1)
37
+ this.a.splice(i, 1);
38
+ return i > -1;
39
+ };
40
+ SortedArray.prototype.clear = function () { this.a = []; };
41
+ SortedArray.prototype.getArray = function () { return this.a; };
42
+ SortedArray.prototype.minKey = function () { return this.a[0][0]; };
43
+ SortedArray.prototype.maxKey = function () { return this.a[this.a.length - 1][0]; };
44
+ SortedArray.prototype.forEach = function (callbackFn) {
45
+ var _this = this;
46
+ this.a.forEach(function (pair) { return callbackFn(pair[1], pair[0], _this); });
47
+ };
48
+ // a.values() used to implement IMap<K,V> but it's not actually available in Node v10.4
49
+ SortedArray.prototype[Symbol.iterator] = function () { return this.a.values(); };
50
+ SortedArray.prototype.entries = function () { return this.a.values(); };
51
+ SortedArray.prototype.keys = function () { return this.a.map(function (pair) { return pair[0]; }).values(); };
52
+ SortedArray.prototype.values = function () { return this.a.map(function (pair) { return pair[1]; }).values(); };
53
+ SortedArray.prototype.indexOf = function (key, failXor) {
54
+ var lo = 0, hi = this.a.length, mid = hi >> 1;
55
+ while (lo < hi) {
56
+ var c = this.cmp(this.a[mid][0], key);
57
+ if (c < 0)
58
+ lo = mid + 1;
59
+ else if (c > 0) // keys[mid] > key
60
+ hi = mid;
61
+ else if (c === 0)
62
+ return mid;
63
+ else
64
+ throw new Error("Problem: compare failed");
65
+ mid = (lo + hi) >> 1;
66
+ }
67
+ return mid ^ failXor;
68
+ };
69
+ return SortedArray;
70
+ }());
71
+ exports.default = SortedArray;