dataply 0.0.26-alpha.0 → 0.0.26-alpha.2
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/dist/cjs/index.js
CHANGED
|
@@ -1954,30 +1954,22 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1954
1954
|
*/
|
|
1955
1955
|
_insertValueIntoLeaf(leaf, key, value) {
|
|
1956
1956
|
if (leaf.values.length) {
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
if (
|
|
1960
|
-
|
|
1961
|
-
return false;
|
|
1962
|
-
}
|
|
1963
|
-
leaf.keys[i].push(key);
|
|
1964
|
-
return true;
|
|
1965
|
-
} else if (this.comparator.isLower(value, nValue)) {
|
|
1966
|
-
leaf.values.splice(i, 0, value);
|
|
1967
|
-
leaf.keys.splice(i, 0, [key]);
|
|
1968
|
-
return true;
|
|
1969
|
-
} else if (i + 1 === leaf.values.length) {
|
|
1970
|
-
leaf.values.push(value);
|
|
1971
|
-
leaf.keys.push([key]);
|
|
1972
|
-
return true;
|
|
1957
|
+
const { index, found } = this._binarySearchValues(leaf.values, value);
|
|
1958
|
+
if (found) {
|
|
1959
|
+
if (leaf.keys[index].includes(key)) {
|
|
1960
|
+
return false;
|
|
1973
1961
|
}
|
|
1962
|
+
leaf.keys[index].push(key);
|
|
1963
|
+
return true;
|
|
1974
1964
|
}
|
|
1965
|
+
leaf.values.splice(index, 0, value);
|
|
1966
|
+
leaf.keys.splice(index, 0, [key]);
|
|
1967
|
+
return true;
|
|
1975
1968
|
} else {
|
|
1976
1969
|
leaf.values = [value];
|
|
1977
1970
|
leaf.keys = [[key]];
|
|
1978
1971
|
return true;
|
|
1979
1972
|
}
|
|
1980
|
-
return false;
|
|
1981
1973
|
}
|
|
1982
1974
|
_cloneNode(node) {
|
|
1983
1975
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -2268,12 +2260,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2268
2260
|
const midValue = parentNode.values[mid];
|
|
2269
2261
|
parentNode.values = parentNode.values.slice(0, mid);
|
|
2270
2262
|
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
2271
|
-
for (
|
|
2272
|
-
const
|
|
2273
|
-
n.parent = parentNode.id;
|
|
2274
|
-
this._updateNode(n);
|
|
2275
|
-
}
|
|
2276
|
-
for (const k of newSiblingNodeRecursive.keys) {
|
|
2263
|
+
for (let i = 0, len = newSiblingNodeRecursive.keys.length; i < len; i++) {
|
|
2264
|
+
const k = newSiblingNodeRecursive.keys[i];
|
|
2277
2265
|
const n = this._cloneNode(this.getNode(k));
|
|
2278
2266
|
n.parent = newSiblingNodeRecursive.id;
|
|
2279
2267
|
this._updateNode(n);
|
|
@@ -2355,7 +2343,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2355
2343
|
for (let i = 0; i < len; i++) {
|
|
2356
2344
|
const nValue = node.values[i];
|
|
2357
2345
|
const keys = node.keys[i];
|
|
2358
|
-
for (let j = 0,
|
|
2346
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
2359
2347
|
yield [keys[j], nValue];
|
|
2360
2348
|
}
|
|
2361
2349
|
}
|
|
@@ -2434,7 +2422,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2434
2422
|
while (true) {
|
|
2435
2423
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2436
2424
|
const keys = node.keys[i];
|
|
2437
|
-
for (let j = 0,
|
|
2425
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
2438
2426
|
if (keys[j] === key) {
|
|
2439
2427
|
return node.values[i];
|
|
2440
2428
|
}
|
|
@@ -2543,8 +2531,16 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2543
2531
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2544
2532
|
let currentLeaf = null;
|
|
2545
2533
|
let modified = false;
|
|
2546
|
-
|
|
2547
|
-
|
|
2534
|
+
let cachedLeafId = null;
|
|
2535
|
+
let cachedLeafMaxValue = null;
|
|
2536
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
2537
|
+
const [key, value] = sorted[i];
|
|
2538
|
+
let targetLeaf;
|
|
2539
|
+
if (cachedLeafId !== null && cachedLeafMaxValue !== null && currentLeaf !== null && (this.comparator.isLower(value, cachedLeafMaxValue) || this.comparator.isSame(value, cachedLeafMaxValue))) {
|
|
2540
|
+
targetLeaf = currentLeaf;
|
|
2541
|
+
} else {
|
|
2542
|
+
targetLeaf = this.locateLeaf(value);
|
|
2543
|
+
}
|
|
2548
2544
|
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
2549
2545
|
} else {
|
|
2550
2546
|
if (currentLeaf !== null && modified) {
|
|
@@ -2553,8 +2549,10 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2553
2549
|
currentLeaf = this._cloneNode(targetLeaf);
|
|
2554
2550
|
modified = false;
|
|
2555
2551
|
}
|
|
2552
|
+
cachedLeafId = currentLeaf.id;
|
|
2556
2553
|
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
2557
2554
|
modified = modified || changed;
|
|
2555
|
+
cachedLeafMaxValue = currentLeaf.values[currentLeaf.values.length - 1];
|
|
2558
2556
|
if (currentLeaf.values.length === this.order) {
|
|
2559
2557
|
this._updateNode(currentLeaf);
|
|
2560
2558
|
let after = this._createNode(
|
|
@@ -2575,6 +2573,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2575
2573
|
this._updateNode(after);
|
|
2576
2574
|
this._insertInParent(currentLeaf, after.values[0], after);
|
|
2577
2575
|
currentLeaf = null;
|
|
2576
|
+
cachedLeafId = null;
|
|
2577
|
+
cachedLeafMaxValue = null;
|
|
2578
2578
|
modified = false;
|
|
2579
2579
|
}
|
|
2580
2580
|
}
|
|
@@ -2582,6 +2582,85 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2582
2582
|
this._updateNode(currentLeaf);
|
|
2583
2583
|
}
|
|
2584
2584
|
}
|
|
2585
|
+
bulkLoad(entries) {
|
|
2586
|
+
if (entries.length === 0) return;
|
|
2587
|
+
const root = this.getNode(this.rootId);
|
|
2588
|
+
if (!root.leaf || root.values.length > 0) {
|
|
2589
|
+
throw new Error("bulkLoad can only be called on an empty tree. Use batchInsert for non-empty trees.");
|
|
2590
|
+
}
|
|
2591
|
+
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2592
|
+
const grouped = [];
|
|
2593
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
2594
|
+
const [key, value] = sorted[i];
|
|
2595
|
+
const last = grouped[grouped.length - 1];
|
|
2596
|
+
if (last && this.comparator.isSame(last.value, value)) {
|
|
2597
|
+
if (!last.keys.includes(key)) {
|
|
2598
|
+
last.keys.push(key);
|
|
2599
|
+
}
|
|
2600
|
+
} else {
|
|
2601
|
+
grouped.push({ keys: [key], value });
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
this._deleteNode(root);
|
|
2605
|
+
const maxLeafSize = this.order - 1;
|
|
2606
|
+
const leaves = [];
|
|
2607
|
+
for (let i = 0, len = grouped.length; i < len; i += maxLeafSize) {
|
|
2608
|
+
const chunk = grouped.slice(i, i + maxLeafSize);
|
|
2609
|
+
const leafKeys = chunk.map((g) => g.keys);
|
|
2610
|
+
const leafValues = chunk.map((g) => g.value);
|
|
2611
|
+
const leaf = this._createNode(
|
|
2612
|
+
true,
|
|
2613
|
+
leafKeys,
|
|
2614
|
+
leafValues,
|
|
2615
|
+
null,
|
|
2616
|
+
null,
|
|
2617
|
+
null
|
|
2618
|
+
);
|
|
2619
|
+
leaves.push(leaf);
|
|
2620
|
+
}
|
|
2621
|
+
for (let i = 0, len = leaves.length; i < len; i++) {
|
|
2622
|
+
if (i > 0) {
|
|
2623
|
+
leaves[i].prev = leaves[i - 1].id;
|
|
2624
|
+
}
|
|
2625
|
+
if (i < len - 1) {
|
|
2626
|
+
leaves[i].next = leaves[i + 1].id;
|
|
2627
|
+
}
|
|
2628
|
+
this._updateNode(leaves[i]);
|
|
2629
|
+
}
|
|
2630
|
+
let currentLevel = leaves;
|
|
2631
|
+
while (currentLevel.length > 1) {
|
|
2632
|
+
const nextLevel = [];
|
|
2633
|
+
for (let i = 0, len = currentLevel.length; i < len; i += this.order) {
|
|
2634
|
+
const children = currentLevel.slice(i, i + this.order);
|
|
2635
|
+
const childIds = children.map((c) => c.id);
|
|
2636
|
+
const separators = [];
|
|
2637
|
+
for (let j = 1, len2 = children.length; j < len2; j++) {
|
|
2638
|
+
separators.push(children[j].values[0]);
|
|
2639
|
+
}
|
|
2640
|
+
const internalNode = this._createNode(
|
|
2641
|
+
false,
|
|
2642
|
+
childIds,
|
|
2643
|
+
separators,
|
|
2644
|
+
null,
|
|
2645
|
+
null,
|
|
2646
|
+
null
|
|
2647
|
+
);
|
|
2648
|
+
for (let j = 0, len2 = children.length; j < len2; j++) {
|
|
2649
|
+
const child = children[j];
|
|
2650
|
+
child.parent = internalNode.id;
|
|
2651
|
+
this._updateNode(child);
|
|
2652
|
+
}
|
|
2653
|
+
nextLevel.push(internalNode);
|
|
2654
|
+
}
|
|
2655
|
+
currentLevel = nextLevel;
|
|
2656
|
+
}
|
|
2657
|
+
const newRoot = currentLevel[0];
|
|
2658
|
+
this._writeHead({
|
|
2659
|
+
root: newRoot.id,
|
|
2660
|
+
order: this.order,
|
|
2661
|
+
data: this.strategy.head.data
|
|
2662
|
+
});
|
|
2663
|
+
}
|
|
2585
2664
|
_deleteEntry(node, key) {
|
|
2586
2665
|
if (!node.leaf) {
|
|
2587
2666
|
let keyIndex = -1;
|
|
@@ -2685,7 +2764,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2685
2764
|
siblingNode.values.push(...node.values);
|
|
2686
2765
|
if (!siblingNode.leaf) {
|
|
2687
2766
|
const keys = siblingNode.keys;
|
|
2688
|
-
for (
|
|
2767
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2768
|
+
const key2 = keys[i];
|
|
2689
2769
|
const node2 = this._cloneNode(this.getNode(key2));
|
|
2690
2770
|
node2.parent = siblingNode.id;
|
|
2691
2771
|
this._updateNode(node2);
|
|
@@ -2753,21 +2833,24 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2753
2833
|
this._updateNode(siblingNode);
|
|
2754
2834
|
}
|
|
2755
2835
|
if (!siblingNode.leaf) {
|
|
2756
|
-
for (
|
|
2836
|
+
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
2837
|
+
const key2 = siblingNode.keys[i];
|
|
2757
2838
|
const n = this._cloneNode(this.getNode(key2));
|
|
2758
2839
|
n.parent = siblingNode.id;
|
|
2759
2840
|
this._updateNode(n);
|
|
2760
2841
|
}
|
|
2761
2842
|
}
|
|
2762
2843
|
if (!node.leaf) {
|
|
2763
|
-
for (
|
|
2844
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
2845
|
+
const key2 = node.keys[i];
|
|
2764
2846
|
const n = this._cloneNode(this.getNode(key2));
|
|
2765
2847
|
n.parent = node.id;
|
|
2766
2848
|
this._updateNode(n);
|
|
2767
2849
|
}
|
|
2768
2850
|
}
|
|
2769
2851
|
if (!parentNode.leaf) {
|
|
2770
|
-
for (
|
|
2852
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
2853
|
+
const key2 = parentNode.keys[i];
|
|
2771
2854
|
const n = this._cloneNode(this.getNode(key2));
|
|
2772
2855
|
n.parent = parentNode.id;
|
|
2773
2856
|
this._updateNode(n);
|
|
@@ -2941,6 +3024,14 @@ var BPTreeSync = class extends BPTreeSyncTransaction {
|
|
|
2941
3024
|
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
2942
3025
|
}
|
|
2943
3026
|
}
|
|
3027
|
+
bulkLoad(entries) {
|
|
3028
|
+
const tx = this.createTransaction();
|
|
3029
|
+
tx.bulkLoad(entries);
|
|
3030
|
+
const result = tx.commit();
|
|
3031
|
+
if (!result.success) {
|
|
3032
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
2944
3035
|
};
|
|
2945
3036
|
var Ryoiki2 = class _Ryoiki2 {
|
|
2946
3037
|
readings;
|
|
@@ -3354,12 +3445,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3354
3445
|
const midValue = parentNode.values[mid];
|
|
3355
3446
|
parentNode.values = parentNode.values.slice(0, mid);
|
|
3356
3447
|
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
3357
|
-
for (
|
|
3358
|
-
const
|
|
3359
|
-
n.parent = parentNode.id;
|
|
3360
|
-
await this._updateNode(n);
|
|
3361
|
-
}
|
|
3362
|
-
for (const k of newSiblingNodeRecursive.keys) {
|
|
3448
|
+
for (let i = 0, len = newSiblingNodeRecursive.keys.length; i < len; i++) {
|
|
3449
|
+
const k = newSiblingNodeRecursive.keys[i];
|
|
3363
3450
|
const n = this._cloneNode(await this.getNode(k));
|
|
3364
3451
|
n.parent = newSiblingNodeRecursive.id;
|
|
3365
3452
|
await this._updateNode(n);
|
|
@@ -3451,7 +3538,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3451
3538
|
for (let i = 0; i < len; i++) {
|
|
3452
3539
|
const nValue = node.values[i];
|
|
3453
3540
|
const keys = node.keys[i];
|
|
3454
|
-
for (let j = 0,
|
|
3541
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
3455
3542
|
yield [keys[j], nValue];
|
|
3456
3543
|
}
|
|
3457
3544
|
}
|
|
@@ -3529,7 +3616,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3529
3616
|
while (true) {
|
|
3530
3617
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
3531
3618
|
const keys = node.keys[i];
|
|
3532
|
-
for (let j = 0,
|
|
3619
|
+
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
3533
3620
|
if (keys[j] === key) {
|
|
3534
3621
|
return node.values[i];
|
|
3535
3622
|
}
|
|
@@ -3641,8 +3728,16 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3641
3728
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3642
3729
|
let currentLeaf = null;
|
|
3643
3730
|
let modified = false;
|
|
3644
|
-
|
|
3645
|
-
|
|
3731
|
+
let cachedLeafId = null;
|
|
3732
|
+
let cachedLeafMaxValue = null;
|
|
3733
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
3734
|
+
const [key, value] = sorted[i];
|
|
3735
|
+
let targetLeaf;
|
|
3736
|
+
if (cachedLeafId !== null && cachedLeafMaxValue !== null && currentLeaf !== null && (this.comparator.isLower(value, cachedLeafMaxValue) || this.comparator.isSame(value, cachedLeafMaxValue))) {
|
|
3737
|
+
targetLeaf = currentLeaf;
|
|
3738
|
+
} else {
|
|
3739
|
+
targetLeaf = await this.locateLeaf(value);
|
|
3740
|
+
}
|
|
3646
3741
|
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
3647
3742
|
} else {
|
|
3648
3743
|
if (currentLeaf !== null && modified) {
|
|
@@ -3651,8 +3746,10 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3651
3746
|
currentLeaf = this._cloneNode(targetLeaf);
|
|
3652
3747
|
modified = false;
|
|
3653
3748
|
}
|
|
3749
|
+
cachedLeafId = currentLeaf.id;
|
|
3654
3750
|
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
3655
3751
|
modified = modified || changed;
|
|
3752
|
+
cachedLeafMaxValue = currentLeaf.values[currentLeaf.values.length - 1];
|
|
3656
3753
|
if (currentLeaf.values.length === this.order) {
|
|
3657
3754
|
await this._updateNode(currentLeaf);
|
|
3658
3755
|
let after = await this._createNode(
|
|
@@ -3673,6 +3770,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3673
3770
|
await this._updateNode(after);
|
|
3674
3771
|
await this._insertInParent(currentLeaf, after.values[0], after);
|
|
3675
3772
|
currentLeaf = null;
|
|
3773
|
+
cachedLeafId = null;
|
|
3774
|
+
cachedLeafMaxValue = null;
|
|
3676
3775
|
modified = false;
|
|
3677
3776
|
}
|
|
3678
3777
|
}
|
|
@@ -3681,6 +3780,87 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3681
3780
|
}
|
|
3682
3781
|
});
|
|
3683
3782
|
}
|
|
3783
|
+
async bulkLoad(entries) {
|
|
3784
|
+
if (entries.length === 0) return;
|
|
3785
|
+
return this.writeLock(0, async () => {
|
|
3786
|
+
const root = await this.getNode(this.rootId);
|
|
3787
|
+
if (!root.leaf || root.values.length > 0) {
|
|
3788
|
+
throw new Error("bulkLoad can only be called on an empty tree. Use batchInsert for non-empty trees.");
|
|
3789
|
+
}
|
|
3790
|
+
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3791
|
+
const grouped = [];
|
|
3792
|
+
for (let i = 0, len = sorted.length; i < len; i++) {
|
|
3793
|
+
const [key, value] = sorted[i];
|
|
3794
|
+
const last = grouped[grouped.length - 1];
|
|
3795
|
+
if (last && this.comparator.isSame(last.value, value)) {
|
|
3796
|
+
if (!last.keys.includes(key)) {
|
|
3797
|
+
last.keys.push(key);
|
|
3798
|
+
}
|
|
3799
|
+
} else {
|
|
3800
|
+
grouped.push({ keys: [key], value });
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
await this._deleteNode(root);
|
|
3804
|
+
const maxLeafSize = this.order - 1;
|
|
3805
|
+
const leaves = [];
|
|
3806
|
+
for (let i = 0, len = grouped.length; i < len; i += maxLeafSize) {
|
|
3807
|
+
const chunk = grouped.slice(i, i + maxLeafSize);
|
|
3808
|
+
const leafKeys = chunk.map((g) => g.keys);
|
|
3809
|
+
const leafValues = chunk.map((g) => g.value);
|
|
3810
|
+
const leaf = await this._createNode(
|
|
3811
|
+
true,
|
|
3812
|
+
leafKeys,
|
|
3813
|
+
leafValues,
|
|
3814
|
+
null,
|
|
3815
|
+
null,
|
|
3816
|
+
null
|
|
3817
|
+
);
|
|
3818
|
+
leaves.push(leaf);
|
|
3819
|
+
}
|
|
3820
|
+
for (let i = 0, len = leaves.length; i < len; i++) {
|
|
3821
|
+
if (i > 0) {
|
|
3822
|
+
leaves[i].prev = leaves[i - 1].id;
|
|
3823
|
+
}
|
|
3824
|
+
if (i < len - 1) {
|
|
3825
|
+
leaves[i].next = leaves[i + 1].id;
|
|
3826
|
+
}
|
|
3827
|
+
await this._updateNode(leaves[i]);
|
|
3828
|
+
}
|
|
3829
|
+
let currentLevel = leaves;
|
|
3830
|
+
while (currentLevel.length > 1) {
|
|
3831
|
+
const nextLevel = [];
|
|
3832
|
+
for (let i = 0, len = currentLevel.length; i < len; i += this.order) {
|
|
3833
|
+
const children = currentLevel.slice(i, i + this.order);
|
|
3834
|
+
const childIds = children.map((c) => c.id);
|
|
3835
|
+
const separators = [];
|
|
3836
|
+
for (let j = 1, len2 = children.length; j < len2; j++) {
|
|
3837
|
+
separators.push(children[j].values[0]);
|
|
3838
|
+
}
|
|
3839
|
+
const internalNode = await this._createNode(
|
|
3840
|
+
false,
|
|
3841
|
+
childIds,
|
|
3842
|
+
separators,
|
|
3843
|
+
null,
|
|
3844
|
+
null,
|
|
3845
|
+
null
|
|
3846
|
+
);
|
|
3847
|
+
for (let j = 0, len2 = children.length; j < len2; j++) {
|
|
3848
|
+
const child = children[j];
|
|
3849
|
+
child.parent = internalNode.id;
|
|
3850
|
+
await this._updateNode(child);
|
|
3851
|
+
}
|
|
3852
|
+
nextLevel.push(internalNode);
|
|
3853
|
+
}
|
|
3854
|
+
currentLevel = nextLevel;
|
|
3855
|
+
}
|
|
3856
|
+
const newRoot = currentLevel[0];
|
|
3857
|
+
await this._writeHead({
|
|
3858
|
+
root: newRoot.id,
|
|
3859
|
+
order: this.order,
|
|
3860
|
+
data: this.strategy.head.data
|
|
3861
|
+
});
|
|
3862
|
+
});
|
|
3863
|
+
}
|
|
3684
3864
|
async _deleteEntry(node, key) {
|
|
3685
3865
|
if (!node.leaf) {
|
|
3686
3866
|
let keyIndex = -1;
|
|
@@ -3784,7 +3964,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3784
3964
|
siblingNode.values.push(...node.values);
|
|
3785
3965
|
if (!siblingNode.leaf) {
|
|
3786
3966
|
const keys = siblingNode.keys;
|
|
3787
|
-
for (
|
|
3967
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3968
|
+
const key2 = keys[i];
|
|
3788
3969
|
const node2 = this._cloneNode(await this.getNode(key2));
|
|
3789
3970
|
node2.parent = siblingNode.id;
|
|
3790
3971
|
await this._updateNode(node2);
|
|
@@ -3852,21 +4033,24 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3852
4033
|
await this._updateNode(siblingNode);
|
|
3853
4034
|
}
|
|
3854
4035
|
if (!siblingNode.leaf) {
|
|
3855
|
-
for (
|
|
4036
|
+
for (let i = 0, len = siblingNode.keys.length; i < len; i++) {
|
|
4037
|
+
const key2 = siblingNode.keys[i];
|
|
3856
4038
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3857
4039
|
n.parent = siblingNode.id;
|
|
3858
4040
|
await this._updateNode(n);
|
|
3859
4041
|
}
|
|
3860
4042
|
}
|
|
3861
4043
|
if (!node.leaf) {
|
|
3862
|
-
for (
|
|
4044
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
4045
|
+
const key2 = node.keys[i];
|
|
3863
4046
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3864
4047
|
n.parent = node.id;
|
|
3865
4048
|
await this._updateNode(n);
|
|
3866
4049
|
}
|
|
3867
4050
|
}
|
|
3868
4051
|
if (!parentNode.leaf) {
|
|
3869
|
-
for (
|
|
4052
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
4053
|
+
const key2 = parentNode.keys[i];
|
|
3870
4054
|
const n = this._cloneNode(await this.getNode(key2));
|
|
3871
4055
|
n.parent = parentNode.id;
|
|
3872
4056
|
await this._updateNode(n);
|
|
@@ -4048,6 +4232,16 @@ var BPTreeAsync = class extends BPTreeAsyncTransaction {
|
|
|
4048
4232
|
}
|
|
4049
4233
|
});
|
|
4050
4234
|
}
|
|
4235
|
+
async bulkLoad(entries) {
|
|
4236
|
+
return this.writeLock(1, async () => {
|
|
4237
|
+
const tx = await this.createTransaction();
|
|
4238
|
+
await tx.bulkLoad(entries);
|
|
4239
|
+
const result = await tx.commit();
|
|
4240
|
+
if (!result.success) {
|
|
4241
|
+
throw new Error(`Transaction failed: ${result.error || "Commit failed due to conflict"}`);
|
|
4242
|
+
}
|
|
4243
|
+
});
|
|
4244
|
+
}
|
|
4051
4245
|
};
|
|
4052
4246
|
var SerializeStrategy = class {
|
|
4053
4247
|
order;
|
|
@@ -8053,6 +8247,14 @@ var HookallSync = class _HookallSync {
|
|
|
8053
8247
|
// src/core/WALManager.ts
|
|
8054
8248
|
var import_node_fs = __toESM(require("node:fs"));
|
|
8055
8249
|
var WALManager = class {
|
|
8250
|
+
fd = null;
|
|
8251
|
+
walFilePath;
|
|
8252
|
+
pageSize;
|
|
8253
|
+
entrySize;
|
|
8254
|
+
buffer;
|
|
8255
|
+
view;
|
|
8256
|
+
totalWrittenPages = 0;
|
|
8257
|
+
logger;
|
|
8056
8258
|
/**
|
|
8057
8259
|
* Constructor
|
|
8058
8260
|
* @param walFilePath WAL file path
|
|
@@ -8060,7 +8262,6 @@ var WALManager = class {
|
|
|
8060
8262
|
* @param logger Logger instance
|
|
8061
8263
|
*/
|
|
8062
8264
|
constructor(walFilePath, pageSize, logger) {
|
|
8063
|
-
this.logger = logger;
|
|
8064
8265
|
if ((pageSize & pageSize - 1) !== 0) {
|
|
8065
8266
|
throw new Error("Page size must be a power of 2");
|
|
8066
8267
|
}
|
|
@@ -8069,14 +8270,8 @@ var WALManager = class {
|
|
|
8069
8270
|
this.entrySize = 4 + pageSize;
|
|
8070
8271
|
this.buffer = new Uint8Array(this.entrySize);
|
|
8071
8272
|
this.view = new DataView(this.buffer.buffer);
|
|
8273
|
+
this.logger = logger;
|
|
8072
8274
|
}
|
|
8073
|
-
fd = null;
|
|
8074
|
-
walFilePath;
|
|
8075
|
-
pageSize;
|
|
8076
|
-
entrySize;
|
|
8077
|
-
buffer;
|
|
8078
|
-
view;
|
|
8079
|
-
totalWrittenPages = 0;
|
|
8080
8275
|
/**
|
|
8081
8276
|
* Opens the log file.
|
|
8082
8277
|
*/
|
|
@@ -8424,21 +8619,22 @@ var PageFileSystem = class {
|
|
|
8424
8619
|
* @param pageCacheCapacity 페이지 캐시 크기
|
|
8425
8620
|
* @param options 데이터플라이 옵션
|
|
8426
8621
|
*/
|
|
8427
|
-
constructor(fileHandle, pageSize, pageCacheCapacity, options, logger) {
|
|
8622
|
+
constructor(fileHandle, pageSize, pageCacheCapacity, options, logger, walLogger) {
|
|
8428
8623
|
this.fileHandle = fileHandle;
|
|
8429
8624
|
this.pageSize = pageSize;
|
|
8430
8625
|
this.pageCacheCapacity = pageCacheCapacity;
|
|
8431
8626
|
this.options = options;
|
|
8432
|
-
this.logger = logger;
|
|
8433
8627
|
const walPath = options.wal;
|
|
8434
|
-
this.walManager = walPath ? new WALManager(walPath, pageSize,
|
|
8628
|
+
this.walManager = walPath && walLogger ? new WALManager(walPath, pageSize, walLogger) : null;
|
|
8435
8629
|
this.pageManagerFactory = new PageManagerFactory();
|
|
8436
8630
|
this.pageStrategy = new PageMVCCStrategy(fileHandle, pageSize, pageCacheCapacity);
|
|
8631
|
+
this.logger = logger;
|
|
8437
8632
|
}
|
|
8438
8633
|
pageFactory = new PageManagerFactory();
|
|
8439
8634
|
walManager;
|
|
8440
8635
|
pageManagerFactory;
|
|
8441
8636
|
pageStrategy;
|
|
8637
|
+
logger;
|
|
8442
8638
|
/** 글로벌 동기화(체크포인트/커밋)를 위한 Mutex */
|
|
8443
8639
|
lockPromise = Promise.resolve();
|
|
8444
8640
|
/**
|
|
@@ -9052,13 +9248,13 @@ var RowTableEngine = class {
|
|
|
9052
9248
|
this.pfs = pfs;
|
|
9053
9249
|
this.txContext = txContext;
|
|
9054
9250
|
this.options = options;
|
|
9055
|
-
this.logger = logger;
|
|
9056
9251
|
this.factory = new PageManagerFactory();
|
|
9057
9252
|
this.metadataPageManager = this.factory.getManagerFromType(MetadataPageManager.CONSTANT.PAGE_TYPE_METADATA);
|
|
9058
9253
|
this.dataPageManager = this.factory.getManagerFromType(DataPageManager.CONSTANT.PAGE_TYPE_DATA);
|
|
9059
9254
|
this.overflowPageManager = this.factory.getManagerFromType(OverflowPageManager.CONSTANT.PAGE_TYPE_OVERFLOW);
|
|
9060
9255
|
this.rowManager = new Row();
|
|
9061
9256
|
this.keyManager = new KeyManager();
|
|
9257
|
+
this.logger = logger;
|
|
9062
9258
|
this.ridBuffer = new Uint8Array(Row.CONSTANT.SIZE_RID);
|
|
9063
9259
|
this.pageIdBuffer = new Uint8Array(DataPageManager.CONSTANT.SIZE_PAGE_ID);
|
|
9064
9260
|
this.maxBodySize = this.pfs.pageSize - DataPageManager.CONSTANT.SIZE_PAGE_HEADER;
|
|
@@ -9087,6 +9283,7 @@ var RowTableEngine = class {
|
|
|
9087
9283
|
maxBodySize;
|
|
9088
9284
|
ridBuffer;
|
|
9089
9285
|
pageIdBuffer;
|
|
9286
|
+
logger;
|
|
9090
9287
|
initialized = false;
|
|
9091
9288
|
/**
|
|
9092
9289
|
* Retrieves the BPTree transaction associated with the given transaction.
|
|
@@ -9860,12 +10057,11 @@ var Colors = {
|
|
|
9860
10057
|
white: "\x1B[37m",
|
|
9861
10058
|
// White
|
|
9862
10059
|
grey: "\x1B[90m"
|
|
10060
|
+
// Grey
|
|
9863
10061
|
};
|
|
9864
|
-
var
|
|
10062
|
+
var LoggerManager = class {
|
|
9865
10063
|
level;
|
|
9866
|
-
|
|
9867
|
-
constructor(moduleName, level = 2 /* Info */) {
|
|
9868
|
-
this.moduleName = moduleName;
|
|
10064
|
+
constructor(level = 2 /* Info */) {
|
|
9869
10065
|
this.level = level;
|
|
9870
10066
|
}
|
|
9871
10067
|
setLevel(level) {
|
|
@@ -9875,23 +10071,32 @@ var Logger = class {
|
|
|
9875
10071
|
if (this.level === 0 /* None */) return false;
|
|
9876
10072
|
return level >= this.level;
|
|
9877
10073
|
}
|
|
10074
|
+
create(moduleName) {
|
|
10075
|
+
return new Logger(this, moduleName);
|
|
10076
|
+
}
|
|
10077
|
+
};
|
|
10078
|
+
var Logger = class {
|
|
10079
|
+
constructor(parent, moduleName) {
|
|
10080
|
+
this.parent = parent;
|
|
10081
|
+
this.moduleName = moduleName;
|
|
10082
|
+
}
|
|
9878
10083
|
debug(message, ...args) {
|
|
9879
|
-
if (this.shouldLog(1 /* Debug */)) {
|
|
10084
|
+
if (this.parent.shouldLog(1 /* Debug */)) {
|
|
9880
10085
|
console.debug(`${Colors.debug}[DEBUG] [${this.moduleName}]${Colors.reset} ${Colors.white}${message}${Colors.reset}`, ...args);
|
|
9881
10086
|
}
|
|
9882
10087
|
}
|
|
9883
10088
|
info(message, ...args) {
|
|
9884
|
-
if (this.shouldLog(2 /* Info */)) {
|
|
10089
|
+
if (this.parent.shouldLog(2 /* Info */)) {
|
|
9885
10090
|
console.info(`${Colors.info}[INFO] [${this.moduleName}]${Colors.reset} ${Colors.white}${message}${Colors.reset}`, ...args);
|
|
9886
10091
|
}
|
|
9887
10092
|
}
|
|
9888
10093
|
warn(message, ...args) {
|
|
9889
|
-
if (this.shouldLog(3 /* Warning */)) {
|
|
10094
|
+
if (this.parent.shouldLog(3 /* Warning */)) {
|
|
9890
10095
|
console.warn(`${Colors.warn}[WARN] [${this.moduleName}]${Colors.reset} ${Colors.white}${message}${Colors.reset}`, ...args);
|
|
9891
10096
|
}
|
|
9892
10097
|
}
|
|
9893
10098
|
error(message, ...args) {
|
|
9894
|
-
if (this.shouldLog(4 /* Error */)) {
|
|
10099
|
+
if (this.parent.shouldLog(4 /* Error */)) {
|
|
9895
10100
|
console.error(`${Colors.error}[ERROR] [${this.moduleName}]${Colors.reset} ${Colors.white}${message}${Colors.reset}`, ...args);
|
|
9896
10101
|
}
|
|
9897
10102
|
}
|
|
@@ -9903,7 +10108,8 @@ var DataplyAPI = class {
|
|
|
9903
10108
|
this.file = file;
|
|
9904
10109
|
this.hook = useHookall(this);
|
|
9905
10110
|
this.options = this.verboseOptions(options);
|
|
9906
|
-
this.
|
|
10111
|
+
this.loggerManager = new LoggerManager(this.options.logLevel);
|
|
10112
|
+
this.logger = this.loggerManager.create("DataplyAPI");
|
|
9907
10113
|
this.isNewlyCreated = !import_node_fs3.default.existsSync(file);
|
|
9908
10114
|
this.fileHandle = this.createOrOpen(file, this.options);
|
|
9909
10115
|
this.pfs = new PageFileSystem(
|
|
@@ -9911,12 +10117,13 @@ var DataplyAPI = class {
|
|
|
9911
10117
|
this.options.pageSize,
|
|
9912
10118
|
this.options.pageCacheCapacity,
|
|
9913
10119
|
this.options,
|
|
9914
|
-
this.
|
|
10120
|
+
this.loggerManager.create("PageFileSystem"),
|
|
10121
|
+
options.wal ? this.loggerManager.create("WALManager") : void 0
|
|
9915
10122
|
);
|
|
9916
10123
|
this.textCodec = new TextCodec();
|
|
9917
10124
|
this.txContext = new TransactionContext();
|
|
9918
10125
|
this.lockManager = new LockManager();
|
|
9919
|
-
this.rowTableEngine = new RowTableEngine(this.pfs, this.txContext, this.options, this.
|
|
10126
|
+
this.rowTableEngine = new RowTableEngine(this.pfs, this.txContext, this.options, this.loggerManager.create("RowTableEngine"));
|
|
9920
10127
|
this.initialized = false;
|
|
9921
10128
|
this.txIdCounter = 0;
|
|
9922
10129
|
this.logger.debug(`DataplyAPI instance created with file: ${file}`);
|
|
@@ -9941,7 +10148,9 @@ var DataplyAPI = class {
|
|
|
9941
10148
|
txContext;
|
|
9942
10149
|
/** Hook */
|
|
9943
10150
|
hook;
|
|
9944
|
-
/** Logger */
|
|
10151
|
+
/** Base Logger */
|
|
10152
|
+
loggerManager;
|
|
10153
|
+
/** Logger module for DataplyAPI */
|
|
9945
10154
|
logger;
|
|
9946
10155
|
/** Whether the database was initialized via `init()` */
|
|
9947
10156
|
initialized;
|
|
@@ -6,7 +6,7 @@ import { TextCodec } from '../utils/TextCodec';
|
|
|
6
6
|
import { LockManager } from './transaction/LockManager';
|
|
7
7
|
import { Transaction } from './transaction/Transaction';
|
|
8
8
|
import { TransactionContext } from './transaction/TxContext';
|
|
9
|
-
import { Logger } from './Logger';
|
|
9
|
+
import { LoggerManager, Logger } from './Logger';
|
|
10
10
|
interface DataplyAPIAsyncHook {
|
|
11
11
|
init: (tx: Transaction, isNewlyCreated: boolean) => Promise<Transaction>;
|
|
12
12
|
close: () => Promise<void>;
|
|
@@ -36,7 +36,9 @@ export declare class DataplyAPI {
|
|
|
36
36
|
protected readonly txContext: TransactionContext;
|
|
37
37
|
/** Hook */
|
|
38
38
|
protected readonly hook: IHookall<DataplyAPIAsyncHook>;
|
|
39
|
-
/** Logger */
|
|
39
|
+
/** Base Logger */
|
|
40
|
+
protected readonly loggerManager: LoggerManager;
|
|
41
|
+
/** Logger module for DataplyAPI */
|
|
40
42
|
protected readonly logger: Logger;
|
|
41
43
|
/** Whether the database was initialized via `init()` */
|
|
42
44
|
protected initialized: boolean;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { LogLevel } from '../types';
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class LoggerManager {
|
|
3
3
|
private level;
|
|
4
|
-
|
|
5
|
-
constructor(moduleName: string, level?: LogLevel);
|
|
4
|
+
constructor(level?: LogLevel);
|
|
6
5
|
setLevel(level: LogLevel): void;
|
|
7
|
-
|
|
6
|
+
shouldLog(level: LogLevel): boolean;
|
|
7
|
+
create(moduleName: string): Logger;
|
|
8
|
+
}
|
|
9
|
+
export declare class Logger {
|
|
10
|
+
private readonly parent;
|
|
11
|
+
private readonly moduleName;
|
|
12
|
+
constructor(parent: LoggerManager, moduleName: string);
|
|
8
13
|
debug(message: string, ...args: any[]): void;
|
|
9
14
|
info(message: string, ...args: any[]): void;
|
|
10
15
|
warn(message: string, ...args: any[]): void;
|
|
@@ -13,18 +13,18 @@ export declare class PageFileSystem {
|
|
|
13
13
|
readonly pageSize: number;
|
|
14
14
|
readonly pageCacheCapacity: number;
|
|
15
15
|
readonly options: Required<DataplyOptions>;
|
|
16
|
-
protected readonly logger: Logger;
|
|
17
16
|
protected readonly pageFactory: PageManagerFactory;
|
|
18
17
|
protected readonly walManager: WALManager | null;
|
|
19
18
|
protected readonly pageManagerFactory: PageManagerFactory;
|
|
20
19
|
protected readonly pageStrategy: PageMVCCStrategy;
|
|
20
|
+
protected readonly logger: Logger;
|
|
21
21
|
/** 글로벌 동기화(체크포인트/커밋)를 위한 Mutex */
|
|
22
22
|
private lockPromise;
|
|
23
23
|
/**
|
|
24
24
|
* @param pageCacheCapacity 페이지 캐시 크기
|
|
25
25
|
* @param options 데이터플라이 옵션
|
|
26
26
|
*/
|
|
27
|
-
constructor(fileHandle: number, pageSize: number, pageCacheCapacity: number, options: Required<DataplyOptions>, logger: Logger);
|
|
27
|
+
constructor(fileHandle: number, pageSize: number, pageCacheCapacity: number, options: Required<DataplyOptions>, logger: Logger, walLogger?: Logger);
|
|
28
28
|
/**
|
|
29
29
|
* 글로벌 동기화 범위 내에서 작업을 실행합니다.
|
|
30
30
|
* @param task 수행할 비동기 작업
|
|
@@ -12,7 +12,6 @@ export declare class RowTableEngine {
|
|
|
12
12
|
protected readonly pfs: PageFileSystem;
|
|
13
13
|
protected readonly txContext: TransactionContext;
|
|
14
14
|
protected readonly options: Required<DataplyOptions>;
|
|
15
|
-
protected readonly logger: Logger;
|
|
16
15
|
protected readonly bptree: BPTreeAsync<number, number>;
|
|
17
16
|
protected readonly strategy: RowIdentifierStrategy;
|
|
18
17
|
protected readonly order: number;
|
|
@@ -25,6 +24,7 @@ export declare class RowTableEngine {
|
|
|
25
24
|
protected readonly maxBodySize: number;
|
|
26
25
|
private readonly ridBuffer;
|
|
27
26
|
private readonly pageIdBuffer;
|
|
27
|
+
private readonly logger;
|
|
28
28
|
private initialized;
|
|
29
29
|
constructor(pfs: PageFileSystem, txContext: TransactionContext, options: Required<DataplyOptions>, logger: Logger);
|
|
30
30
|
/**
|
|
@@ -5,7 +5,6 @@ import { Logger } from './Logger';
|
|
|
5
5
|
* Handles commit phases and crash recovery.
|
|
6
6
|
*/
|
|
7
7
|
export declare class WALManager {
|
|
8
|
-
private readonly logger;
|
|
9
8
|
private fd;
|
|
10
9
|
private readonly walFilePath;
|
|
11
10
|
private readonly pageSize;
|
|
@@ -13,6 +12,7 @@ export declare class WALManager {
|
|
|
13
12
|
private buffer;
|
|
14
13
|
private view;
|
|
15
14
|
private totalWrittenPages;
|
|
15
|
+
private readonly logger;
|
|
16
16
|
/**
|
|
17
17
|
* Constructor
|
|
18
18
|
* @param walFilePath WAL file path
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataply",
|
|
3
|
-
"version": "0.0.26-alpha.
|
|
3
|
+
"version": "0.0.26-alpha.2",
|
|
4
4
|
"description": "A lightweight storage engine for Node.js with support for MVCC, WAL.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "izure <admin@izure.org>",
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"hookall": "^2.2.0",
|
|
50
50
|
"mvcc-api": "^1.3.5",
|
|
51
51
|
"ryoiki": "^1.2.0",
|
|
52
|
-
"serializable-bptree": "^8.
|
|
52
|
+
"serializable-bptree": "^8.4.0"
|
|
53
53
|
}
|
|
54
|
-
}
|
|
54
|
+
}
|