serializable-bptree 6.1.1 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -432,7 +432,7 @@ var CacheEntanglementAsync = class extends CacheEntanglement {
432
432
  };
433
433
 
434
434
  // src/base/BPTree.ts
435
- var BPTree = class {
435
+ var BPTree = class _BPTree {
436
436
  _cachedRegexp;
437
437
  strategy;
438
438
  comparator;
@@ -460,7 +460,7 @@ var BPTree = class {
460
460
  primaryOr: (nv, v) => this.ensureValues(v).some((v2) => this.comparator.isPrimarySame(nv, v2)),
461
461
  like: (nv, v) => {
462
462
  const nodeValue = this.comparator.match(nv);
463
- const value = this.comparator.match(v);
463
+ const value = v;
464
464
  const cache = this._cachedRegexp.cache(value);
465
465
  const regexp = cache.raw;
466
466
  return regexp.test(nodeValue);
@@ -544,6 +544,82 @@ var BPTree = class {
544
544
  primaryOr: false,
545
545
  like: false
546
546
  };
547
+ /**
548
+ * Priority map for condition types.
549
+ * Higher value = higher selectivity (fewer expected results).
550
+ * Used by `chooseDriver` to select the most selective index.
551
+ */
552
+ static conditionPriority = {
553
+ equal: 100,
554
+ primaryEqual: 100,
555
+ or: 80,
556
+ primaryOr: 80,
557
+ gt: 50,
558
+ gte: 50,
559
+ lt: 50,
560
+ lte: 50,
561
+ primaryGt: 50,
562
+ primaryGte: 50,
563
+ primaryLt: 50,
564
+ primaryLte: 50,
565
+ like: 30,
566
+ notEqual: 10,
567
+ primaryNotEqual: 10
568
+ };
569
+ /**
570
+ * Selects the best driver tree from multiple tree/condition pairs.
571
+ * Uses rule-based optimization to choose the tree with highest estimated selectivity.
572
+ *
573
+ * @param candidates Array of { tree, condition } pairs to evaluate
574
+ * @returns The candidate with highest priority condition, or null if empty
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * const driver = BPTreeSync.chooseDriver([
579
+ * { tree: idxId, condition: { equal: 100 } },
580
+ * { tree: idxAge, condition: { gt: 20 } }
581
+ * ])
582
+ * // Returns { tree: idxId, condition: { equal: 100 } } because 'equal' has higher priority
583
+ * ```
584
+ */
585
+ static ChooseDriver(candidates) {
586
+ if (candidates.length === 0) return null;
587
+ if (candidates.length === 1) return candidates[0];
588
+ let best = candidates[0];
589
+ let bestScore = 0;
590
+ for (const candidate of candidates) {
591
+ let score = 0;
592
+ for (const key in candidate.condition) {
593
+ const condKey = key;
594
+ const priority = _BPTree.conditionPriority[condKey] ?? 0;
595
+ if (priority > score) {
596
+ score = priority;
597
+ }
598
+ }
599
+ if (score > bestScore) {
600
+ bestScore = score;
601
+ best = candidate;
602
+ }
603
+ }
604
+ return best;
605
+ }
606
+ /**
607
+ * Verified if the value satisfies the condition.
608
+ *
609
+ * @param nodeValue The value to verify.
610
+ * @param condition The condition to verify against.
611
+ * @returns Returns true if the value satisfies the condition.
612
+ */
613
+ verify(nodeValue, condition) {
614
+ for (const key in condition) {
615
+ const verify = this.verifierMap[key];
616
+ const condValue = condition[key];
617
+ if (!verify(nodeValue, condValue)) {
618
+ return false;
619
+ }
620
+ }
621
+ return true;
622
+ }
547
623
  constructor(strategy, comparator, option) {
548
624
  this.strategy = strategy;
549
625
  this.comparator = comparator;
@@ -664,8 +740,7 @@ var BPTreeSync = class extends BPTree {
664
740
  capacity: this.option.capacity ?? 1e3
665
741
  });
666
742
  }
667
- getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate) {
668
- const pairs = [];
743
+ *getPairsGenerator(value, startNode, endNode, comparator, direction, earlyTerminate) {
669
744
  let node = startNode;
670
745
  let done = false;
671
746
  let hasMatched = false;
@@ -674,71 +749,52 @@ var BPTreeSync = class extends BPTree {
674
749
  done = true;
675
750
  break;
676
751
  }
677
- let i = node.values.length;
678
- while (i--) {
679
- const nValue = node.values[i];
680
- const keys = node.keys[i];
681
- if (comparator(nValue, value)) {
682
- hasMatched = true;
683
- let j = keys.length;
684
- while (j--) {
685
- pairs.push([keys[j], nValue]);
752
+ const len = node.values.length;
753
+ if (direction === 1) {
754
+ for (let i = 0; i < len; i++) {
755
+ const nValue = node.values[i];
756
+ const keys = node.keys[i];
757
+ if (comparator(nValue, value)) {
758
+ hasMatched = true;
759
+ for (let j = 0; j < keys.length; j++) {
760
+ yield [keys[j], nValue];
761
+ }
762
+ } else if (earlyTerminate && hasMatched) {
763
+ done = true;
764
+ break;
765
+ }
766
+ }
767
+ } else {
768
+ let i = len;
769
+ while (i--) {
770
+ const nValue = node.values[i];
771
+ const keys = node.keys[i];
772
+ if (comparator(nValue, value)) {
773
+ hasMatched = true;
774
+ let j = keys.length;
775
+ while (j--) {
776
+ yield [keys[j], nValue];
777
+ }
778
+ } else if (earlyTerminate && hasMatched) {
779
+ done = true;
780
+ break;
686
781
  }
687
- } else if (earlyTerminate && hasMatched) {
688
- done = true;
689
- break;
690
782
  }
691
783
  }
692
784
  if (done) break;
693
- if (!node.prev) {
694
- done = true;
695
- break;
696
- }
697
- node = this.getNode(node.prev);
698
- }
699
- return new Map(pairs.reverse());
700
- }
701
- getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate) {
702
- const pairs = [];
703
- let node = startNode;
704
- let done = false;
705
- let hasMatched = false;
706
- while (!done) {
707
- if (endNode && node.id === endNode.id) {
708
- done = true;
709
- break;
710
- }
711
- for (let i = 0, len = node.values.length; i < len; i++) {
712
- const nValue = node.values[i];
713
- const keys = node.keys[i];
714
- if (comparator(nValue, value)) {
715
- hasMatched = true;
716
- for (let j = 0, len2 = keys.length; j < len2; j++) {
717
- const key = keys[j];
718
- pairs.push([key, nValue]);
719
- }
720
- } else if (earlyTerminate && hasMatched) {
785
+ if (direction === 1) {
786
+ if (!node.next) {
721
787
  done = true;
722
788
  break;
723
789
  }
790
+ node = this.getNode(node.next);
791
+ } else {
792
+ if (!node.prev) {
793
+ done = true;
794
+ break;
795
+ }
796
+ node = this.getNode(node.prev);
724
797
  }
725
- if (done) break;
726
- if (!node.next) {
727
- done = true;
728
- break;
729
- }
730
- node = this.getNode(node.next);
731
- }
732
- return new Map(pairs);
733
- }
734
- getPairs(value, startNode, endNode, comparator, direction, earlyTerminate) {
735
- switch (direction) {
736
- case -1:
737
- return this.getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate);
738
- case 1:
739
- return this.getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate);
740
- default:
741
- throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
742
798
  }
743
799
  }
744
800
  _createNodeId(isLeaf) {
@@ -1194,55 +1250,109 @@ var BPTreeSync = class extends BPTree {
1194
1250
  }
1195
1251
  this._nodeDeleteBuffer.clear();
1196
1252
  }
1197
- keys(condition, filterValues) {
1198
- for (const k in condition) {
1199
- const key = k;
1200
- const value = condition[key];
1201
- const startNode = this.verifierStartNode[key](value);
1202
- const endNode = this.verifierEndNode[key](value);
1203
- const direction = this.verifierDirection[key];
1204
- const comparator = this.verifierMap[key];
1205
- const earlyTerminate = this.verifierEarlyTerminate[key];
1206
- const pairs = this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
1207
- if (!filterValues) {
1208
- filterValues = new Set(pairs.keys());
1209
- } else {
1210
- const intersections = /* @__PURE__ */ new Set();
1211
- for (const key2 of filterValues) {
1212
- const has = pairs.has(key2);
1213
- if (has) {
1214
- intersections.add(key2);
1253
+ /**
1254
+ * Retrieves the value associated with the given key (PK).
1255
+ * Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
1256
+ *
1257
+ * @param key The key to search for.
1258
+ * @returns The value associated with the key, or undefined if not found.
1259
+ */
1260
+ get(key) {
1261
+ let node = this.leftestNode();
1262
+ while (true) {
1263
+ if (node.values) {
1264
+ const len = node.values.length;
1265
+ for (let i = 0; i < len; i++) {
1266
+ const keys = node.keys[i];
1267
+ for (let j = 0; j < keys.length; j++) {
1268
+ if (keys[j] === key) {
1269
+ return node.values[i];
1270
+ }
1215
1271
  }
1216
1272
  }
1217
- filterValues = intersections;
1218
1273
  }
1274
+ if (!node.next) break;
1275
+ node = this.getNode(node.next);
1219
1276
  }
1220
- return filterValues ?? /* @__PURE__ */ new Set([]);
1277
+ return void 0;
1221
1278
  }
1222
- where(condition) {
1223
- let result = null;
1224
- for (const k in condition) {
1225
- const key = k;
1226
- const value = condition[key];
1227
- const startNode = this.verifierStartNode[key](value);
1228
- const endNode = this.verifierEndNode[key](value);
1229
- const direction = this.verifierDirection[key];
1230
- const comparator = this.verifierMap[key];
1231
- const earlyTerminate = this.verifierEarlyTerminate[key];
1232
- const pairs = this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
1233
- if (result === null) {
1234
- result = pairs;
1235
- } else {
1236
- const intersection = /* @__PURE__ */ new Map();
1237
- for (const [k2, v] of pairs) {
1238
- if (result.has(k2)) {
1239
- intersection.set(k2, v);
1240
- }
1279
+ *keysStream(condition, filterValues, limit) {
1280
+ const stream = this.whereStream(condition, limit);
1281
+ const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
1282
+ for (const [key] of stream) {
1283
+ if (intersection && !intersection.has(key)) {
1284
+ continue;
1285
+ }
1286
+ yield key;
1287
+ }
1288
+ }
1289
+ *whereStream(condition, limit) {
1290
+ let driverKey = null;
1291
+ if ("primaryEqual" in condition) driverKey = "primaryEqual";
1292
+ else if ("equal" in condition) driverKey = "equal";
1293
+ else if ("gt" in condition) driverKey = "gt";
1294
+ else if ("gte" in condition) driverKey = "gte";
1295
+ else if ("lt" in condition) driverKey = "lt";
1296
+ else if ("lte" in condition) driverKey = "lte";
1297
+ else if ("primaryGt" in condition) driverKey = "primaryGt";
1298
+ else if ("primaryGte" in condition) driverKey = "primaryGte";
1299
+ else if ("primaryLt" in condition) driverKey = "primaryLt";
1300
+ else if ("primaryLte" in condition) driverKey = "primaryLte";
1301
+ else if ("like" in condition) driverKey = "like";
1302
+ else if ("notEqual" in condition) driverKey = "notEqual";
1303
+ else if ("primaryNotEqual" in condition) driverKey = "primaryNotEqual";
1304
+ else if ("or" in condition) driverKey = "or";
1305
+ else if ("primaryOr" in condition) driverKey = "primaryOr";
1306
+ if (!driverKey) return;
1307
+ const value = condition[driverKey];
1308
+ const startNode = this.verifierStartNode[driverKey](value);
1309
+ const endNode = this.verifierEndNode[driverKey](value);
1310
+ const direction = this.verifierDirection[driverKey];
1311
+ const comparator = this.verifierMap[driverKey];
1312
+ const earlyTerminate = this.verifierEarlyTerminate[driverKey];
1313
+ const generator = this.getPairsGenerator(
1314
+ value,
1315
+ startNode,
1316
+ endNode,
1317
+ comparator,
1318
+ direction,
1319
+ earlyTerminate
1320
+ );
1321
+ let count = 0;
1322
+ for (const pair of generator) {
1323
+ const [k, v] = pair;
1324
+ let isMatch = true;
1325
+ for (const key in condition) {
1326
+ if (key === driverKey) continue;
1327
+ const verify = this.verifierMap[key];
1328
+ const condValue = condition[key];
1329
+ if (!verify(v, condValue)) {
1330
+ isMatch = false;
1331
+ break;
1241
1332
  }
1242
- result = intersection;
1243
1333
  }
1334
+ if (isMatch) {
1335
+ yield pair;
1336
+ count++;
1337
+ if (limit !== void 0 && count >= limit) {
1338
+ break;
1339
+ }
1340
+ }
1341
+ }
1342
+ }
1343
+ keys(condition, filterValues) {
1344
+ const set = /* @__PURE__ */ new Set();
1345
+ for (const key of this.keysStream(condition, filterValues)) {
1346
+ set.add(key);
1244
1347
  }
1245
- return result ?? /* @__PURE__ */ new Map();
1348
+ return set;
1349
+ }
1350
+ where(condition) {
1351
+ const map = /* @__PURE__ */ new Map();
1352
+ for (const [key, value] of this.whereStream(condition)) {
1353
+ map.set(key, value);
1354
+ }
1355
+ return map;
1246
1356
  }
1247
1357
  insert(key, value) {
1248
1358
  const before = this.insertableNode(value);
@@ -1617,8 +1727,7 @@ var BPTreeAsync = class extends BPTree {
1617
1727
  this.lock.writeUnlock(lockId);
1618
1728
  });
1619
1729
  }
1620
- async getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate) {
1621
- const pairs = [];
1730
+ async *getPairsGenerator(value, startNode, endNode, comparator, direction, earlyTerminate) {
1622
1731
  let node = startNode;
1623
1732
  let done = false;
1624
1733
  let hasMatched = false;
@@ -1627,71 +1736,52 @@ var BPTreeAsync = class extends BPTree {
1627
1736
  done = true;
1628
1737
  break;
1629
1738
  }
1630
- let i = node.values.length;
1631
- while (i--) {
1632
- const nValue = node.values[i];
1633
- const keys = node.keys[i];
1634
- if (comparator(nValue, value)) {
1635
- hasMatched = true;
1636
- let j = keys.length;
1637
- while (j--) {
1638
- pairs.push([keys[j], nValue]);
1739
+ const len = node.values.length;
1740
+ if (direction === 1) {
1741
+ for (let i = 0; i < len; i++) {
1742
+ const nValue = node.values[i];
1743
+ const keys = node.keys[i];
1744
+ if (comparator(nValue, value)) {
1745
+ hasMatched = true;
1746
+ for (let j = 0; j < keys.length; j++) {
1747
+ yield [keys[j], nValue];
1748
+ }
1749
+ } else if (earlyTerminate && hasMatched) {
1750
+ done = true;
1751
+ break;
1752
+ }
1753
+ }
1754
+ } else {
1755
+ let i = len;
1756
+ while (i--) {
1757
+ const nValue = node.values[i];
1758
+ const keys = node.keys[i];
1759
+ if (comparator(nValue, value)) {
1760
+ hasMatched = true;
1761
+ let j = keys.length;
1762
+ while (j--) {
1763
+ yield [keys[j], nValue];
1764
+ }
1765
+ } else if (earlyTerminate && hasMatched) {
1766
+ done = true;
1767
+ break;
1639
1768
  }
1640
- } else if (earlyTerminate && hasMatched) {
1641
- done = true;
1642
- break;
1643
1769
  }
1644
1770
  }
1645
1771
  if (done) break;
1646
- if (!node.prev) {
1647
- done = true;
1648
- break;
1649
- }
1650
- node = await this.getNode(node.prev);
1651
- }
1652
- return new Map(pairs.reverse());
1653
- }
1654
- async getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate) {
1655
- const pairs = [];
1656
- let node = startNode;
1657
- let done = false;
1658
- let hasMatched = false;
1659
- while (!done) {
1660
- if (endNode && node.id === endNode.id) {
1661
- done = true;
1662
- break;
1663
- }
1664
- for (let i = 0, len = node.values.length; i < len; i++) {
1665
- const nValue = node.values[i];
1666
- const keys = node.keys[i];
1667
- if (comparator(nValue, value)) {
1668
- hasMatched = true;
1669
- for (let j = 0, len2 = keys.length; j < len2; j++) {
1670
- const key = keys[j];
1671
- pairs.push([key, nValue]);
1672
- }
1673
- } else if (earlyTerminate && hasMatched) {
1772
+ if (direction === 1) {
1773
+ if (!node.next) {
1674
1774
  done = true;
1675
1775
  break;
1676
1776
  }
1777
+ node = await this.getNode(node.next);
1778
+ } else {
1779
+ if (!node.prev) {
1780
+ done = true;
1781
+ break;
1782
+ }
1783
+ node = await this.getNode(node.prev);
1677
1784
  }
1678
- if (done) break;
1679
- if (!node.next) {
1680
- done = true;
1681
- break;
1682
- }
1683
- node = await this.getNode(node.next);
1684
- }
1685
- return new Map(pairs);
1686
- }
1687
- async getPairs(value, startNode, endNode, comparator, direction, earlyTerminate) {
1688
- switch (direction) {
1689
- case -1:
1690
- return await this.getPairsRightToLeft(value, startNode, endNode, comparator, earlyTerminate);
1691
- case 1:
1692
- return await this.getPairsLeftToRight(value, startNode, endNode, comparator, earlyTerminate);
1693
- default:
1694
- throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
1695
1785
  }
1696
1786
  }
1697
1787
  async _createNodeId(isLeaf) {
@@ -2147,58 +2237,114 @@ var BPTreeAsync = class extends BPTree {
2147
2237
  }
2148
2238
  this._nodeDeleteBuffer.clear();
2149
2239
  }
2150
- async keys(condition, filterValues) {
2240
+ /**
2241
+ * Retrieves the value associated with the given key (PK).
2242
+ * Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
2243
+ *
2244
+ * @param key The key to search for.
2245
+ * @returns The value associated with the key, or undefined if not found.
2246
+ */
2247
+ async get(key) {
2151
2248
  return this.readLock(async () => {
2152
- for (const k in condition) {
2153
- const key = k;
2154
- const value = condition[key];
2155
- const startNode = await this.verifierStartNode[key](value);
2156
- const endNode = await this.verifierEndNode[key](value);
2157
- const direction = this.verifierDirection[key];
2158
- const comparator = this.verifierMap[key];
2159
- const earlyTerminate = this.verifierEarlyTerminate[key];
2160
- const pairs = await this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
2161
- if (!filterValues) {
2162
- filterValues = new Set(pairs.keys());
2163
- } else {
2164
- const intersections = /* @__PURE__ */ new Set();
2165
- for (const key2 of filterValues) {
2166
- const has = pairs.has(key2);
2167
- if (has) {
2168
- intersections.add(key2);
2249
+ let node = await this.leftestNode();
2250
+ while (true) {
2251
+ if (node.values) {
2252
+ const len = node.values.length;
2253
+ for (let i = 0; i < len; i++) {
2254
+ const keys = node.keys[i];
2255
+ for (let j = 0; j < keys.length; j++) {
2256
+ if (keys[j] === key) {
2257
+ return node.values[i];
2258
+ }
2169
2259
  }
2170
2260
  }
2171
- filterValues = intersections;
2172
2261
  }
2262
+ if (!node.next) break;
2263
+ node = await this.getNode(node.next);
2173
2264
  }
2174
- return filterValues ?? /* @__PURE__ */ new Set([]);
2265
+ return void 0;
2266
+ });
2267
+ }
2268
+ async *keysStream(condition, filterValues, limit) {
2269
+ const stream = this.whereStream(condition, limit);
2270
+ const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2271
+ for await (const [key] of stream) {
2272
+ if (intersection && !intersection.has(key)) {
2273
+ continue;
2274
+ }
2275
+ yield key;
2276
+ }
2277
+ }
2278
+ async *whereStream(condition, limit) {
2279
+ let driverKey = null;
2280
+ if ("primaryEqual" in condition) driverKey = "primaryEqual";
2281
+ else if ("equal" in condition) driverKey = "equal";
2282
+ else if ("gt" in condition) driverKey = "gt";
2283
+ else if ("gte" in condition) driverKey = "gte";
2284
+ else if ("lt" in condition) driverKey = "lt";
2285
+ else if ("lte" in condition) driverKey = "lte";
2286
+ else if ("primaryGt" in condition) driverKey = "primaryGt";
2287
+ else if ("primaryGte" in condition) driverKey = "primaryGte";
2288
+ else if ("primaryLt" in condition) driverKey = "primaryLt";
2289
+ else if ("primaryLte" in condition) driverKey = "primaryLte";
2290
+ else if ("like" in condition) driverKey = "like";
2291
+ else if ("notEqual" in condition) driverKey = "notEqual";
2292
+ else if ("primaryNotEqual" in condition) driverKey = "primaryNotEqual";
2293
+ else if ("or" in condition) driverKey = "or";
2294
+ else if ("primaryOr" in condition) driverKey = "primaryOr";
2295
+ if (!driverKey) return;
2296
+ const value = condition[driverKey];
2297
+ const startNode = await this.verifierStartNode[driverKey](value);
2298
+ const endNode = await this.verifierEndNode[driverKey](value);
2299
+ const direction = this.verifierDirection[driverKey];
2300
+ const comparator = this.verifierMap[driverKey];
2301
+ const earlyTerminate = this.verifierEarlyTerminate[driverKey];
2302
+ const generator = this.getPairsGenerator(
2303
+ value,
2304
+ startNode,
2305
+ endNode,
2306
+ comparator,
2307
+ direction,
2308
+ earlyTerminate
2309
+ );
2310
+ let count = 0;
2311
+ for await (const pair of generator) {
2312
+ const [k, v] = pair;
2313
+ let isMatch = true;
2314
+ for (const key in condition) {
2315
+ if (key === driverKey) continue;
2316
+ const verify = this.verifierMap[key];
2317
+ const condValue = condition[key];
2318
+ if (!verify(v, condValue)) {
2319
+ isMatch = false;
2320
+ break;
2321
+ }
2322
+ }
2323
+ if (isMatch) {
2324
+ yield pair;
2325
+ count++;
2326
+ if (limit !== void 0 && count >= limit) {
2327
+ break;
2328
+ }
2329
+ }
2330
+ }
2331
+ }
2332
+ async keys(condition, filterValues) {
2333
+ return this.readLock(async () => {
2334
+ const set = /* @__PURE__ */ new Set();
2335
+ for await (const key of this.keysStream(condition, filterValues)) {
2336
+ set.add(key);
2337
+ }
2338
+ return set;
2175
2339
  });
2176
2340
  }
2177
2341
  async where(condition) {
2178
2342
  return this.readLock(async () => {
2179
- let result = null;
2180
- for (const k in condition) {
2181
- const key = k;
2182
- const value = condition[key];
2183
- const startNode = await this.verifierStartNode[key](value);
2184
- const endNode = await this.verifierEndNode[key](value);
2185
- const direction = this.verifierDirection[key];
2186
- const comparator = this.verifierMap[key];
2187
- const earlyTerminate = this.verifierEarlyTerminate[key];
2188
- const pairs = await this.getPairs(value, startNode, endNode, comparator, direction, earlyTerminate);
2189
- if (result === null) {
2190
- result = pairs;
2191
- } else {
2192
- const intersection = /* @__PURE__ */ new Map();
2193
- for (const [k2, v] of pairs) {
2194
- if (result.has(k2)) {
2195
- intersection.set(k2, v);
2196
- }
2197
- }
2198
- result = intersection;
2199
- }
2343
+ const map = /* @__PURE__ */ new Map();
2344
+ for await (const [key, value] of this.whereStream(condition)) {
2345
+ map.set(key, value);
2200
2346
  }
2201
- return result ?? /* @__PURE__ */ new Map();
2347
+ return map;
2202
2348
  });
2203
2349
  }
2204
2350
  async insert(key, value) {
@@ -10,9 +10,7 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
10
10
  private _createCachedNode;
11
11
  protected readLock<T>(callback: () => Promise<T>): Promise<T>;
12
12
  protected writeLock<T>(callback: () => Promise<T>): Promise<T>;
13
- protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, earlyTerminate: boolean): Promise<BPTreePair<K, V>>;
14
- protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, earlyTerminate: boolean): Promise<BPTreePair<K, V>>;
15
- protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1, earlyTerminate: boolean): Promise<BPTreePair<K, V>>;
13
+ protected getPairsGenerator(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1, earlyTerminate: boolean): AsyncGenerator<[K, V]>;
16
14
  protected _createNodeId(isLeaf: boolean): Promise<string>;
17
15
  protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
18
16
  protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Promise<void>;
@@ -34,6 +32,16 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
34
32
  protected commitNodeCreateBuffer(): Promise<void>;
35
33
  protected commitNodeUpdateBuffer(): Promise<void>;
36
34
  protected commitNodeDeleteBuffer(): Promise<void>;
35
+ /**
36
+ * Retrieves the value associated with the given key (PK).
37
+ * Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
38
+ *
39
+ * @param key The key to search for.
40
+ * @returns The value associated with the key, or undefined if not found.
41
+ */
42
+ get(key: K): Promise<V | undefined>;
43
+ keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): AsyncGenerator<K>;
44
+ whereStream(condition: BPTreeCondition<V>, limit?: number): AsyncGenerator<[K, V]>;
37
45
  keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Promise<Set<K>>;
38
46
  where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>>;
39
47
  insert(key: K, value: V): Promise<void>;