dataply 0.0.10 → 0.0.12
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 +227 -14
- package/package.json +2 -2
- package/readme.md +2 -0
package/dist/cjs/index.js
CHANGED
|
@@ -71,6 +71,33 @@ var ValueComparator = class {
|
|
|
71
71
|
isHigher(value, than) {
|
|
72
72
|
return this.asc(value, than) > 0;
|
|
73
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* This method is used for range queries with composite values.
|
|
76
|
+
* By default, it calls the `asc` method, so existing code works without changes.
|
|
77
|
+
*
|
|
78
|
+
* When using composite values (e.g., `{ k: number, v: number }`),
|
|
79
|
+
* override this method to compare only the primary sorting field (e.g., `v`),
|
|
80
|
+
* ignoring the unique identifier field (e.g., `k`).
|
|
81
|
+
*
|
|
82
|
+
* This enables efficient range queries like `primaryEqual` that find all entries
|
|
83
|
+
* with the same primary value regardless of their unique identifiers.
|
|
84
|
+
*
|
|
85
|
+
* @param a Value a.
|
|
86
|
+
* @param b Value b.
|
|
87
|
+
* @returns Negative if a < b, 0 if equal, positive if a > b (based on primary field only).
|
|
88
|
+
*/
|
|
89
|
+
primaryAsc(a, b) {
|
|
90
|
+
return this.asc(a, b);
|
|
91
|
+
}
|
|
92
|
+
isPrimarySame(value, than) {
|
|
93
|
+
return this.primaryAsc(value, than) === 0;
|
|
94
|
+
}
|
|
95
|
+
isPrimaryLower(value, than) {
|
|
96
|
+
return this.primaryAsc(value, than) < 0;
|
|
97
|
+
}
|
|
98
|
+
isPrimaryHigher(value, than) {
|
|
99
|
+
return this.primaryAsc(value, than) > 0;
|
|
100
|
+
}
|
|
74
101
|
};
|
|
75
102
|
var NumericComparator = class extends ValueComparator {
|
|
76
103
|
asc(a, b) {
|
|
@@ -482,6 +509,13 @@ var BPTree = class {
|
|
|
482
509
|
equal: (nv, v) => this.comparator.isSame(nv, v),
|
|
483
510
|
notEqual: (nv, v) => this.comparator.isSame(nv, v) === false,
|
|
484
511
|
or: (nv, v) => this.ensureValues(v).some((v2) => this.comparator.isSame(nv, v2)),
|
|
512
|
+
primaryGt: (nv, v) => this.comparator.isPrimaryHigher(nv, v),
|
|
513
|
+
primaryGte: (nv, v) => this.comparator.isPrimaryHigher(nv, v) || this.comparator.isPrimarySame(nv, v),
|
|
514
|
+
primaryLt: (nv, v) => this.comparator.isPrimaryLower(nv, v),
|
|
515
|
+
primaryLte: (nv, v) => this.comparator.isPrimaryLower(nv, v) || this.comparator.isPrimarySame(nv, v),
|
|
516
|
+
primaryEqual: (nv, v) => this.comparator.isPrimarySame(nv, v),
|
|
517
|
+
primaryNotEqual: (nv, v) => this.comparator.isPrimarySame(nv, v) === false,
|
|
518
|
+
primaryOr: (nv, v) => this.ensureValues(v).some((v2) => this.comparator.isPrimarySame(nv, v2)),
|
|
485
519
|
like: (nv, v) => {
|
|
486
520
|
const nodeValue = this.comparator.match(nv);
|
|
487
521
|
const value = this.comparator.match(v);
|
|
@@ -498,6 +532,13 @@ var BPTree = class {
|
|
|
498
532
|
equal: (v) => this.insertableNode(v),
|
|
499
533
|
notEqual: (v) => this.leftestNode(),
|
|
500
534
|
or: (v) => this.insertableNode(this.lowestValue(this.ensureValues(v))),
|
|
535
|
+
primaryGt: (v) => this.insertableNodeByPrimary(v),
|
|
536
|
+
primaryGte: (v) => this.insertableNodeByPrimary(v),
|
|
537
|
+
primaryLt: (v) => this.insertableNodeByPrimary(v),
|
|
538
|
+
primaryLte: (v) => this.insertableRightestNodeByPrimary(v),
|
|
539
|
+
primaryEqual: (v) => this.insertableNodeByPrimary(v),
|
|
540
|
+
primaryNotEqual: (v) => this.leftestNode(),
|
|
541
|
+
primaryOr: (v) => this.insertableNodeByPrimary(this.lowestPrimaryValue(this.ensureValues(v))),
|
|
501
542
|
like: (v) => this.leftestNode()
|
|
502
543
|
};
|
|
503
544
|
verifierEndNode = {
|
|
@@ -511,6 +552,15 @@ var BPTree = class {
|
|
|
511
552
|
this.highestValue(this.ensureValues(v)),
|
|
512
553
|
this.verifierDirection.or
|
|
513
554
|
),
|
|
555
|
+
primaryGt: (v) => null,
|
|
556
|
+
primaryGte: (v) => null,
|
|
557
|
+
primaryLt: (v) => null,
|
|
558
|
+
primaryLte: (v) => null,
|
|
559
|
+
primaryEqual: (v) => null,
|
|
560
|
+
primaryNotEqual: (v) => null,
|
|
561
|
+
primaryOr: (v) => this.insertableRightestEndNodeByPrimary(
|
|
562
|
+
this.highestPrimaryValue(this.ensureValues(v))
|
|
563
|
+
),
|
|
514
564
|
like: (v) => null
|
|
515
565
|
};
|
|
516
566
|
verifierDirection = {
|
|
@@ -521,8 +571,37 @@ var BPTree = class {
|
|
|
521
571
|
equal: 1,
|
|
522
572
|
notEqual: 1,
|
|
523
573
|
or: 1,
|
|
574
|
+
primaryGt: 1,
|
|
575
|
+
primaryGte: 1,
|
|
576
|
+
primaryLt: -1,
|
|
577
|
+
primaryLte: -1,
|
|
578
|
+
primaryEqual: 1,
|
|
579
|
+
primaryNotEqual: 1,
|
|
580
|
+
primaryOr: 1,
|
|
524
581
|
like: 1
|
|
525
582
|
};
|
|
583
|
+
/**
|
|
584
|
+
* Determines whether early termination is allowed for each condition.
|
|
585
|
+
* When true, the search will stop once a match is found and then a non-match is encountered.
|
|
586
|
+
* Only applicable for conditions that guarantee contiguous matches in a sorted B+Tree.
|
|
587
|
+
*/
|
|
588
|
+
verifierEarlyTerminate = {
|
|
589
|
+
gt: false,
|
|
590
|
+
gte: false,
|
|
591
|
+
lt: false,
|
|
592
|
+
lte: false,
|
|
593
|
+
equal: true,
|
|
594
|
+
notEqual: false,
|
|
595
|
+
or: false,
|
|
596
|
+
primaryGt: false,
|
|
597
|
+
primaryGte: false,
|
|
598
|
+
primaryLt: false,
|
|
599
|
+
primaryLte: false,
|
|
600
|
+
primaryEqual: true,
|
|
601
|
+
primaryNotEqual: false,
|
|
602
|
+
primaryOr: false,
|
|
603
|
+
like: false
|
|
604
|
+
};
|
|
526
605
|
constructor(strategy, comparator, option) {
|
|
527
606
|
this.strategy = strategy;
|
|
528
607
|
this.comparator = comparator;
|
|
@@ -556,6 +635,14 @@ var BPTree = class {
|
|
|
556
635
|
const i = v.length - 1;
|
|
557
636
|
return [...v].sort((a, b) => this.comparator.asc(a, b))[i];
|
|
558
637
|
}
|
|
638
|
+
lowestPrimaryValue(v) {
|
|
639
|
+
const i = 0;
|
|
640
|
+
return [...v].sort((a, b) => this.comparator.primaryAsc(a, b))[i];
|
|
641
|
+
}
|
|
642
|
+
highestPrimaryValue(v) {
|
|
643
|
+
const i = v.length - 1;
|
|
644
|
+
return [...v].sort((a, b) => this.comparator.primaryAsc(a, b))[i];
|
|
645
|
+
}
|
|
559
646
|
_insertAtLeaf(node, key, value) {
|
|
560
647
|
if (node.values.length) {
|
|
561
648
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
@@ -633,10 +720,11 @@ var BPTreeSync = class extends BPTree {
|
|
|
633
720
|
capacity: this.option.capacity ?? 1e3
|
|
634
721
|
});
|
|
635
722
|
}
|
|
636
|
-
getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
723
|
+
getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate) {
|
|
637
724
|
const pairs = [];
|
|
638
725
|
let node = startNode;
|
|
639
726
|
let done = false;
|
|
727
|
+
let hasMatched = false;
|
|
640
728
|
while (!done) {
|
|
641
729
|
if (endNode && node.id === endNode.id) {
|
|
642
730
|
done = true;
|
|
@@ -647,12 +735,17 @@ var BPTreeSync = class extends BPTree {
|
|
|
647
735
|
const nValue = node.values[i];
|
|
648
736
|
const keys = node.keys[i];
|
|
649
737
|
if (comparator(nValue, value)) {
|
|
738
|
+
hasMatched = true;
|
|
650
739
|
let j = keys.length;
|
|
651
740
|
while (j--) {
|
|
652
741
|
pairs.push([keys[j], nValue]);
|
|
653
742
|
}
|
|
743
|
+
} else if (earlyTerminate && hasMatched) {
|
|
744
|
+
done = true;
|
|
745
|
+
break;
|
|
654
746
|
}
|
|
655
747
|
}
|
|
748
|
+
if (done) break;
|
|
656
749
|
if (!node.prev) {
|
|
657
750
|
done = true;
|
|
658
751
|
break;
|
|
@@ -661,10 +754,11 @@ var BPTreeSync = class extends BPTree {
|
|
|
661
754
|
}
|
|
662
755
|
return new Map(pairs.reverse());
|
|
663
756
|
}
|
|
664
|
-
getPairsLeftToRight(value, startNode, endNode, comparator) {
|
|
757
|
+
getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate) {
|
|
665
758
|
const pairs = [];
|
|
666
759
|
let node = startNode;
|
|
667
760
|
let done = false;
|
|
761
|
+
let hasMatched = false;
|
|
668
762
|
while (!done) {
|
|
669
763
|
if (endNode && node.id === endNode.id) {
|
|
670
764
|
done = true;
|
|
@@ -674,12 +768,17 @@ var BPTreeSync = class extends BPTree {
|
|
|
674
768
|
const nValue = node.values[i];
|
|
675
769
|
const keys = node.keys[i];
|
|
676
770
|
if (comparator(nValue, value)) {
|
|
771
|
+
hasMatched = true;
|
|
677
772
|
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
678
773
|
const key = keys[j];
|
|
679
774
|
pairs.push([key, nValue]);
|
|
680
775
|
}
|
|
776
|
+
} else if (earlyTerminate && hasMatched) {
|
|
777
|
+
done = true;
|
|
778
|
+
break;
|
|
681
779
|
}
|
|
682
780
|
}
|
|
781
|
+
if (done) break;
|
|
683
782
|
if (!node.next) {
|
|
684
783
|
done = true;
|
|
685
784
|
break;
|
|
@@ -688,12 +787,12 @@ var BPTreeSync = class extends BPTree {
|
|
|
688
787
|
}
|
|
689
788
|
return new Map(pairs);
|
|
690
789
|
}
|
|
691
|
-
getPairs(value, startNode, endNode, comparator, direction) {
|
|
790
|
+
getPairs(value, startNode, endNode, comparator, direction, earlyTerminate) {
|
|
692
791
|
switch (direction) {
|
|
693
792
|
case -1:
|
|
694
|
-
return this.getPairsRightToLeft(value, startNode, endNode, comparator);
|
|
793
|
+
return this.getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate);
|
|
695
794
|
case 1:
|
|
696
|
-
return this.getPairsLeftToRight(value, startNode, endNode, comparator);
|
|
795
|
+
return this.getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate);
|
|
697
796
|
default:
|
|
698
797
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
699
798
|
}
|
|
@@ -1042,6 +1141,55 @@ var BPTreeSync = class extends BPTree {
|
|
|
1042
1141
|
}
|
|
1043
1142
|
return node;
|
|
1044
1143
|
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Find the insertable node using primaryAsc comparison.
|
|
1146
|
+
* This allows finding nodes by primary value only, ignoring unique identifiers.
|
|
1147
|
+
*/
|
|
1148
|
+
insertableNodeByPrimary(value) {
|
|
1149
|
+
let node = this.getNode(this.root.id);
|
|
1150
|
+
while (!node.leaf) {
|
|
1151
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1152
|
+
const nValue = node.values[i];
|
|
1153
|
+
const k = node.keys;
|
|
1154
|
+
if (this.comparator.isPrimarySame(value, nValue)) {
|
|
1155
|
+
node = this.getNode(k[i]);
|
|
1156
|
+
break;
|
|
1157
|
+
} else if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
1158
|
+
node = this.getNode(k[i]);
|
|
1159
|
+
break;
|
|
1160
|
+
} else if (i + 1 === node.values.length) {
|
|
1161
|
+
node = this.getNode(k[i + 1]);
|
|
1162
|
+
break;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
return node;
|
|
1167
|
+
}
|
|
1168
|
+
insertableRightestNodeByPrimary(value) {
|
|
1169
|
+
let node = this.getNode(this.root.id);
|
|
1170
|
+
while (!node.leaf) {
|
|
1171
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1172
|
+
const nValue = node.values[i];
|
|
1173
|
+
const k = node.keys;
|
|
1174
|
+
if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
1175
|
+
node = this.getNode(k[i]);
|
|
1176
|
+
break;
|
|
1177
|
+
}
|
|
1178
|
+
if (i + 1 === node.values.length) {
|
|
1179
|
+
node = this.getNode(k[i + 1]);
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return node;
|
|
1185
|
+
}
|
|
1186
|
+
insertableRightestEndNodeByPrimary(value) {
|
|
1187
|
+
const node = this.insertableRightestNodeByPrimary(value);
|
|
1188
|
+
if (!node.next) {
|
|
1189
|
+
return null;
|
|
1190
|
+
}
|
|
1191
|
+
return this.getNode(node.next);
|
|
1192
|
+
}
|
|
1045
1193
|
insertableEndNode(value, direction) {
|
|
1046
1194
|
const insertableNode = this.insertableNode(value);
|
|
1047
1195
|
let key;
|
|
@@ -1110,7 +1258,8 @@ var BPTreeSync = class extends BPTree {
|
|
|
1110
1258
|
const endNode = this.verifierEndNode[key](value);
|
|
1111
1259
|
const direction = this.verifierDirection[key];
|
|
1112
1260
|
const comparator = this.verifierMap[key];
|
|
1113
|
-
const
|
|
1261
|
+
const earlyTerminate = this.verifierEarlyTerminate[key];
|
|
1262
|
+
const pairs = this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
|
|
1114
1263
|
if (!filterValues) {
|
|
1115
1264
|
filterValues = new Set(pairs.keys());
|
|
1116
1265
|
} else {
|
|
@@ -1135,7 +1284,8 @@ var BPTreeSync = class extends BPTree {
|
|
|
1135
1284
|
const endNode = this.verifierEndNode[key](value);
|
|
1136
1285
|
const direction = this.verifierDirection[key];
|
|
1137
1286
|
const comparator = this.verifierMap[key];
|
|
1138
|
-
const
|
|
1287
|
+
const earlyTerminate = this.verifierEarlyTerminate[key];
|
|
1288
|
+
const pairs = this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
|
|
1139
1289
|
if (result === null) {
|
|
1140
1290
|
result = pairs;
|
|
1141
1291
|
} else {
|
|
@@ -1519,10 +1669,11 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1519
1669
|
this.lock.writeUnlock(lockId);
|
|
1520
1670
|
});
|
|
1521
1671
|
}
|
|
1522
|
-
async getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
1672
|
+
async getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate) {
|
|
1523
1673
|
const pairs = [];
|
|
1524
1674
|
let node = startNode;
|
|
1525
1675
|
let done = false;
|
|
1676
|
+
let hasMatched = false;
|
|
1526
1677
|
while (!done) {
|
|
1527
1678
|
if (endNode && node.id === endNode.id) {
|
|
1528
1679
|
done = true;
|
|
@@ -1533,12 +1684,17 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1533
1684
|
const nValue = node.values[i];
|
|
1534
1685
|
const keys = node.keys[i];
|
|
1535
1686
|
if (comparator(nValue, value)) {
|
|
1687
|
+
hasMatched = true;
|
|
1536
1688
|
let j = keys.length;
|
|
1537
1689
|
while (j--) {
|
|
1538
1690
|
pairs.push([keys[j], nValue]);
|
|
1539
1691
|
}
|
|
1692
|
+
} else if (earlyTerminate && hasMatched) {
|
|
1693
|
+
done = true;
|
|
1694
|
+
break;
|
|
1540
1695
|
}
|
|
1541
1696
|
}
|
|
1697
|
+
if (done) break;
|
|
1542
1698
|
if (!node.prev) {
|
|
1543
1699
|
done = true;
|
|
1544
1700
|
break;
|
|
@@ -1547,10 +1703,11 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1547
1703
|
}
|
|
1548
1704
|
return new Map(pairs.reverse());
|
|
1549
1705
|
}
|
|
1550
|
-
async getPairsLeftToRight(value, startNode, endNode, comparator) {
|
|
1706
|
+
async getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate) {
|
|
1551
1707
|
const pairs = [];
|
|
1552
1708
|
let node = startNode;
|
|
1553
1709
|
let done = false;
|
|
1710
|
+
let hasMatched = false;
|
|
1554
1711
|
while (!done) {
|
|
1555
1712
|
if (endNode && node.id === endNode.id) {
|
|
1556
1713
|
done = true;
|
|
@@ -1560,12 +1717,17 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1560
1717
|
const nValue = node.values[i];
|
|
1561
1718
|
const keys = node.keys[i];
|
|
1562
1719
|
if (comparator(nValue, value)) {
|
|
1720
|
+
hasMatched = true;
|
|
1563
1721
|
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
1564
1722
|
const key = keys[j];
|
|
1565
1723
|
pairs.push([key, nValue]);
|
|
1566
1724
|
}
|
|
1725
|
+
} else if (earlyTerminate && hasMatched) {
|
|
1726
|
+
done = true;
|
|
1727
|
+
break;
|
|
1567
1728
|
}
|
|
1568
1729
|
}
|
|
1730
|
+
if (done) break;
|
|
1569
1731
|
if (!node.next) {
|
|
1570
1732
|
done = true;
|
|
1571
1733
|
break;
|
|
@@ -1574,12 +1736,12 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1574
1736
|
}
|
|
1575
1737
|
return new Map(pairs);
|
|
1576
1738
|
}
|
|
1577
|
-
async getPairs(value, startNode, endNode, comparator, direction) {
|
|
1739
|
+
async getPairs(value, startNode, endNode, comparator, direction, earlyTerminate) {
|
|
1578
1740
|
switch (direction) {
|
|
1579
1741
|
case -1:
|
|
1580
|
-
return await this.getPairsRightToLeft(value, startNode, endNode, comparator);
|
|
1742
|
+
return await this.getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate);
|
|
1581
1743
|
case 1:
|
|
1582
|
-
return await this.getPairsLeftToRight(value, startNode, endNode, comparator);
|
|
1744
|
+
return await this.getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate);
|
|
1583
1745
|
default:
|
|
1584
1746
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
1585
1747
|
}
|
|
@@ -1928,6 +2090,55 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1928
2090
|
}
|
|
1929
2091
|
return node;
|
|
1930
2092
|
}
|
|
2093
|
+
/**
|
|
2094
|
+
* Find the insertable node using primaryAsc comparison.
|
|
2095
|
+
* This allows finding nodes by primary value only, ignoring unique identifiers.
|
|
2096
|
+
*/
|
|
2097
|
+
async insertableNodeByPrimary(value) {
|
|
2098
|
+
let node = await this.getNode(this.root.id);
|
|
2099
|
+
while (!node.leaf) {
|
|
2100
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2101
|
+
const nValue = node.values[i];
|
|
2102
|
+
const k = node.keys;
|
|
2103
|
+
if (this.comparator.isPrimarySame(value, nValue)) {
|
|
2104
|
+
node = await this.getNode(k[i]);
|
|
2105
|
+
break;
|
|
2106
|
+
} else if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
2107
|
+
node = await this.getNode(k[i]);
|
|
2108
|
+
break;
|
|
2109
|
+
} else if (i + 1 === node.values.length) {
|
|
2110
|
+
node = await this.getNode(k[i + 1]);
|
|
2111
|
+
break;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
return node;
|
|
2116
|
+
}
|
|
2117
|
+
async insertableRightestNodeByPrimary(value) {
|
|
2118
|
+
let node = await this.getNode(this.root.id);
|
|
2119
|
+
while (!node.leaf) {
|
|
2120
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
2121
|
+
const nValue = node.values[i];
|
|
2122
|
+
const k = node.keys;
|
|
2123
|
+
if (this.comparator.isPrimaryLower(value, nValue)) {
|
|
2124
|
+
node = await this.getNode(k[i]);
|
|
2125
|
+
break;
|
|
2126
|
+
}
|
|
2127
|
+
if (i + 1 === node.values.length) {
|
|
2128
|
+
node = await this.getNode(k[i + 1]);
|
|
2129
|
+
break;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
return node;
|
|
2134
|
+
}
|
|
2135
|
+
async insertableRightestEndNodeByPrimary(value) {
|
|
2136
|
+
const node = await this.insertableRightestNodeByPrimary(value);
|
|
2137
|
+
if (!node.next) {
|
|
2138
|
+
return null;
|
|
2139
|
+
}
|
|
2140
|
+
return await this.getNode(node.next);
|
|
2141
|
+
}
|
|
1931
2142
|
async insertableEndNode(value, direction) {
|
|
1932
2143
|
const insertableNode = await this.insertableNode(value);
|
|
1933
2144
|
let key;
|
|
@@ -1997,7 +2208,8 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1997
2208
|
const endNode = await this.verifierEndNode[key](value);
|
|
1998
2209
|
const direction = this.verifierDirection[key];
|
|
1999
2210
|
const comparator = this.verifierMap[key];
|
|
2000
|
-
const
|
|
2211
|
+
const earlyTerminate = this.verifierEarlyTerminate[key];
|
|
2212
|
+
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
|
|
2001
2213
|
if (!filterValues) {
|
|
2002
2214
|
filterValues = new Set(pairs.keys());
|
|
2003
2215
|
} else {
|
|
@@ -2024,7 +2236,8 @@ var BPTreeAsync = class extends BPTree {
|
|
|
2024
2236
|
const endNode = await this.verifierEndNode[key](value);
|
|
2025
2237
|
const direction = this.verifierDirection[key];
|
|
2026
2238
|
const comparator = this.verifierMap[key];
|
|
2027
|
-
const
|
|
2239
|
+
const earlyTerminate = this.verifierEarlyTerminate[key];
|
|
2240
|
+
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
|
|
2028
2241
|
if (result === null) {
|
|
2029
2242
|
result = pairs;
|
|
2030
2243
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataply",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
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>",
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
"cache-entanglement": "^1.7.1",
|
|
48
48
|
"hookall": "^2.2.0",
|
|
49
49
|
"ryoiki": "^1.2.0",
|
|
50
|
-
"serializable-bptree": "^6.
|
|
50
|
+
"serializable-bptree": "^6.1.1"
|
|
51
51
|
}
|
|
52
52
|
}
|
package/readme.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
- **📝 WAL (Write-Ahead Logging)**: Ensures data integrity and provides recovery capabilities in case of system failures.
|
|
16
16
|
- **💼 Transaction Mechanism**: Supports Commit and Rollback for atomic operations.
|
|
17
17
|
- **📦 Page-Based Storage**: Efficient page caching and disk I/O optimization through Virtual File System (VFS).
|
|
18
|
+
- **📉 Bitmap Space Optimization**: Uses bitmapped management to efficiently track page usage and maximize disk space utilization.
|
|
18
19
|
- **⌨️ TypeScript Support**: Provides comprehensive type definitions for all APIs.
|
|
19
20
|
|
|
20
21
|
## Installation
|
|
@@ -224,6 +225,7 @@ graph TD
|
|
|
224
225
|
- **Fixed-size Pages**: All data is managed in fixed-size units (default 8KB) called pages.
|
|
225
226
|
- **VFS Cache**: Minimizes disk I/O by caching frequently accessed pages in memory.
|
|
226
227
|
- **Dirty Page Tracking**: Tracks modified pages (Dirty) to synchronize them with disk efficiently only at the time of commit.
|
|
228
|
+
- **Bitmap Management**: Efficiently tracks the allocation and deallocation of pages using a bitmap structure, facilitating fast space reclamation and reuse. For more details on this mechanism, see [Page Reclamation and Reuse Guide](docs/page_reclamation.md).
|
|
227
229
|
- **Detailed Structure**: For technical details on the physical layout, see [structure.md](docs/structure.md).
|
|
228
230
|
|
|
229
231
|
#### Page & Row Layout
|