dataply 0.0.12 → 0.0.13
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 +348 -202
- package/package.json +2 -2
package/dist/cjs/index.js
CHANGED
|
@@ -490,7 +490,7 @@ var CacheEntanglementAsync = class extends CacheEntanglement {
|
|
|
490
490
|
return this.caches.get(key);
|
|
491
491
|
}
|
|
492
492
|
};
|
|
493
|
-
var BPTree = class {
|
|
493
|
+
var BPTree = class _BPTree {
|
|
494
494
|
_cachedRegexp;
|
|
495
495
|
strategy;
|
|
496
496
|
comparator;
|
|
@@ -602,6 +602,82 @@ var BPTree = class {
|
|
|
602
602
|
primaryOr: false,
|
|
603
603
|
like: false
|
|
604
604
|
};
|
|
605
|
+
/**
|
|
606
|
+
* Priority map for condition types.
|
|
607
|
+
* Higher value = higher selectivity (fewer expected results).
|
|
608
|
+
* Used by `chooseDriver` to select the most selective index.
|
|
609
|
+
*/
|
|
610
|
+
static conditionPriority = {
|
|
611
|
+
equal: 100,
|
|
612
|
+
primaryEqual: 100,
|
|
613
|
+
or: 80,
|
|
614
|
+
primaryOr: 80,
|
|
615
|
+
gt: 50,
|
|
616
|
+
gte: 50,
|
|
617
|
+
lt: 50,
|
|
618
|
+
lte: 50,
|
|
619
|
+
primaryGt: 50,
|
|
620
|
+
primaryGte: 50,
|
|
621
|
+
primaryLt: 50,
|
|
622
|
+
primaryLte: 50,
|
|
623
|
+
like: 30,
|
|
624
|
+
notEqual: 10,
|
|
625
|
+
primaryNotEqual: 10
|
|
626
|
+
};
|
|
627
|
+
/**
|
|
628
|
+
* Selects the best driver tree from multiple tree/condition pairs.
|
|
629
|
+
* Uses rule-based optimization to choose the tree with highest estimated selectivity.
|
|
630
|
+
*
|
|
631
|
+
* @param candidates Array of { tree, condition } pairs to evaluate
|
|
632
|
+
* @returns The candidate with highest priority condition, or null if empty
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* ```typescript
|
|
636
|
+
* const driver = BPTreeSync.chooseDriver([
|
|
637
|
+
* { tree: idxId, condition: { equal: 100 } },
|
|
638
|
+
* { tree: idxAge, condition: { gt: 20 } }
|
|
639
|
+
* ])
|
|
640
|
+
* // Returns { tree: idxId, condition: { equal: 100 } } because 'equal' has higher priority
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
static ChooseDriver(candidates) {
|
|
644
|
+
if (candidates.length === 0) return null;
|
|
645
|
+
if (candidates.length === 1) return candidates[0];
|
|
646
|
+
let best = candidates[0];
|
|
647
|
+
let bestScore = 0;
|
|
648
|
+
for (const candidate of candidates) {
|
|
649
|
+
let score = 0;
|
|
650
|
+
for (const key in candidate.condition) {
|
|
651
|
+
const condKey = key;
|
|
652
|
+
const priority = _BPTree.conditionPriority[condKey] ?? 0;
|
|
653
|
+
if (priority > score) {
|
|
654
|
+
score = priority;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (score > bestScore) {
|
|
658
|
+
bestScore = score;
|
|
659
|
+
best = candidate;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return best;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Verified if the value satisfies the condition.
|
|
666
|
+
*
|
|
667
|
+
* @param nodeValue The value to verify.
|
|
668
|
+
* @param condition The condition to verify against.
|
|
669
|
+
* @returns Returns true if the value satisfies the condition.
|
|
670
|
+
*/
|
|
671
|
+
verify(nodeValue, condition) {
|
|
672
|
+
for (const key in condition) {
|
|
673
|
+
const verify = this.verifierMap[key];
|
|
674
|
+
const condValue = condition[key];
|
|
675
|
+
if (!verify(nodeValue, condValue)) {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
return true;
|
|
680
|
+
}
|
|
605
681
|
constructor(strategy, comparator, option) {
|
|
606
682
|
this.strategy = strategy;
|
|
607
683
|
this.comparator = comparator;
|
|
@@ -720,8 +796,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
720
796
|
capacity: this.option.capacity ?? 1e3
|
|
721
797
|
});
|
|
722
798
|
}
|
|
723
|
-
|
|
724
|
-
const pairs = [];
|
|
799
|
+
*getPairsGenerator(value, startNode, endNode, comparator, direction, earlyTerminate) {
|
|
725
800
|
let node = startNode;
|
|
726
801
|
let done = false;
|
|
727
802
|
let hasMatched = false;
|
|
@@ -730,71 +805,52 @@ var BPTreeSync = class extends BPTree {
|
|
|
730
805
|
done = true;
|
|
731
806
|
break;
|
|
732
807
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
808
|
+
const len = node.values.length;
|
|
809
|
+
if (direction === 1) {
|
|
810
|
+
for (let i = 0; i < len; i++) {
|
|
811
|
+
const nValue = node.values[i];
|
|
812
|
+
const keys = node.keys[i];
|
|
813
|
+
if (comparator(nValue, value)) {
|
|
814
|
+
hasMatched = true;
|
|
815
|
+
for (let j = 0; j < keys.length; j++) {
|
|
816
|
+
yield [keys[j], nValue];
|
|
817
|
+
}
|
|
818
|
+
} else if (earlyTerminate && hasMatched) {
|
|
819
|
+
done = true;
|
|
820
|
+
break;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
} else {
|
|
824
|
+
let i = len;
|
|
825
|
+
while (i--) {
|
|
826
|
+
const nValue = node.values[i];
|
|
827
|
+
const keys = node.keys[i];
|
|
828
|
+
if (comparator(nValue, value)) {
|
|
829
|
+
hasMatched = true;
|
|
830
|
+
let j = keys.length;
|
|
831
|
+
while (j--) {
|
|
832
|
+
yield [keys[j], nValue];
|
|
833
|
+
}
|
|
834
|
+
} else if (earlyTerminate && hasMatched) {
|
|
835
|
+
done = true;
|
|
836
|
+
break;
|
|
742
837
|
}
|
|
743
|
-
} else if (earlyTerminate && hasMatched) {
|
|
744
|
-
done = true;
|
|
745
|
-
break;
|
|
746
838
|
}
|
|
747
839
|
}
|
|
748
840
|
if (done) break;
|
|
749
|
-
if (
|
|
750
|
-
|
|
751
|
-
break;
|
|
752
|
-
}
|
|
753
|
-
node = this.getNode(node.prev);
|
|
754
|
-
}
|
|
755
|
-
return new Map(pairs.reverse());
|
|
756
|
-
}
|
|
757
|
-
getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate) {
|
|
758
|
-
const pairs = [];
|
|
759
|
-
let node = startNode;
|
|
760
|
-
let done = false;
|
|
761
|
-
let hasMatched = false;
|
|
762
|
-
while (!done) {
|
|
763
|
-
if (endNode && node.id === endNode.id) {
|
|
764
|
-
done = true;
|
|
765
|
-
break;
|
|
766
|
-
}
|
|
767
|
-
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
768
|
-
const nValue = node.values[i];
|
|
769
|
-
const keys = node.keys[i];
|
|
770
|
-
if (comparator(nValue, value)) {
|
|
771
|
-
hasMatched = true;
|
|
772
|
-
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
773
|
-
const key = keys[j];
|
|
774
|
-
pairs.push([key, nValue]);
|
|
775
|
-
}
|
|
776
|
-
} else if (earlyTerminate && hasMatched) {
|
|
841
|
+
if (direction === 1) {
|
|
842
|
+
if (!node.next) {
|
|
777
843
|
done = true;
|
|
778
844
|
break;
|
|
779
845
|
}
|
|
846
|
+
node = this.getNode(node.next);
|
|
847
|
+
} else {
|
|
848
|
+
if (!node.prev) {
|
|
849
|
+
done = true;
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
node = this.getNode(node.prev);
|
|
780
853
|
}
|
|
781
|
-
if (done) break;
|
|
782
|
-
if (!node.next) {
|
|
783
|
-
done = true;
|
|
784
|
-
break;
|
|
785
|
-
}
|
|
786
|
-
node = this.getNode(node.next);
|
|
787
|
-
}
|
|
788
|
-
return new Map(pairs);
|
|
789
|
-
}
|
|
790
|
-
getPairs(value, startNode, endNode, comparator, direction, earlyTerminate) {
|
|
791
|
-
switch (direction) {
|
|
792
|
-
case -1:
|
|
793
|
-
return this.getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate);
|
|
794
|
-
case 1:
|
|
795
|
-
return this.getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate);
|
|
796
|
-
default:
|
|
797
|
-
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
798
854
|
}
|
|
799
855
|
}
|
|
800
856
|
_createNodeId(isLeaf) {
|
|
@@ -1250,55 +1306,109 @@ var BPTreeSync = class extends BPTree {
|
|
|
1250
1306
|
}
|
|
1251
1307
|
this._nodeDeleteBuffer.clear();
|
|
1252
1308
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
if (
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1309
|
+
/**
|
|
1310
|
+
* Retrieves the value associated with the given key (PK).
|
|
1311
|
+
* Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
|
|
1312
|
+
*
|
|
1313
|
+
* @param key The key to search for.
|
|
1314
|
+
* @returns The value associated with the key, or undefined if not found.
|
|
1315
|
+
*/
|
|
1316
|
+
get(key) {
|
|
1317
|
+
let node = this.leftestNode();
|
|
1318
|
+
while (true) {
|
|
1319
|
+
if (node.values) {
|
|
1320
|
+
const len = node.values.length;
|
|
1321
|
+
for (let i = 0; i < len; i++) {
|
|
1322
|
+
const keys = node.keys[i];
|
|
1323
|
+
for (let j = 0; j < keys.length; j++) {
|
|
1324
|
+
if (keys[j] === key) {
|
|
1325
|
+
return node.values[i];
|
|
1326
|
+
}
|
|
1271
1327
|
}
|
|
1272
1328
|
}
|
|
1273
|
-
filterValues = intersections;
|
|
1274
1329
|
}
|
|
1330
|
+
if (!node.next) break;
|
|
1331
|
+
node = this.getNode(node.next);
|
|
1275
1332
|
}
|
|
1276
|
-
return
|
|
1333
|
+
return void 0;
|
|
1277
1334
|
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1335
|
+
*keysStream(condition, filterValues, limit) {
|
|
1336
|
+
const stream = this.whereStream(condition, limit);
|
|
1337
|
+
const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
|
|
1338
|
+
for (const [key] of stream) {
|
|
1339
|
+
if (intersection && !intersection.has(key)) {
|
|
1340
|
+
continue;
|
|
1341
|
+
}
|
|
1342
|
+
yield key;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
*whereStream(condition, limit) {
|
|
1346
|
+
let driverKey = null;
|
|
1347
|
+
if ("primaryEqual" in condition) driverKey = "primaryEqual";
|
|
1348
|
+
else if ("equal" in condition) driverKey = "equal";
|
|
1349
|
+
else if ("gt" in condition) driverKey = "gt";
|
|
1350
|
+
else if ("gte" in condition) driverKey = "gte";
|
|
1351
|
+
else if ("lt" in condition) driverKey = "lt";
|
|
1352
|
+
else if ("lte" in condition) driverKey = "lte";
|
|
1353
|
+
else if ("primaryGt" in condition) driverKey = "primaryGt";
|
|
1354
|
+
else if ("primaryGte" in condition) driverKey = "primaryGte";
|
|
1355
|
+
else if ("primaryLt" in condition) driverKey = "primaryLt";
|
|
1356
|
+
else if ("primaryLte" in condition) driverKey = "primaryLte";
|
|
1357
|
+
else if ("like" in condition) driverKey = "like";
|
|
1358
|
+
else if ("notEqual" in condition) driverKey = "notEqual";
|
|
1359
|
+
else if ("primaryNotEqual" in condition) driverKey = "primaryNotEqual";
|
|
1360
|
+
else if ("or" in condition) driverKey = "or";
|
|
1361
|
+
else if ("primaryOr" in condition) driverKey = "primaryOr";
|
|
1362
|
+
if (!driverKey) return;
|
|
1363
|
+
const value = condition[driverKey];
|
|
1364
|
+
const startNode = this.verifierStartNode[driverKey](value);
|
|
1365
|
+
const endNode = this.verifierEndNode[driverKey](value);
|
|
1366
|
+
const direction = this.verifierDirection[driverKey];
|
|
1367
|
+
const comparator = this.verifierMap[driverKey];
|
|
1368
|
+
const earlyTerminate = this.verifierEarlyTerminate[driverKey];
|
|
1369
|
+
const generator = this.getPairsGenerator(
|
|
1370
|
+
value,
|
|
1371
|
+
startNode,
|
|
1372
|
+
endNode,
|
|
1373
|
+
comparator,
|
|
1374
|
+
direction,
|
|
1375
|
+
earlyTerminate
|
|
1376
|
+
);
|
|
1377
|
+
let count = 0;
|
|
1378
|
+
for (const pair of generator) {
|
|
1379
|
+
const [k, v] = pair;
|
|
1380
|
+
let isMatch = true;
|
|
1381
|
+
for (const key in condition) {
|
|
1382
|
+
if (key === driverKey) continue;
|
|
1383
|
+
const verify = this.verifierMap[key];
|
|
1384
|
+
const condValue = condition[key];
|
|
1385
|
+
if (!verify(v, condValue)) {
|
|
1386
|
+
isMatch = false;
|
|
1387
|
+
break;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
if (isMatch) {
|
|
1391
|
+
yield pair;
|
|
1392
|
+
count++;
|
|
1393
|
+
if (limit !== void 0 && count >= limit) {
|
|
1394
|
+
break;
|
|
1297
1395
|
}
|
|
1298
|
-
result = intersection;
|
|
1299
1396
|
}
|
|
1300
1397
|
}
|
|
1301
|
-
|
|
1398
|
+
}
|
|
1399
|
+
keys(condition, filterValues) {
|
|
1400
|
+
const set = /* @__PURE__ */ new Set();
|
|
1401
|
+
for (const key of this.keysStream(condition, filterValues)) {
|
|
1402
|
+
set.add(key);
|
|
1403
|
+
}
|
|
1404
|
+
return set;
|
|
1405
|
+
}
|
|
1406
|
+
where(condition) {
|
|
1407
|
+
const map = /* @__PURE__ */ new Map();
|
|
1408
|
+
for (const [key, value] of this.whereStream(condition)) {
|
|
1409
|
+
map.set(key, value);
|
|
1410
|
+
}
|
|
1411
|
+
return map;
|
|
1302
1412
|
}
|
|
1303
1413
|
insert(key, value) {
|
|
1304
1414
|
const before = this.insertableNode(value);
|
|
@@ -1669,8 +1779,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1669
1779
|
this.lock.writeUnlock(lockId);
|
|
1670
1780
|
});
|
|
1671
1781
|
}
|
|
1672
|
-
async
|
|
1673
|
-
const pairs = [];
|
|
1782
|
+
async *getPairsGenerator(value, startNode, endNode, comparator, direction, earlyTerminate) {
|
|
1674
1783
|
let node = startNode;
|
|
1675
1784
|
let done = false;
|
|
1676
1785
|
let hasMatched = false;
|
|
@@ -1679,71 +1788,52 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1679
1788
|
done = true;
|
|
1680
1789
|
break;
|
|
1681
1790
|
}
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1791
|
+
const len = node.values.length;
|
|
1792
|
+
if (direction === 1) {
|
|
1793
|
+
for (let i = 0; i < len; i++) {
|
|
1794
|
+
const nValue = node.values[i];
|
|
1795
|
+
const keys = node.keys[i];
|
|
1796
|
+
if (comparator(nValue, value)) {
|
|
1797
|
+
hasMatched = true;
|
|
1798
|
+
for (let j = 0; j < keys.length; j++) {
|
|
1799
|
+
yield [keys[j], nValue];
|
|
1800
|
+
}
|
|
1801
|
+
} else if (earlyTerminate && hasMatched) {
|
|
1802
|
+
done = true;
|
|
1803
|
+
break;
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
} else {
|
|
1807
|
+
let i = len;
|
|
1808
|
+
while (i--) {
|
|
1809
|
+
const nValue = node.values[i];
|
|
1810
|
+
const keys = node.keys[i];
|
|
1811
|
+
if (comparator(nValue, value)) {
|
|
1812
|
+
hasMatched = true;
|
|
1813
|
+
let j = keys.length;
|
|
1814
|
+
while (j--) {
|
|
1815
|
+
yield [keys[j], nValue];
|
|
1816
|
+
}
|
|
1817
|
+
} else if (earlyTerminate && hasMatched) {
|
|
1818
|
+
done = true;
|
|
1819
|
+
break;
|
|
1691
1820
|
}
|
|
1692
|
-
} else if (earlyTerminate && hasMatched) {
|
|
1693
|
-
done = true;
|
|
1694
|
-
break;
|
|
1695
1821
|
}
|
|
1696
1822
|
}
|
|
1697
1823
|
if (done) break;
|
|
1698
|
-
if (
|
|
1699
|
-
|
|
1700
|
-
break;
|
|
1701
|
-
}
|
|
1702
|
-
node = await this.getNode(node.prev);
|
|
1703
|
-
}
|
|
1704
|
-
return new Map(pairs.reverse());
|
|
1705
|
-
}
|
|
1706
|
-
async getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate) {
|
|
1707
|
-
const pairs = [];
|
|
1708
|
-
let node = startNode;
|
|
1709
|
-
let done = false;
|
|
1710
|
-
let hasMatched = false;
|
|
1711
|
-
while (!done) {
|
|
1712
|
-
if (endNode && node.id === endNode.id) {
|
|
1713
|
-
done = true;
|
|
1714
|
-
break;
|
|
1715
|
-
}
|
|
1716
|
-
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1717
|
-
const nValue = node.values[i];
|
|
1718
|
-
const keys = node.keys[i];
|
|
1719
|
-
if (comparator(nValue, value)) {
|
|
1720
|
-
hasMatched = true;
|
|
1721
|
-
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
1722
|
-
const key = keys[j];
|
|
1723
|
-
pairs.push([key, nValue]);
|
|
1724
|
-
}
|
|
1725
|
-
} else if (earlyTerminate && hasMatched) {
|
|
1824
|
+
if (direction === 1) {
|
|
1825
|
+
if (!node.next) {
|
|
1726
1826
|
done = true;
|
|
1727
1827
|
break;
|
|
1728
1828
|
}
|
|
1829
|
+
node = await this.getNode(node.next);
|
|
1830
|
+
} else {
|
|
1831
|
+
if (!node.prev) {
|
|
1832
|
+
done = true;
|
|
1833
|
+
break;
|
|
1834
|
+
}
|
|
1835
|
+
node = await this.getNode(node.prev);
|
|
1729
1836
|
}
|
|
1730
|
-
if (done) break;
|
|
1731
|
-
if (!node.next) {
|
|
1732
|
-
done = true;
|
|
1733
|
-
break;
|
|
1734
|
-
}
|
|
1735
|
-
node = await this.getNode(node.next);
|
|
1736
|
-
}
|
|
1737
|
-
return new Map(pairs);
|
|
1738
|
-
}
|
|
1739
|
-
async getPairs(value, startNode, endNode, comparator, direction, earlyTerminate) {
|
|
1740
|
-
switch (direction) {
|
|
1741
|
-
case -1:
|
|
1742
|
-
return await this.getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate);
|
|
1743
|
-
case 1:
|
|
1744
|
-
return await this.getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate);
|
|
1745
|
-
default:
|
|
1746
|
-
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
1747
1837
|
}
|
|
1748
1838
|
}
|
|
1749
1839
|
async _createNodeId(isLeaf) {
|
|
@@ -2199,58 +2289,114 @@ var BPTreeAsync = class extends BPTree {
|
|
|
2199
2289
|
}
|
|
2200
2290
|
this._nodeDeleteBuffer.clear();
|
|
2201
2291
|
}
|
|
2202
|
-
|
|
2292
|
+
/**
|
|
2293
|
+
* Retrieves the value associated with the given key (PK).
|
|
2294
|
+
* Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
|
|
2295
|
+
*
|
|
2296
|
+
* @param key The key to search for.
|
|
2297
|
+
* @returns The value associated with the key, or undefined if not found.
|
|
2298
|
+
*/
|
|
2299
|
+
async get(key) {
|
|
2203
2300
|
return this.readLock(async () => {
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
filterValues = new Set(pairs.keys());
|
|
2215
|
-
} else {
|
|
2216
|
-
const intersections = /* @__PURE__ */ new Set();
|
|
2217
|
-
for (const key2 of filterValues) {
|
|
2218
|
-
const has = pairs.has(key2);
|
|
2219
|
-
if (has) {
|
|
2220
|
-
intersections.add(key2);
|
|
2301
|
+
let node = await this.leftestNode();
|
|
2302
|
+
while (true) {
|
|
2303
|
+
if (node.values) {
|
|
2304
|
+
const len = node.values.length;
|
|
2305
|
+
for (let i = 0; i < len; i++) {
|
|
2306
|
+
const keys = node.keys[i];
|
|
2307
|
+
for (let j = 0; j < keys.length; j++) {
|
|
2308
|
+
if (keys[j] === key) {
|
|
2309
|
+
return node.values[i];
|
|
2310
|
+
}
|
|
2221
2311
|
}
|
|
2222
2312
|
}
|
|
2223
|
-
filterValues = intersections;
|
|
2224
2313
|
}
|
|
2314
|
+
if (!node.next) break;
|
|
2315
|
+
node = await this.getNode(node.next);
|
|
2225
2316
|
}
|
|
2226
|
-
return
|
|
2317
|
+
return void 0;
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
async *keysStream(condition, filterValues, limit) {
|
|
2321
|
+
const stream = this.whereStream(condition, limit);
|
|
2322
|
+
const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
|
|
2323
|
+
for await (const [key] of stream) {
|
|
2324
|
+
if (intersection && !intersection.has(key)) {
|
|
2325
|
+
continue;
|
|
2326
|
+
}
|
|
2327
|
+
yield key;
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
async *whereStream(condition, limit) {
|
|
2331
|
+
let driverKey = null;
|
|
2332
|
+
if ("primaryEqual" in condition) driverKey = "primaryEqual";
|
|
2333
|
+
else if ("equal" in condition) driverKey = "equal";
|
|
2334
|
+
else if ("gt" in condition) driverKey = "gt";
|
|
2335
|
+
else if ("gte" in condition) driverKey = "gte";
|
|
2336
|
+
else if ("lt" in condition) driverKey = "lt";
|
|
2337
|
+
else if ("lte" in condition) driverKey = "lte";
|
|
2338
|
+
else if ("primaryGt" in condition) driverKey = "primaryGt";
|
|
2339
|
+
else if ("primaryGte" in condition) driverKey = "primaryGte";
|
|
2340
|
+
else if ("primaryLt" in condition) driverKey = "primaryLt";
|
|
2341
|
+
else if ("primaryLte" in condition) driverKey = "primaryLte";
|
|
2342
|
+
else if ("like" in condition) driverKey = "like";
|
|
2343
|
+
else if ("notEqual" in condition) driverKey = "notEqual";
|
|
2344
|
+
else if ("primaryNotEqual" in condition) driverKey = "primaryNotEqual";
|
|
2345
|
+
else if ("or" in condition) driverKey = "or";
|
|
2346
|
+
else if ("primaryOr" in condition) driverKey = "primaryOr";
|
|
2347
|
+
if (!driverKey) return;
|
|
2348
|
+
const value = condition[driverKey];
|
|
2349
|
+
const startNode = await this.verifierStartNode[driverKey](value);
|
|
2350
|
+
const endNode = await this.verifierEndNode[driverKey](value);
|
|
2351
|
+
const direction = this.verifierDirection[driverKey];
|
|
2352
|
+
const comparator = this.verifierMap[driverKey];
|
|
2353
|
+
const earlyTerminate = this.verifierEarlyTerminate[driverKey];
|
|
2354
|
+
const generator = this.getPairsGenerator(
|
|
2355
|
+
value,
|
|
2356
|
+
startNode,
|
|
2357
|
+
endNode,
|
|
2358
|
+
comparator,
|
|
2359
|
+
direction,
|
|
2360
|
+
earlyTerminate
|
|
2361
|
+
);
|
|
2362
|
+
let count = 0;
|
|
2363
|
+
for await (const pair of generator) {
|
|
2364
|
+
const [k, v] = pair;
|
|
2365
|
+
let isMatch = true;
|
|
2366
|
+
for (const key in condition) {
|
|
2367
|
+
if (key === driverKey) continue;
|
|
2368
|
+
const verify = this.verifierMap[key];
|
|
2369
|
+
const condValue = condition[key];
|
|
2370
|
+
if (!verify(v, condValue)) {
|
|
2371
|
+
isMatch = false;
|
|
2372
|
+
break;
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
if (isMatch) {
|
|
2376
|
+
yield pair;
|
|
2377
|
+
count++;
|
|
2378
|
+
if (limit !== void 0 && count >= limit) {
|
|
2379
|
+
break;
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
async keys(condition, filterValues) {
|
|
2385
|
+
return this.readLock(async () => {
|
|
2386
|
+
const set = /* @__PURE__ */ new Set();
|
|
2387
|
+
for await (const key of this.keysStream(condition, filterValues)) {
|
|
2388
|
+
set.add(key);
|
|
2389
|
+
}
|
|
2390
|
+
return set;
|
|
2227
2391
|
});
|
|
2228
2392
|
}
|
|
2229
2393
|
async where(condition) {
|
|
2230
2394
|
return this.readLock(async () => {
|
|
2231
|
-
|
|
2232
|
-
for (const
|
|
2233
|
-
|
|
2234
|
-
const value = condition[key];
|
|
2235
|
-
const startNode = await this.verifierStartNode[key](value);
|
|
2236
|
-
const endNode = await this.verifierEndNode[key](value);
|
|
2237
|
-
const direction = this.verifierDirection[key];
|
|
2238
|
-
const comparator = this.verifierMap[key];
|
|
2239
|
-
const earlyTerminate = this.verifierEarlyTerminate[key];
|
|
2240
|
-
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
|
|
2241
|
-
if (result === null) {
|
|
2242
|
-
result = pairs;
|
|
2243
|
-
} else {
|
|
2244
|
-
const intersection = /* @__PURE__ */ new Map();
|
|
2245
|
-
for (const [k2, v] of pairs) {
|
|
2246
|
-
if (result.has(k2)) {
|
|
2247
|
-
intersection.set(k2, v);
|
|
2248
|
-
}
|
|
2249
|
-
}
|
|
2250
|
-
result = intersection;
|
|
2251
|
-
}
|
|
2395
|
+
const map = /* @__PURE__ */ new Map();
|
|
2396
|
+
for await (const [key, value] of this.whereStream(condition)) {
|
|
2397
|
+
map.set(key, value);
|
|
2252
2398
|
}
|
|
2253
|
-
return
|
|
2399
|
+
return map;
|
|
2254
2400
|
});
|
|
2255
2401
|
}
|
|
2256
2402
|
async insert(key, value) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dataply",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
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.2.0"
|
|
51
51
|
}
|
|
52
52
|
}
|