serializable-bptree 8.3.5 → 8.4.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.
- package/README.md +1 -0
- package/dist/cjs/index.cjs +269 -64
- package/dist/esm/index.mjs +269 -64
- package/dist/types/BPTreeAsync.d.ts +1 -0
- package/dist/types/BPTreeSync.d.ts +1 -0
- package/dist/types/base/BPTreeTransaction.d.ts +12 -0
- package/dist/types/transaction/BPTreeAsyncTransaction.d.ts +1 -0
- package/dist/types/transaction/BPTreeSyncTransaction.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ Additionally, this library supports asynchronous operations and rule-based query
|
|
|
84
84
|
- **Async/Sync Support**: Provides both synchronous and asynchronous APIs.
|
|
85
85
|
- **Query Optimization**: Rule-based optimizer to choose the best index for complex queries.
|
|
86
86
|
- **TypeScript**: Fully typed for a better developer experience.
|
|
87
|
+
- **Auto Rollback**: Automatically cleans up internal memory buffers on commit failures, preventing memory leaks without manual intervention.
|
|
87
88
|
|
|
88
89
|
## How to use
|
|
89
90
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -413,11 +413,7 @@ var MVCCTransaction = class {
|
|
|
413
413
|
*/
|
|
414
414
|
rollback() {
|
|
415
415
|
const { created, updated, deleted } = this.getResultEntries();
|
|
416
|
-
this.
|
|
417
|
-
this.deleteBuffer.clear();
|
|
418
|
-
this.createdKeys.clear();
|
|
419
|
-
this.deletedValues.clear();
|
|
420
|
-
this.originallyExisted.clear();
|
|
416
|
+
this._cleanupAll();
|
|
421
417
|
this.committed = true;
|
|
422
418
|
if (this.root !== this) {
|
|
423
419
|
this.root.activeTransactions.delete(this);
|
|
@@ -453,6 +449,19 @@ var MVCCTransaction = class {
|
|
|
453
449
|
}
|
|
454
450
|
return Array.from(conflicts);
|
|
455
451
|
}
|
|
452
|
+
/**
|
|
453
|
+
* Cleans up all buffers and history.
|
|
454
|
+
* This method is called by the commit method.
|
|
455
|
+
*/
|
|
456
|
+
_cleanupAll() {
|
|
457
|
+
this.writeBuffer.clear();
|
|
458
|
+
this.deleteBuffer.clear();
|
|
459
|
+
this.createdKeys.clear();
|
|
460
|
+
this.deletedValues.clear();
|
|
461
|
+
this.originallyExisted.clear();
|
|
462
|
+
this.keyVersions.clear();
|
|
463
|
+
this.bufferHistory.clear();
|
|
464
|
+
}
|
|
456
465
|
/**
|
|
457
466
|
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
458
467
|
* Root transactions call this after commit to reclaim memory.
|
|
@@ -644,6 +653,7 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
644
653
|
if (this.parent) {
|
|
645
654
|
const failure = this.parent._merge(this);
|
|
646
655
|
if (failure) {
|
|
656
|
+
this.rollback();
|
|
647
657
|
return {
|
|
648
658
|
label,
|
|
649
659
|
success: false,
|
|
@@ -654,11 +664,13 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
654
664
|
deleted
|
|
655
665
|
};
|
|
656
666
|
}
|
|
667
|
+
this._cleanupAll();
|
|
657
668
|
this.committed = true;
|
|
658
669
|
} else {
|
|
659
670
|
if (this.writeBuffer.size > 0 || this.deleteBuffer.size > 0) {
|
|
660
671
|
const failure = this._merge(this);
|
|
661
672
|
if (failure) {
|
|
673
|
+
this.rollback();
|
|
662
674
|
return {
|
|
663
675
|
label,
|
|
664
676
|
success: false,
|
|
@@ -669,13 +681,7 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
669
681
|
deleted: []
|
|
670
682
|
};
|
|
671
683
|
}
|
|
672
|
-
this.
|
|
673
|
-
this.deleteBuffer.clear();
|
|
674
|
-
this.createdKeys.clear();
|
|
675
|
-
this.deletedValues.clear();
|
|
676
|
-
this.originallyExisted.clear();
|
|
677
|
-
this.keyVersions.clear();
|
|
678
|
-
this.bufferHistory.clear();
|
|
684
|
+
this._cleanupAll();
|
|
679
685
|
this.localVersion = 0;
|
|
680
686
|
this.snapshotVersion = this.version;
|
|
681
687
|
}
|
|
@@ -1309,6 +1315,7 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1309
1315
|
if (this.parent) {
|
|
1310
1316
|
const failure = await this.parent._merge(this);
|
|
1311
1317
|
if (failure) {
|
|
1318
|
+
this.rollback();
|
|
1312
1319
|
return {
|
|
1313
1320
|
label,
|
|
1314
1321
|
success: false,
|
|
@@ -1319,11 +1326,13 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1319
1326
|
deleted
|
|
1320
1327
|
};
|
|
1321
1328
|
}
|
|
1329
|
+
this._cleanupAll();
|
|
1322
1330
|
this.committed = true;
|
|
1323
1331
|
} else {
|
|
1324
1332
|
if (this.writeBuffer.size > 0 || this.deleteBuffer.size > 0) {
|
|
1325
1333
|
const failure = await this._merge(this);
|
|
1326
1334
|
if (failure) {
|
|
1335
|
+
this.rollback();
|
|
1327
1336
|
return {
|
|
1328
1337
|
label,
|
|
1329
1338
|
success: false,
|
|
@@ -1334,13 +1343,7 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1334
1343
|
deleted: []
|
|
1335
1344
|
};
|
|
1336
1345
|
}
|
|
1337
|
-
this.
|
|
1338
|
-
this.deleteBuffer.clear();
|
|
1339
|
-
this.createdKeys.clear();
|
|
1340
|
-
this.deletedValues.clear();
|
|
1341
|
-
this.originallyExisted.clear();
|
|
1342
|
-
this.keyVersions.clear();
|
|
1343
|
-
this.bufferHistory.clear();
|
|
1346
|
+
this._cleanupAll();
|
|
1344
1347
|
this.localVersion = 0;
|
|
1345
1348
|
this.snapshotVersion = this.version;
|
|
1346
1349
|
}
|
|
@@ -1924,30 +1927,22 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1924
1927
|
*/
|
|
1925
1928
|
_insertValueIntoLeaf(leaf, key, value) {
|
|
1926
1929
|
if (leaf.values.length) {
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
if (
|
|
1930
|
-
|
|
1931
|
-
return false;
|
|
1932
|
-
}
|
|
1933
|
-
leaf.keys[i].push(key);
|
|
1934
|
-
return true;
|
|
1935
|
-
} else if (this.comparator.isLower(value, nValue)) {
|
|
1936
|
-
leaf.values.splice(i, 0, value);
|
|
1937
|
-
leaf.keys.splice(i, 0, [key]);
|
|
1938
|
-
return true;
|
|
1939
|
-
} else if (i + 1 === leaf.values.length) {
|
|
1940
|
-
leaf.values.push(value);
|
|
1941
|
-
leaf.keys.push([key]);
|
|
1942
|
-
return true;
|
|
1930
|
+
const { index, found } = this._binarySearchValues(leaf.values, value);
|
|
1931
|
+
if (found) {
|
|
1932
|
+
if (leaf.keys[index].includes(key)) {
|
|
1933
|
+
return false;
|
|
1943
1934
|
}
|
|
1935
|
+
leaf.keys[index].push(key);
|
|
1936
|
+
return true;
|
|
1944
1937
|
}
|
|
1938
|
+
leaf.values.splice(index, 0, value);
|
|
1939
|
+
leaf.keys.splice(index, 0, [key]);
|
|
1940
|
+
return true;
|
|
1945
1941
|
} else {
|
|
1946
1942
|
leaf.values = [value];
|
|
1947
1943
|
leaf.keys = [[key]];
|
|
1948
1944
|
return true;
|
|
1949
1945
|
}
|
|
1950
|
-
return false;
|
|
1951
1946
|
}
|
|
1952
1947
|
_cloneNode(node) {
|
|
1953
1948
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -2240,12 +2235,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2240
2235
|
const midValue = parentNode.values[mid];
|
|
2241
2236
|
parentNode.values = parentNode.values.slice(0, mid);
|
|
2242
2237
|
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
2243
|
-
for (
|
|
2244
|
-
const
|
|
2245
|
-
n.parent = parentNode.id;
|
|
2246
|
-
this._updateNode(n);
|
|
2247
|
-
}
|
|
2248
|
-
for (const k of newSiblingNodeRecursive.keys) {
|
|
2238
|
+
for (let i = 0, len = newSiblingNodeRecursive.keys.length; i < len; i++) {
|
|
2239
|
+
const k = newSiblingNodeRecursive.keys[i];
|
|
2249
2240
|
const n = this._cloneNode(this.getNode(k));
|
|
2250
2241
|
n.parent = newSiblingNodeRecursive.id;
|
|
2251
2242
|
this._updateNode(n);
|
|
@@ -2327,7 +2318,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2327
2318
|
for (let i = 0; i < len; i++) {
|
|
2328
2319
|
const nValue = node.values[i];
|
|
2329
2320
|
const keys = node.keys[i];
|
|
2330
|
-
for (let j = 0,
|
|
2321
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
2331
2322
|
yield [keys[j], nValue];
|
|
2332
2323
|
}
|
|
2333
2324
|
}
|
|
@@ -2406,7 +2397,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2406
2397
|
while (true) {
|
|
2407
2398
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2408
2399
|
const keys = node.keys[i];
|
|
2409
|
-
for (let j = 0,
|
|
2400
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
2410
2401
|
if (keys[j] === key) {
|
|
2411
2402
|
return node.values[i];
|
|
2412
2403
|
}
|
|
@@ -2515,8 +2506,16 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2515
2506
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2516
2507
|
let currentLeaf = null;
|
|
2517
2508
|
let modified = false;
|
|
2518
|
-
|
|
2519
|
-
|
|
2509
|
+
let cachedLeafId = null;
|
|
2510
|
+
let cachedLeafMaxValue = null;
|
|
2511
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
2512
|
+
const [key, value] = sorted[i];
|
|
2513
|
+
let targetLeaf;
|
|
2514
|
+
if (cachedLeafId !== null && cachedLeafMaxValue !== null && currentLeaf !== null && (this.comparator.isLower(value, cachedLeafMaxValue) || this.comparator.isSame(value, cachedLeafMaxValue))) {
|
|
2515
|
+
targetLeaf = currentLeaf;
|
|
2516
|
+
} else {
|
|
2517
|
+
targetLeaf = this.locateLeaf(value);
|
|
2518
|
+
}
|
|
2520
2519
|
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
2521
2520
|
} else {
|
|
2522
2521
|
if (currentLeaf !== null && modified) {
|
|
@@ -2525,8 +2524,10 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2525
2524
|
currentLeaf = this._cloneNode(targetLeaf);
|
|
2526
2525
|
modified = false;
|
|
2527
2526
|
}
|
|
2527
|
+
cachedLeafId = currentLeaf.id;
|
|
2528
2528
|
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
2529
2529
|
modified = modified || changed;
|
|
2530
|
+
cachedLeafMaxValue = currentLeaf.values[currentLeaf.values.length - 1];
|
|
2530
2531
|
if (currentLeaf.values.length === this.order) {
|
|
2531
2532
|
this._updateNode(currentLeaf);
|
|
2532
2533
|
let after = this._createNode(
|
|
@@ -2547,6 +2548,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2547
2548
|
this._updateNode(after);
|
|
2548
2549
|
this._insertInParent(currentLeaf, after.values[0], after);
|
|
2549
2550
|
currentLeaf = null;
|
|
2551
|
+
cachedLeafId = null;
|
|
2552
|
+
cachedLeafMaxValue = null;
|
|
2550
2553
|
modified = false;
|
|
2551
2554
|
}
|
|
2552
2555
|
}
|
|
@@ -2554,6 +2557,85 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2554
2557
|
this._updateNode(currentLeaf);
|
|
2555
2558
|
}
|
|
2556
2559
|
}
|
|
2560
|
+
bulkLoad(entries) {
|
|
2561
|
+
if (entries.length === 0) return;
|
|
2562
|
+
const root = this.getNode(this.rootId);
|
|
2563
|
+
if (!root.leaf || root.values.length > 0) {
|
|
2564
|
+
throw new Error("bulkLoad can only be called on an empty tree. Use batchInsert for non-empty trees.");
|
|
2565
|
+
}
|
|
2566
|
+
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2567
|
+
const grouped = [];
|
|
2568
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
2569
|
+
const [key, value] = sorted[i];
|
|
2570
|
+
const last = grouped[grouped.length - 1];
|
|
2571
|
+
if (last && this.comparator.isSame(last.value, value)) {
|
|
2572
|
+
if (!last.keys.includes(key)) {
|
|
2573
|
+
last.keys.push(key);
|
|
2574
|
+
}
|
|
2575
|
+
} else {
|
|
2576
|
+
grouped.push({ keys: [key], value });
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
this._deleteNode(root);
|
|
2580
|
+
const maxLeafSize = this.order - 1;
|
|
2581
|
+
const leaves = [];
|
|
2582
|
+
for (let i = 0, len = grouped.length; i < len; i += maxLeafSize) {
|
|
2583
|
+
const chunk = grouped.slice(i, i + maxLeafSize);
|
|
2584
|
+
const leafKeys = chunk.map((g) => g.keys);
|
|
2585
|
+
const leafValues = chunk.map((g) => g.value);
|
|
2586
|
+
const leaf = this._createNode(
|
|
2587
|
+
true,
|
|
2588
|
+
leafKeys,
|
|
2589
|
+
leafValues,
|
|
2590
|
+
null,
|
|
2591
|
+
null,
|
|
2592
|
+
null
|
|
2593
|
+
);
|
|
2594
|
+
leaves.push(leaf);
|
|
2595
|
+
}
|
|
2596
|
+
for (let i = 0, len = leaves.length; i < len; i++) {
|
|
2597
|
+
if (i > 0) {
|
|
2598
|
+
leaves[i].prev = leaves[i - 1].id;
|
|
2599
|
+
}
|
|
2600
|
+
if (i < len - 1) {
|
|
2601
|
+
leaves[i].next = leaves[i + 1].id;
|
|
2602
|
+
}
|
|
2603
|
+
this._updateNode(leaves[i]);
|
|
2604
|
+
}
|
|
2605
|
+
let currentLevel = leaves;
|
|
2606
|
+
while (currentLevel.length > 1) {
|
|
2607
|
+
const nextLevel = [];
|
|
2608
|
+
for (let i = 0, len = currentLevel.length; i < len; i += this.order) {
|
|
2609
|
+
const children = currentLevel.slice(i, i + this.order);
|
|
2610
|
+
const childIds = children.map((c) => c.id);
|
|
2611
|
+
const separators = [];
|
|
2612
|
+
for (let j = 1, len2 = children.length; j < len2; j++) {
|
|
2613
|
+
separators.push(children[j].values[0]);
|
|
2614
|
+
}
|
|
2615
|
+
const internalNode = this._createNode(
|
|
2616
|
+
false,
|
|
2617
|
+
childIds,
|
|
2618
|
+
separators,
|
|
2619
|
+
null,
|
|
2620
|
+
null,
|
|
2621
|
+
null
|
|
2622
|
+
);
|
|
2623
|
+
for (let j = 0, len2 = children.length; j < len2; j++) {
|
|
2624
|
+
const child = children[j];
|
|
2625
|
+
child.parent = internalNode.id;
|
|
2626
|
+
this._updateNode(child);
|
|
2627
|
+
}
|
|
2628
|
+
nextLevel.push(internalNode);
|
|
2629
|
+
}
|
|
2630
|
+
currentLevel = nextLevel;
|
|
2631
|
+
}
|
|
2632
|
+
const newRoot = currentLevel[0];
|
|
2633
|
+
this._writeHead({
|
|
2634
|
+
root: newRoot.id,
|
|
2635
|
+
order: this.order,
|
|
2636
|
+
data: this.strategy.head.data
|
|
2637
|
+
});
|
|
2638
|
+
}
|
|
2557
2639
|
_deleteEntry(node, key) {
|
|
2558
2640
|
if (!node.leaf) {
|
|
2559
2641
|
let keyIndex = -1;
|
|
@@ -2657,7 +2739,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2657
2739
|
siblingNode.values.push(...node.values);
|
|
2658
2740
|
if (!siblingNode.leaf) {
|
|
2659
2741
|
const keys = siblingNode.keys;
|
|
2660
|
-
for (
|
|
2742
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2743
|
+
const key2 = keys[i];
|
|
2661
2744
|
const node2 = this._cloneNode(this.getNode(key2));
|
|
2662
2745
|
node2.parent = siblingNode.id;
|
|
2663
2746
|
this._updateNode(node2);
|
|
@@ -2725,21 +2808,24 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2725
2808
|
this._updateNode(siblingNode);
|
|
2726
2809
|
}
|
|
2727
2810
|
if (!siblingNode.leaf) {
|
|
2728
|
-
for (
|
|
2811
|
+
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
2812
|
+
const key2 = siblingNode.keys[i];
|
|
2729
2813
|
const n = this._cloneNode(this.getNode(key2));
|
|
2730
2814
|
n.parent = siblingNode.id;
|
|
2731
2815
|
this._updateNode(n);
|
|
2732
2816
|
}
|
|
2733
2817
|
}
|
|
2734
2818
|
if (!node.leaf) {
|
|
2735
|
-
for (
|
|
2819
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
2820
|
+
const key2 = node.keys[i];
|
|
2736
2821
|
const n = this._cloneNode(this.getNode(key2));
|
|
2737
2822
|
n.parent = node.id;
|
|
2738
2823
|
this._updateNode(n);
|
|
2739
2824
|
}
|
|
2740
2825
|
}
|
|
2741
2826
|
if (!parentNode.leaf) {
|
|
2742
|
-
for (
|
|
2827
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
2828
|
+
const key2 = parentNode.keys[i];
|
|
2743
2829
|
const n = this._cloneNode(this.getNode(key2));
|
|
2744
2830
|
n.parent = parentNode.id;
|
|
2745
2831
|
this._updateNode(n);
|
|
@@ -2816,8 +2902,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2816
2902
|
result = this.rootTx.commit(label);
|
|
2817
2903
|
if (result.success) {
|
|
2818
2904
|
this.rootTx.rootId = this.rootId;
|
|
2905
|
+
} else {
|
|
2906
|
+
this.mvcc.rollback();
|
|
2819
2907
|
}
|
|
2820
2908
|
}
|
|
2909
|
+
} else {
|
|
2910
|
+
this.mvcc.rollback();
|
|
2821
2911
|
}
|
|
2822
2912
|
return result;
|
|
2823
2913
|
}
|
|
@@ -2917,6 +3007,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
|
|
|
2917
3007
|
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
2918
3008
|
}
|
|
2919
3009
|
}
|
|
3010
|
+
bulkLoad(entries) {
|
|
3011
|
+
const tx = this.createTransaction();
|
|
3012
|
+
tx.bulkLoad(entries);
|
|
3013
|
+
const result = tx.commit();
|
|
3014
|
+
if (!result.success) {
|
|
3015
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
2920
3018
|
};
|
|
2921
3019
|
|
|
2922
3020
|
// node_modules/ryoiki/dist/esm/index.mjs
|
|
@@ -3334,12 +3432,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3334
3432
|
const midValue = parentNode.values[mid];
|
|
3335
3433
|
parentNode.values = parentNode.values.slice(0, mid);
|
|
3336
3434
|
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
3337
|
-
for (
|
|
3338
|
-
const
|
|
3339
|
-
n.parent = parentNode.id;
|
|
3340
|
-
await this._updateNode(n);
|
|
3341
|
-
}
|
|
3342
|
-
for (const k of newSiblingNodeRecursive.keys) {
|
|
3435
|
+
for (let i = 0, len = newSiblingNodeRecursive.keys.length; i < len; i++) {
|
|
3436
|
+
const k = newSiblingNodeRecursive.keys[i];
|
|
3343
3437
|
const n = this._cloneNode(await this.getNode(k));
|
|
3344
3438
|
n.parent = newSiblingNodeRecursive.id;
|
|
3345
3439
|
await this._updateNode(n);
|
|
@@ -3431,7 +3525,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3431
3525
|
for (let i = 0; i < len; i++) {
|
|
3432
3526
|
const nValue = node.values[i];
|
|
3433
3527
|
const keys = node.keys[i];
|
|
3434
|
-
for (let j = 0,
|
|
3528
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
3435
3529
|
yield [keys[j], nValue];
|
|
3436
3530
|
}
|
|
3437
3531
|
}
|
|
@@ -3509,7 +3603,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3509
3603
|
while (true) {
|
|
3510
3604
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
3511
3605
|
const keys = node.keys[i];
|
|
3512
|
-
for (let j = 0,
|
|
3606
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
3513
3607
|
if (keys[j] === key) {
|
|
3514
3608
|
return node.values[i];
|
|
3515
3609
|
}
|
|
@@ -3621,8 +3715,16 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3621
3715
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3622
3716
|
let currentLeaf = null;
|
|
3623
3717
|
let modified = false;
|
|
3624
|
-
|
|
3625
|
-
|
|
3718
|
+
let cachedLeafId = null;
|
|
3719
|
+
let cachedLeafMaxValue = null;
|
|
3720
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
3721
|
+
const [key, value] = sorted[i];
|
|
3722
|
+
let targetLeaf;
|
|
3723
|
+
if (cachedLeafId !== null && cachedLeafMaxValue !== null && currentLeaf !== null && (this.comparator.isLower(value, cachedLeafMaxValue) || this.comparator.isSame(value, cachedLeafMaxValue))) {
|
|
3724
|
+
targetLeaf = currentLeaf;
|
|
3725
|
+
} else {
|
|
3726
|
+
targetLeaf = await this.locateLeaf(value);
|
|
3727
|
+
}
|
|
3626
3728
|
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
3627
3729
|
} else {
|
|
3628
3730
|
if (currentLeaf !== null && modified) {
|
|
@@ -3631,8 +3733,10 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3631
3733
|
currentLeaf = this._cloneNode(targetLeaf);
|
|
3632
3734
|
modified = false;
|
|
3633
3735
|
}
|
|
3736
|
+
cachedLeafId = currentLeaf.id;
|
|
3634
3737
|
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
3635
3738
|
modified = modified || changed;
|
|
3739
|
+
cachedLeafMaxValue = currentLeaf.values[currentLeaf.values.length - 1];
|
|
3636
3740
|
if (currentLeaf.values.length === this.order) {
|
|
3637
3741
|
await this._updateNode(currentLeaf);
|
|
3638
3742
|
let after = await this._createNode(
|
|
@@ -3653,6 +3757,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3653
3757
|
await this._updateNode(after);
|
|
3654
3758
|
await this._insertInParent(currentLeaf, after.values[0], after);
|
|
3655
3759
|
currentLeaf = null;
|
|
3760
|
+
cachedLeafId = null;
|
|
3761
|
+
cachedLeafMaxValue = null;
|
|
3656
3762
|
modified = false;
|
|
3657
3763
|
}
|
|
3658
3764
|
}
|
|
@@ -3661,6 +3767,87 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3661
3767
|
}
|
|
3662
3768
|
});
|
|
3663
3769
|
}
|
|
3770
|
+
async bulkLoad(entries) {
|
|
3771
|
+
if (entries.length === 0) return;
|
|
3772
|
+
return this.writeLock(0, async () => {
|
|
3773
|
+
const root = await this.getNode(this.rootId);
|
|
3774
|
+
if (!root.leaf || root.values.length > 0) {
|
|
3775
|
+
throw new Error("bulkLoad can only be called on an empty tree. Use batchInsert for non-empty trees.");
|
|
3776
|
+
}
|
|
3777
|
+
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3778
|
+
const grouped = [];
|
|
3779
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
3780
|
+
const [key, value] = sorted[i];
|
|
3781
|
+
const last = grouped[grouped.length - 1];
|
|
3782
|
+
if (last && this.comparator.isSame(last.value, value)) {
|
|
3783
|
+
if (!last.keys.includes(key)) {
|
|
3784
|
+
last.keys.push(key);
|
|
3785
|
+
}
|
|
3786
|
+
} else {
|
|
3787
|
+
grouped.push({ keys: [key], value });
|
|
3788
|
+
}
|
|
3789
|
+
}
|
|
3790
|
+
await this._deleteNode(root);
|
|
3791
|
+
const maxLeafSize = this.order - 1;
|
|
3792
|
+
const leaves = [];
|
|
3793
|
+
for (let i = 0, len = grouped.length; i < len; i += maxLeafSize) {
|
|
3794
|
+
const chunk = grouped.slice(i, i + maxLeafSize);
|
|
3795
|
+
const leafKeys = chunk.map((g) => g.keys);
|
|
3796
|
+
const leafValues = chunk.map((g) => g.value);
|
|
3797
|
+
const leaf = await this._createNode(
|
|
3798
|
+
true,
|
|
3799
|
+
leafKeys,
|
|
3800
|
+
leafValues,
|
|
3801
|
+
null,
|
|
3802
|
+
null,
|
|
3803
|
+
null
|
|
3804
|
+
);
|
|
3805
|
+
leaves.push(leaf);
|
|
3806
|
+
}
|
|
3807
|
+
for (let i = 0, len = leaves.length; i < len; i++) {
|
|
3808
|
+
if (i > 0) {
|
|
3809
|
+
leaves[i].prev = leaves[i - 1].id;
|
|
3810
|
+
}
|
|
3811
|
+
if (i < len - 1) {
|
|
3812
|
+
leaves[i].next = leaves[i + 1].id;
|
|
3813
|
+
}
|
|
3814
|
+
await this._updateNode(leaves[i]);
|
|
3815
|
+
}
|
|
3816
|
+
let currentLevel = leaves;
|
|
3817
|
+
while (currentLevel.length > 1) {
|
|
3818
|
+
const nextLevel = [];
|
|
3819
|
+
for (let i = 0, len = currentLevel.length; i < len; i += this.order) {
|
|
3820
|
+
const children = currentLevel.slice(i, i + this.order);
|
|
3821
|
+
const childIds = children.map((c) => c.id);
|
|
3822
|
+
const separators = [];
|
|
3823
|
+
for (let j = 1, len2 = children.length; j < len2; j++) {
|
|
3824
|
+
separators.push(children[j].values[0]);
|
|
3825
|
+
}
|
|
3826
|
+
const internalNode = await this._createNode(
|
|
3827
|
+
false,
|
|
3828
|
+
childIds,
|
|
3829
|
+
separators,
|
|
3830
|
+
null,
|
|
3831
|
+
null,
|
|
3832
|
+
null
|
|
3833
|
+
);
|
|
3834
|
+
for (let j = 0, len2 = children.length; j < len2; j++) {
|
|
3835
|
+
const child = children[j];
|
|
3836
|
+
child.parent = internalNode.id;
|
|
3837
|
+
await this._updateNode(child);
|
|
3838
|
+
}
|
|
3839
|
+
nextLevel.push(internalNode);
|
|
3840
|
+
}
|
|
3841
|
+
currentLevel = nextLevel;
|
|
3842
|
+
}
|
|
3843
|
+
const newRoot = currentLevel[0];
|
|
3844
|
+
await this._writeHead({
|
|
3845
|
+
root: newRoot.id,
|
|
3846
|
+
order: this.order,
|
|
3847
|
+
data: this.strategy.head.data
|
|
3848
|
+
});
|
|
3849
|
+
});
|
|
3850
|
+
}
|
|
3664
3851
|
async _deleteEntry(node, key) {
|
|
3665
3852
|
if (!node.leaf) {
|
|
3666
3853
|
let keyIndex = -1;
|
|
@@ -3764,7 +3951,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3764
3951
|
siblingNode.values.push(...node.values);
|
|
3765
3952
|
if (!siblingNode.leaf) {
|
|
3766
3953
|
const keys = siblingNode.keys;
|
|
3767
|
-
for (
|
|
3954
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3955
|
+
const key2 = keys[i];
|
|
3768
3956
|
const node2 = this._cloneNode(await this.getNode(key2));
|
|
3769
3957
|
node2.parent = siblingNode.id;
|
|
3770
3958
|
await this._updateNode(node2);
|
|
@@ -3832,21 +4020,24 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3832
4020
|
await this._updateNode(siblingNode);
|
|
3833
4021
|
}
|
|
3834
4022
|
if (!siblingNode.leaf) {
|
|
3835
|
-
for (
|
|
4023
|
+
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
4024
|
+
const key2 = siblingNode.keys[i];
|
|
3836
4025
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3837
4026
|
n.parent = siblingNode.id;
|
|
3838
4027
|
await this._updateNode(n);
|
|
3839
4028
|
}
|
|
3840
4029
|
}
|
|
3841
4030
|
if (!node.leaf) {
|
|
3842
|
-
for (
|
|
4031
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
4032
|
+
const key2 = node.keys[i];
|
|
3843
4033
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3844
4034
|
n.parent = node.id;
|
|
3845
4035
|
await this._updateNode(n);
|
|
3846
4036
|
}
|
|
3847
4037
|
}
|
|
3848
4038
|
if (!parentNode.leaf) {
|
|
3849
|
-
for (
|
|
4039
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
4040
|
+
const key2 = parentNode.keys[i];
|
|
3850
4041
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3851
4042
|
n.parent = parentNode.id;
|
|
3852
4043
|
await this._updateNode(n);
|
|
@@ -3925,8 +4116,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3925
4116
|
result = await this.rootTx.commit(label);
|
|
3926
4117
|
if (result.success) {
|
|
3927
4118
|
this.rootTx.rootId = this.rootId;
|
|
4119
|
+
} else {
|
|
4120
|
+
this.mvcc.rollback();
|
|
3928
4121
|
}
|
|
3929
4122
|
}
|
|
4123
|
+
} else {
|
|
4124
|
+
this.mvcc.rollback();
|
|
3930
4125
|
}
|
|
3931
4126
|
return result;
|
|
3932
4127
|
}
|
|
@@ -4032,6 +4227,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
|
|
|
4032
4227
|
}
|
|
4033
4228
|
});
|
|
4034
4229
|
}
|
|
4230
|
+
async bulkLoad(entries) {
|
|
4231
|
+
return this.writeLock(1, async () => {
|
|
4232
|
+
const tx = await this.createTransaction();
|
|
4233
|
+
await tx.bulkLoad(entries);
|
|
4234
|
+
const result = await tx.commit();
|
|
4235
|
+
if (!result.success) {
|
|
4236
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
4237
|
+
}
|
|
4238
|
+
});
|
|
4239
|
+
}
|
|
4035
4240
|
};
|
|
4036
4241
|
|
|
4037
4242
|
// src/base/SerializeStrategy.ts
|
package/dist/esm/index.mjs
CHANGED
|
@@ -377,11 +377,7 @@ var MVCCTransaction = class {
|
|
|
377
377
|
*/
|
|
378
378
|
rollback() {
|
|
379
379
|
const { created, updated, deleted } = this.getResultEntries();
|
|
380
|
-
this.
|
|
381
|
-
this.deleteBuffer.clear();
|
|
382
|
-
this.createdKeys.clear();
|
|
383
|
-
this.deletedValues.clear();
|
|
384
|
-
this.originallyExisted.clear();
|
|
380
|
+
this._cleanupAll();
|
|
385
381
|
this.committed = true;
|
|
386
382
|
if (this.root !== this) {
|
|
387
383
|
this.root.activeTransactions.delete(this);
|
|
@@ -417,6 +413,19 @@ var MVCCTransaction = class {
|
|
|
417
413
|
}
|
|
418
414
|
return Array.from(conflicts);
|
|
419
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Cleans up all buffers and history.
|
|
418
|
+
* This method is called by the commit method.
|
|
419
|
+
*/
|
|
420
|
+
_cleanupAll() {
|
|
421
|
+
this.writeBuffer.clear();
|
|
422
|
+
this.deleteBuffer.clear();
|
|
423
|
+
this.createdKeys.clear();
|
|
424
|
+
this.deletedValues.clear();
|
|
425
|
+
this.originallyExisted.clear();
|
|
426
|
+
this.keyVersions.clear();
|
|
427
|
+
this.bufferHistory.clear();
|
|
428
|
+
}
|
|
420
429
|
/**
|
|
421
430
|
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
422
431
|
* Root transactions call this after commit to reclaim memory.
|
|
@@ -608,6 +617,7 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
608
617
|
if (this.parent) {
|
|
609
618
|
const failure = this.parent._merge(this);
|
|
610
619
|
if (failure) {
|
|
620
|
+
this.rollback();
|
|
611
621
|
return {
|
|
612
622
|
label,
|
|
613
623
|
success: false,
|
|
@@ -618,11 +628,13 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
618
628
|
deleted
|
|
619
629
|
};
|
|
620
630
|
}
|
|
631
|
+
this._cleanupAll();
|
|
621
632
|
this.committed = true;
|
|
622
633
|
} else {
|
|
623
634
|
if (this.writeBuffer.size > 0 || this.deleteBuffer.size > 0) {
|
|
624
635
|
const failure = this._merge(this);
|
|
625
636
|
if (failure) {
|
|
637
|
+
this.rollback();
|
|
626
638
|
return {
|
|
627
639
|
label,
|
|
628
640
|
success: false,
|
|
@@ -633,13 +645,7 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
633
645
|
deleted: []
|
|
634
646
|
};
|
|
635
647
|
}
|
|
636
|
-
this.
|
|
637
|
-
this.deleteBuffer.clear();
|
|
638
|
-
this.createdKeys.clear();
|
|
639
|
-
this.deletedValues.clear();
|
|
640
|
-
this.originallyExisted.clear();
|
|
641
|
-
this.keyVersions.clear();
|
|
642
|
-
this.bufferHistory.clear();
|
|
648
|
+
this._cleanupAll();
|
|
643
649
|
this.localVersion = 0;
|
|
644
650
|
this.snapshotVersion = this.version;
|
|
645
651
|
}
|
|
@@ -1273,6 +1279,7 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1273
1279
|
if (this.parent) {
|
|
1274
1280
|
const failure = await this.parent._merge(this);
|
|
1275
1281
|
if (failure) {
|
|
1282
|
+
this.rollback();
|
|
1276
1283
|
return {
|
|
1277
1284
|
label,
|
|
1278
1285
|
success: false,
|
|
@@ -1283,11 +1290,13 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1283
1290
|
deleted
|
|
1284
1291
|
};
|
|
1285
1292
|
}
|
|
1293
|
+
this._cleanupAll();
|
|
1286
1294
|
this.committed = true;
|
|
1287
1295
|
} else {
|
|
1288
1296
|
if (this.writeBuffer.size > 0 || this.deleteBuffer.size > 0) {
|
|
1289
1297
|
const failure = await this._merge(this);
|
|
1290
1298
|
if (failure) {
|
|
1299
|
+
this.rollback();
|
|
1291
1300
|
return {
|
|
1292
1301
|
label,
|
|
1293
1302
|
success: false,
|
|
@@ -1298,13 +1307,7 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1298
1307
|
deleted: []
|
|
1299
1308
|
};
|
|
1300
1309
|
}
|
|
1301
|
-
this.
|
|
1302
|
-
this.deleteBuffer.clear();
|
|
1303
|
-
this.createdKeys.clear();
|
|
1304
|
-
this.deletedValues.clear();
|
|
1305
|
-
this.originallyExisted.clear();
|
|
1306
|
-
this.keyVersions.clear();
|
|
1307
|
-
this.bufferHistory.clear();
|
|
1310
|
+
this._cleanupAll();
|
|
1308
1311
|
this.localVersion = 0;
|
|
1309
1312
|
this.snapshotVersion = this.version;
|
|
1310
1313
|
}
|
|
@@ -1888,30 +1891,22 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1888
1891
|
*/
|
|
1889
1892
|
_insertValueIntoLeaf(leaf, key, value) {
|
|
1890
1893
|
if (leaf.values.length) {
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
if (
|
|
1894
|
-
|
|
1895
|
-
return false;
|
|
1896
|
-
}
|
|
1897
|
-
leaf.keys[i].push(key);
|
|
1898
|
-
return true;
|
|
1899
|
-
} else if (this.comparator.isLower(value, nValue)) {
|
|
1900
|
-
leaf.values.splice(i, 0, value);
|
|
1901
|
-
leaf.keys.splice(i, 0, [key]);
|
|
1902
|
-
return true;
|
|
1903
|
-
} else if (i + 1 === leaf.values.length) {
|
|
1904
|
-
leaf.values.push(value);
|
|
1905
|
-
leaf.keys.push([key]);
|
|
1906
|
-
return true;
|
|
1894
|
+
const { index, found } = this._binarySearchValues(leaf.values, value);
|
|
1895
|
+
if (found) {
|
|
1896
|
+
if (leaf.keys[index].includes(key)) {
|
|
1897
|
+
return false;
|
|
1907
1898
|
}
|
|
1899
|
+
leaf.keys[index].push(key);
|
|
1900
|
+
return true;
|
|
1908
1901
|
}
|
|
1902
|
+
leaf.values.splice(index, 0, value);
|
|
1903
|
+
leaf.keys.splice(index, 0, [key]);
|
|
1904
|
+
return true;
|
|
1909
1905
|
} else {
|
|
1910
1906
|
leaf.values = [value];
|
|
1911
1907
|
leaf.keys = [[key]];
|
|
1912
1908
|
return true;
|
|
1913
1909
|
}
|
|
1914
|
-
return false;
|
|
1915
1910
|
}
|
|
1916
1911
|
_cloneNode(node) {
|
|
1917
1912
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -2204,12 +2199,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2204
2199
|
const midValue = parentNode.values[mid];
|
|
2205
2200
|
parentNode.values = parentNode.values.slice(0, mid);
|
|
2206
2201
|
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
2207
|
-
for (
|
|
2208
|
-
const
|
|
2209
|
-
n.parent = parentNode.id;
|
|
2210
|
-
this._updateNode(n);
|
|
2211
|
-
}
|
|
2212
|
-
for (const k of newSiblingNodeRecursive.keys) {
|
|
2202
|
+
for (let i = 0, len = newSiblingNodeRecursive.keys.length; i < len; i++) {
|
|
2203
|
+
const k = newSiblingNodeRecursive.keys[i];
|
|
2213
2204
|
const n = this._cloneNode(this.getNode(k));
|
|
2214
2205
|
n.parent = newSiblingNodeRecursive.id;
|
|
2215
2206
|
this._updateNode(n);
|
|
@@ -2291,7 +2282,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2291
2282
|
for (let i = 0; i < len; i++) {
|
|
2292
2283
|
const nValue = node.values[i];
|
|
2293
2284
|
const keys = node.keys[i];
|
|
2294
|
-
for (let j = 0,
|
|
2285
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
2295
2286
|
yield [keys[j], nValue];
|
|
2296
2287
|
}
|
|
2297
2288
|
}
|
|
@@ -2370,7 +2361,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2370
2361
|
while (true) {
|
|
2371
2362
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2372
2363
|
const keys = node.keys[i];
|
|
2373
|
-
for (let j = 0,
|
|
2364
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
2374
2365
|
if (keys[j] === key) {
|
|
2375
2366
|
return node.values[i];
|
|
2376
2367
|
}
|
|
@@ -2479,8 +2470,16 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2479
2470
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2480
2471
|
let currentLeaf = null;
|
|
2481
2472
|
let modified = false;
|
|
2482
|
-
|
|
2483
|
-
|
|
2473
|
+
let cachedLeafId = null;
|
|
2474
|
+
let cachedLeafMaxValue = null;
|
|
2475
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
2476
|
+
const [key, value] = sorted[i];
|
|
2477
|
+
let targetLeaf;
|
|
2478
|
+
if (cachedLeafId !== null && cachedLeafMaxValue !== null && currentLeaf !== null && (this.comparator.isLower(value, cachedLeafMaxValue) || this.comparator.isSame(value, cachedLeafMaxValue))) {
|
|
2479
|
+
targetLeaf = currentLeaf;
|
|
2480
|
+
} else {
|
|
2481
|
+
targetLeaf = this.locateLeaf(value);
|
|
2482
|
+
}
|
|
2484
2483
|
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
2485
2484
|
} else {
|
|
2486
2485
|
if (currentLeaf !== null && modified) {
|
|
@@ -2489,8 +2488,10 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2489
2488
|
currentLeaf = this._cloneNode(targetLeaf);
|
|
2490
2489
|
modified = false;
|
|
2491
2490
|
}
|
|
2491
|
+
cachedLeafId = currentLeaf.id;
|
|
2492
2492
|
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
2493
2493
|
modified = modified || changed;
|
|
2494
|
+
cachedLeafMaxValue = currentLeaf.values[currentLeaf.values.length - 1];
|
|
2494
2495
|
if (currentLeaf.values.length === this.order) {
|
|
2495
2496
|
this._updateNode(currentLeaf);
|
|
2496
2497
|
let after = this._createNode(
|
|
@@ -2511,6 +2512,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2511
2512
|
this._updateNode(after);
|
|
2512
2513
|
this._insertInParent(currentLeaf, after.values[0], after);
|
|
2513
2514
|
currentLeaf = null;
|
|
2515
|
+
cachedLeafId = null;
|
|
2516
|
+
cachedLeafMaxValue = null;
|
|
2514
2517
|
modified = false;
|
|
2515
2518
|
}
|
|
2516
2519
|
}
|
|
@@ -2518,6 +2521,85 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2518
2521
|
this._updateNode(currentLeaf);
|
|
2519
2522
|
}
|
|
2520
2523
|
}
|
|
2524
|
+
bulkLoad(entries) {
|
|
2525
|
+
if (entries.length === 0) return;
|
|
2526
|
+
const root = this.getNode(this.rootId);
|
|
2527
|
+
if (!root.leaf || root.values.length > 0) {
|
|
2528
|
+
throw new Error("bulkLoad can only be called on an empty tree. Use batchInsert for non-empty trees.");
|
|
2529
|
+
}
|
|
2530
|
+
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2531
|
+
const grouped = [];
|
|
2532
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
2533
|
+
const [key, value] = sorted[i];
|
|
2534
|
+
const last = grouped[grouped.length - 1];
|
|
2535
|
+
if (last && this.comparator.isSame(last.value, value)) {
|
|
2536
|
+
if (!last.keys.includes(key)) {
|
|
2537
|
+
last.keys.push(key);
|
|
2538
|
+
}
|
|
2539
|
+
} else {
|
|
2540
|
+
grouped.push({ keys: [key], value });
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
this._deleteNode(root);
|
|
2544
|
+
const maxLeafSize = this.order - 1;
|
|
2545
|
+
const leaves = [];
|
|
2546
|
+
for (let i = 0, len = grouped.length; i < len; i += maxLeafSize) {
|
|
2547
|
+
const chunk = grouped.slice(i, i + maxLeafSize);
|
|
2548
|
+
const leafKeys = chunk.map((g) => g.keys);
|
|
2549
|
+
const leafValues = chunk.map((g) => g.value);
|
|
2550
|
+
const leaf = this._createNode(
|
|
2551
|
+
true,
|
|
2552
|
+
leafKeys,
|
|
2553
|
+
leafValues,
|
|
2554
|
+
null,
|
|
2555
|
+
null,
|
|
2556
|
+
null
|
|
2557
|
+
);
|
|
2558
|
+
leaves.push(leaf);
|
|
2559
|
+
}
|
|
2560
|
+
for (let i = 0, len = leaves.length; i < len; i++) {
|
|
2561
|
+
if (i > 0) {
|
|
2562
|
+
leaves[i].prev = leaves[i - 1].id;
|
|
2563
|
+
}
|
|
2564
|
+
if (i < len - 1) {
|
|
2565
|
+
leaves[i].next = leaves[i + 1].id;
|
|
2566
|
+
}
|
|
2567
|
+
this._updateNode(leaves[i]);
|
|
2568
|
+
}
|
|
2569
|
+
let currentLevel = leaves;
|
|
2570
|
+
while (currentLevel.length > 1) {
|
|
2571
|
+
const nextLevel = [];
|
|
2572
|
+
for (let i = 0, len = currentLevel.length; i < len; i += this.order) {
|
|
2573
|
+
const children = currentLevel.slice(i, i + this.order);
|
|
2574
|
+
const childIds = children.map((c) => c.id);
|
|
2575
|
+
const separators = [];
|
|
2576
|
+
for (let j = 1, len2 = children.length; j < len2; j++) {
|
|
2577
|
+
separators.push(children[j].values[0]);
|
|
2578
|
+
}
|
|
2579
|
+
const internalNode = this._createNode(
|
|
2580
|
+
false,
|
|
2581
|
+
childIds,
|
|
2582
|
+
separators,
|
|
2583
|
+
null,
|
|
2584
|
+
null,
|
|
2585
|
+
null
|
|
2586
|
+
);
|
|
2587
|
+
for (let j = 0, len2 = children.length; j < len2; j++) {
|
|
2588
|
+
const child = children[j];
|
|
2589
|
+
child.parent = internalNode.id;
|
|
2590
|
+
this._updateNode(child);
|
|
2591
|
+
}
|
|
2592
|
+
nextLevel.push(internalNode);
|
|
2593
|
+
}
|
|
2594
|
+
currentLevel = nextLevel;
|
|
2595
|
+
}
|
|
2596
|
+
const newRoot = currentLevel[0];
|
|
2597
|
+
this._writeHead({
|
|
2598
|
+
root: newRoot.id,
|
|
2599
|
+
order: this.order,
|
|
2600
|
+
data: this.strategy.head.data
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2521
2603
|
_deleteEntry(node, key) {
|
|
2522
2604
|
if (!node.leaf) {
|
|
2523
2605
|
let keyIndex = -1;
|
|
@@ -2621,7 +2703,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2621
2703
|
siblingNode.values.push(...node.values);
|
|
2622
2704
|
if (!siblingNode.leaf) {
|
|
2623
2705
|
const keys = siblingNode.keys;
|
|
2624
|
-
for (
|
|
2706
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2707
|
+
const key2 = keys[i];
|
|
2625
2708
|
const node2 = this._cloneNode(this.getNode(key2));
|
|
2626
2709
|
node2.parent = siblingNode.id;
|
|
2627
2710
|
this._updateNode(node2);
|
|
@@ -2689,21 +2772,24 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2689
2772
|
this._updateNode(siblingNode);
|
|
2690
2773
|
}
|
|
2691
2774
|
if (!siblingNode.leaf) {
|
|
2692
|
-
for (
|
|
2775
|
+
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
2776
|
+
const key2 = siblingNode.keys[i];
|
|
2693
2777
|
const n = this._cloneNode(this.getNode(key2));
|
|
2694
2778
|
n.parent = siblingNode.id;
|
|
2695
2779
|
this._updateNode(n);
|
|
2696
2780
|
}
|
|
2697
2781
|
}
|
|
2698
2782
|
if (!node.leaf) {
|
|
2699
|
-
for (
|
|
2783
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
2784
|
+
const key2 = node.keys[i];
|
|
2700
2785
|
const n = this._cloneNode(this.getNode(key2));
|
|
2701
2786
|
n.parent = node.id;
|
|
2702
2787
|
this._updateNode(n);
|
|
2703
2788
|
}
|
|
2704
2789
|
}
|
|
2705
2790
|
if (!parentNode.leaf) {
|
|
2706
|
-
for (
|
|
2791
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
2792
|
+
const key2 = parentNode.keys[i];
|
|
2707
2793
|
const n = this._cloneNode(this.getNode(key2));
|
|
2708
2794
|
n.parent = parentNode.id;
|
|
2709
2795
|
this._updateNode(n);
|
|
@@ -2780,8 +2866,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2780
2866
|
result = this.rootTx.commit(label);
|
|
2781
2867
|
if (result.success) {
|
|
2782
2868
|
this.rootTx.rootId = this.rootId;
|
|
2869
|
+
} else {
|
|
2870
|
+
this.mvcc.rollback();
|
|
2783
2871
|
}
|
|
2784
2872
|
}
|
|
2873
|
+
} else {
|
|
2874
|
+
this.mvcc.rollback();
|
|
2785
2875
|
}
|
|
2786
2876
|
return result;
|
|
2787
2877
|
}
|
|
@@ -2881,6 +2971,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
|
|
|
2881
2971
|
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
2882
2972
|
}
|
|
2883
2973
|
}
|
|
2974
|
+
bulkLoad(entries) {
|
|
2975
|
+
const tx = this.createTransaction();
|
|
2976
|
+
tx.bulkLoad(entries);
|
|
2977
|
+
const result = tx.commit();
|
|
2978
|
+
if (!result.success) {
|
|
2979
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2884
2982
|
};
|
|
2885
2983
|
|
|
2886
2984
|
// node_modules/ryoiki/dist/esm/index.mjs
|
|
@@ -3298,12 +3396,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3298
3396
|
const midValue = parentNode.values[mid];
|
|
3299
3397
|
parentNode.values = parentNode.values.slice(0, mid);
|
|
3300
3398
|
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
3301
|
-
for (
|
|
3302
|
-
const
|
|
3303
|
-
n.parent = parentNode.id;
|
|
3304
|
-
await this._updateNode(n);
|
|
3305
|
-
}
|
|
3306
|
-
for (const k of newSiblingNodeRecursive.keys) {
|
|
3399
|
+
for (let i = 0, len = newSiblingNodeRecursive.keys.length; i < len; i++) {
|
|
3400
|
+
const k = newSiblingNodeRecursive.keys[i];
|
|
3307
3401
|
const n = this._cloneNode(await this.getNode(k));
|
|
3308
3402
|
n.parent = newSiblingNodeRecursive.id;
|
|
3309
3403
|
await this._updateNode(n);
|
|
@@ -3395,7 +3489,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3395
3489
|
for (let i = 0; i < len; i++) {
|
|
3396
3490
|
const nValue = node.values[i];
|
|
3397
3491
|
const keys = node.keys[i];
|
|
3398
|
-
for (let j = 0,
|
|
3492
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
3399
3493
|
yield [keys[j], nValue];
|
|
3400
3494
|
}
|
|
3401
3495
|
}
|
|
@@ -3473,7 +3567,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3473
3567
|
while (true) {
|
|
3474
3568
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
3475
3569
|
const keys = node.keys[i];
|
|
3476
|
-
for (let j = 0,
|
|
3570
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
3477
3571
|
if (keys[j] === key) {
|
|
3478
3572
|
return node.values[i];
|
|
3479
3573
|
}
|
|
@@ -3585,8 +3679,16 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3585
3679
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3586
3680
|
let currentLeaf = null;
|
|
3587
3681
|
let modified = false;
|
|
3588
|
-
|
|
3589
|
-
|
|
3682
|
+
let cachedLeafId = null;
|
|
3683
|
+
let cachedLeafMaxValue = null;
|
|
3684
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
3685
|
+
const [key, value] = sorted[i];
|
|
3686
|
+
let targetLeaf;
|
|
3687
|
+
if (cachedLeafId !== null && cachedLeafMaxValue !== null && currentLeaf !== null && (this.comparator.isLower(value, cachedLeafMaxValue) || this.comparator.isSame(value, cachedLeafMaxValue))) {
|
|
3688
|
+
targetLeaf = currentLeaf;
|
|
3689
|
+
} else {
|
|
3690
|
+
targetLeaf = await this.locateLeaf(value);
|
|
3691
|
+
}
|
|
3590
3692
|
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
3591
3693
|
} else {
|
|
3592
3694
|
if (currentLeaf !== null && modified) {
|
|
@@ -3595,8 +3697,10 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3595
3697
|
currentLeaf = this._cloneNode(targetLeaf);
|
|
3596
3698
|
modified = false;
|
|
3597
3699
|
}
|
|
3700
|
+
cachedLeafId = currentLeaf.id;
|
|
3598
3701
|
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
3599
3702
|
modified = modified || changed;
|
|
3703
|
+
cachedLeafMaxValue = currentLeaf.values[currentLeaf.values.length - 1];
|
|
3600
3704
|
if (currentLeaf.values.length === this.order) {
|
|
3601
3705
|
await this._updateNode(currentLeaf);
|
|
3602
3706
|
let after = await this._createNode(
|
|
@@ -3617,6 +3721,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3617
3721
|
await this._updateNode(after);
|
|
3618
3722
|
await this._insertInParent(currentLeaf, after.values[0], after);
|
|
3619
3723
|
currentLeaf = null;
|
|
3724
|
+
cachedLeafId = null;
|
|
3725
|
+
cachedLeafMaxValue = null;
|
|
3620
3726
|
modified = false;
|
|
3621
3727
|
}
|
|
3622
3728
|
}
|
|
@@ -3625,6 +3731,87 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3625
3731
|
}
|
|
3626
3732
|
});
|
|
3627
3733
|
}
|
|
3734
|
+
async bulkLoad(entries) {
|
|
3735
|
+
if (entries.length === 0) return;
|
|
3736
|
+
return this.writeLock(0, async () => {
|
|
3737
|
+
const root = await this.getNode(this.rootId);
|
|
3738
|
+
if (!root.leaf || root.values.length > 0) {
|
|
3739
|
+
throw new Error("bulkLoad can only be called on an empty tree. Use batchInsert for non-empty trees.");
|
|
3740
|
+
}
|
|
3741
|
+
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3742
|
+
const grouped = [];
|
|
3743
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
3744
|
+
const [key, value] = sorted[i];
|
|
3745
|
+
const last = grouped[grouped.length - 1];
|
|
3746
|
+
if (last && this.comparator.isSame(last.value, value)) {
|
|
3747
|
+
if (!last.keys.includes(key)) {
|
|
3748
|
+
last.keys.push(key);
|
|
3749
|
+
}
|
|
3750
|
+
} else {
|
|
3751
|
+
grouped.push({ keys: [key], value });
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
await this._deleteNode(root);
|
|
3755
|
+
const maxLeafSize = this.order - 1;
|
|
3756
|
+
const leaves = [];
|
|
3757
|
+
for (let i = 0, len = grouped.length; i < len; i += maxLeafSize) {
|
|
3758
|
+
const chunk = grouped.slice(i, i + maxLeafSize);
|
|
3759
|
+
const leafKeys = chunk.map((g) => g.keys);
|
|
3760
|
+
const leafValues = chunk.map((g) => g.value);
|
|
3761
|
+
const leaf = await this._createNode(
|
|
3762
|
+
true,
|
|
3763
|
+
leafKeys,
|
|
3764
|
+
leafValues,
|
|
3765
|
+
null,
|
|
3766
|
+
null,
|
|
3767
|
+
null
|
|
3768
|
+
);
|
|
3769
|
+
leaves.push(leaf);
|
|
3770
|
+
}
|
|
3771
|
+
for (let i = 0, len = leaves.length; i < len; i++) {
|
|
3772
|
+
if (i > 0) {
|
|
3773
|
+
leaves[i].prev = leaves[i - 1].id;
|
|
3774
|
+
}
|
|
3775
|
+
if (i < len - 1) {
|
|
3776
|
+
leaves[i].next = leaves[i + 1].id;
|
|
3777
|
+
}
|
|
3778
|
+
await this._updateNode(leaves[i]);
|
|
3779
|
+
}
|
|
3780
|
+
let currentLevel = leaves;
|
|
3781
|
+
while (currentLevel.length > 1) {
|
|
3782
|
+
const nextLevel = [];
|
|
3783
|
+
for (let i = 0, len = currentLevel.length; i < len; i += this.order) {
|
|
3784
|
+
const children = currentLevel.slice(i, i + this.order);
|
|
3785
|
+
const childIds = children.map((c) => c.id);
|
|
3786
|
+
const separators = [];
|
|
3787
|
+
for (let j = 1, len2 = children.length; j < len2; j++) {
|
|
3788
|
+
separators.push(children[j].values[0]);
|
|
3789
|
+
}
|
|
3790
|
+
const internalNode = await this._createNode(
|
|
3791
|
+
false,
|
|
3792
|
+
childIds,
|
|
3793
|
+
separators,
|
|
3794
|
+
null,
|
|
3795
|
+
null,
|
|
3796
|
+
null
|
|
3797
|
+
);
|
|
3798
|
+
for (let j = 0, len2 = children.length; j < len2; j++) {
|
|
3799
|
+
const child = children[j];
|
|
3800
|
+
child.parent = internalNode.id;
|
|
3801
|
+
await this._updateNode(child);
|
|
3802
|
+
}
|
|
3803
|
+
nextLevel.push(internalNode);
|
|
3804
|
+
}
|
|
3805
|
+
currentLevel = nextLevel;
|
|
3806
|
+
}
|
|
3807
|
+
const newRoot = currentLevel[0];
|
|
3808
|
+
await this._writeHead({
|
|
3809
|
+
root: newRoot.id,
|
|
3810
|
+
order: this.order,
|
|
3811
|
+
data: this.strategy.head.data
|
|
3812
|
+
});
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3628
3815
|
async _deleteEntry(node, key) {
|
|
3629
3816
|
if (!node.leaf) {
|
|
3630
3817
|
let keyIndex = -1;
|
|
@@ -3728,7 +3915,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3728
3915
|
siblingNode.values.push(...node.values);
|
|
3729
3916
|
if (!siblingNode.leaf) {
|
|
3730
3917
|
const keys = siblingNode.keys;
|
|
3731
|
-
for (
|
|
3918
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3919
|
+
const key2 = keys[i];
|
|
3732
3920
|
const node2 = this._cloneNode(await this.getNode(key2));
|
|
3733
3921
|
node2.parent = siblingNode.id;
|
|
3734
3922
|
await this._updateNode(node2);
|
|
@@ -3796,21 +3984,24 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3796
3984
|
await this._updateNode(siblingNode);
|
|
3797
3985
|
}
|
|
3798
3986
|
if (!siblingNode.leaf) {
|
|
3799
|
-
for (
|
|
3987
|
+
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
3988
|
+
const key2 = siblingNode.keys[i];
|
|
3800
3989
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3801
3990
|
n.parent = siblingNode.id;
|
|
3802
3991
|
await this._updateNode(n);
|
|
3803
3992
|
}
|
|
3804
3993
|
}
|
|
3805
3994
|
if (!node.leaf) {
|
|
3806
|
-
for (
|
|
3995
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
3996
|
+
const key2 = node.keys[i];
|
|
3807
3997
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3808
3998
|
n.parent = node.id;
|
|
3809
3999
|
await this._updateNode(n);
|
|
3810
4000
|
}
|
|
3811
4001
|
}
|
|
3812
4002
|
if (!parentNode.leaf) {
|
|
3813
|
-
for (
|
|
4003
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
4004
|
+
const key2 = parentNode.keys[i];
|
|
3814
4005
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3815
4006
|
n.parent = parentNode.id;
|
|
3816
4007
|
await this._updateNode(n);
|
|
@@ -3889,8 +4080,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3889
4080
|
result = await this.rootTx.commit(label);
|
|
3890
4081
|
if (result.success) {
|
|
3891
4082
|
this.rootTx.rootId = this.rootId;
|
|
4083
|
+
} else {
|
|
4084
|
+
this.mvcc.rollback();
|
|
3892
4085
|
}
|
|
3893
4086
|
}
|
|
4087
|
+
} else {
|
|
4088
|
+
this.mvcc.rollback();
|
|
3894
4089
|
}
|
|
3895
4090
|
return result;
|
|
3896
4091
|
}
|
|
@@ -3996,6 +4191,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
|
|
|
3996
4191
|
}
|
|
3997
4192
|
});
|
|
3998
4193
|
}
|
|
4194
|
+
async bulkLoad(entries) {
|
|
4195
|
+
return this.writeLock(1, async () => {
|
|
4196
|
+
const tx = await this.createTransaction();
|
|
4197
|
+
await tx.bulkLoad(entries);
|
|
4198
|
+
const result = await tx.commit();
|
|
4199
|
+
if (!result.success) {
|
|
4200
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
4201
|
+
}
|
|
4202
|
+
});
|
|
4203
|
+
}
|
|
3999
4204
|
};
|
|
4000
4205
|
|
|
4001
4206
|
// src/base/SerializeStrategy.ts
|
|
@@ -12,4 +12,5 @@ export declare class BPTreeAsync<K, V> extends BPTreeAsyncTransaction<K, V> {
|
|
|
12
12
|
insert(key: K, value: V): Promise<void>;
|
|
13
13
|
delete(key: K, value?: V): Promise<void>;
|
|
14
14
|
batchInsert(entries: [K, V][]): Promise<void>;
|
|
15
|
+
bulkLoad(entries: [K, V][]): Promise<void>;
|
|
15
16
|
}
|
|
@@ -173,6 +173,18 @@ export declare abstract class BPTreeTransaction<K, V> {
|
|
|
173
173
|
* @param entries Array of [key, value] pairs to insert.
|
|
174
174
|
*/
|
|
175
175
|
abstract batchInsert(entries: [K, V][]): Deferred<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Builds a B+Tree from scratch using bulk loading (bottom-up construction).
|
|
178
|
+
* This is significantly faster than batchInsert for initial tree construction,
|
|
179
|
+
* as it avoids top-down traversal and creates nodes directly.
|
|
180
|
+
*
|
|
181
|
+
* **Precondition**: The tree must be empty. If the tree already contains data,
|
|
182
|
+
* an error will be thrown. Use batchInsert for adding data to an existing tree.
|
|
183
|
+
*
|
|
184
|
+
* @param entries Array of [key, value] pairs to bulk load.
|
|
185
|
+
* @throws Error if the tree is not empty.
|
|
186
|
+
*/
|
|
187
|
+
abstract bulkLoad(entries: [K, V][]): Deferred<void>;
|
|
176
188
|
/**
|
|
177
189
|
* Deletes the pair that matches the key and value.
|
|
178
190
|
* @param key The key of the pair. This key must be unique.
|
|
@@ -42,6 +42,7 @@ export declare class BPTreeAsyncTransaction<K, V> extends BPTreeTransaction<K, V
|
|
|
42
42
|
where(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): Promise<BPTreePair<K, V>>;
|
|
43
43
|
insert(key: K, value: V): Promise<void>;
|
|
44
44
|
batchInsert(entries: [K, V][]): Promise<void>;
|
|
45
|
+
bulkLoad(entries: [K, V][]): Promise<void>;
|
|
45
46
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): Promise<BPTreeUnknownNode<K, V>>;
|
|
46
47
|
delete(key: K, value?: V): Promise<void>;
|
|
47
48
|
getHeadData(): Promise<SerializableData>;
|
|
@@ -39,6 +39,7 @@ export declare class BPTreeSyncTransaction<K, V> extends BPTreeTransaction<K, V>
|
|
|
39
39
|
where(condition: BPTreeCondition<V>, options?: BPTreeSearchOption<K>): BPTreePair<K, V>;
|
|
40
40
|
insert(key: K, value: V): void;
|
|
41
41
|
batchInsert(entries: [K, V][]): void;
|
|
42
|
+
bulkLoad(entries: [K, V][]): void;
|
|
42
43
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): BPTreeUnknownNode<K, V>;
|
|
43
44
|
delete(key: K, value?: V): void;
|
|
44
45
|
getHeadData(): SerializableData;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serializable-bptree",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.4.1",
|
|
4
4
|
"description": "Store the B+tree flexibly, not only in-memory.",
|
|
5
5
|
"types": "./dist/types/index.d.ts",
|
|
6
6
|
"main": "./dist/cjs/index.cjs",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"typescript": "^5.9.3"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"mvcc-api": "^1.3.
|
|
47
|
+
"mvcc-api": "^1.3.6",
|
|
48
48
|
"ryoiki": "^1.2.0"
|
|
49
49
|
}
|
|
50
50
|
}
|