serializable-bptree 8.3.3 → 8.3.5

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.
@@ -94,39 +94,125 @@ var StringComparator = class extends ValueComparator {
94
94
  var MVCCStrategy = class {
95
95
  };
96
96
  var LRUMap = class {
97
- cache = /* @__PURE__ */ new Map();
98
97
  capacity;
98
+ map;
99
+ head = null;
100
+ tail = null;
101
+ /**
102
+ * Creates an instance of LRUMap.
103
+ * @param capacity The maximum number of items the cache can hold.
104
+ */
99
105
  constructor(capacity) {
100
106
  this.capacity = capacity;
107
+ this.map = /* @__PURE__ */ new Map();
101
108
  }
102
- get(key) {
103
- if (!this.cache.has(key)) return void 0;
104
- const value = this.cache.get(key);
105
- this.cache.delete(key);
106
- this.cache.set(key, value);
107
- return value;
109
+ /**
110
+ * Promotes a node to the head of the linked list (marks as most recently used).
111
+ * @param node The node to promote.
112
+ */
113
+ promote(node) {
114
+ this.extract(node);
115
+ this.prepend(node);
108
116
  }
117
+ /**
118
+ * Disconnects a node from the doubly linked list.
119
+ * @param node The node to extract.
120
+ */
121
+ extract(node) {
122
+ if (node.prev) node.prev.next = node.next;
123
+ else this.head = node.next;
124
+ if (node.next) node.next.prev = node.prev;
125
+ else this.tail = node.prev;
126
+ node.prev = null;
127
+ node.next = null;
128
+ }
129
+ /**
130
+ * Inserts a node at the head of the doubly linked list.
131
+ * @param node The node to prepend.
132
+ */
133
+ prepend(node) {
134
+ node.next = this.head;
135
+ if (this.head) this.head.prev = node;
136
+ this.head = node;
137
+ if (!this.tail) this.tail = node;
138
+ }
139
+ /**
140
+ * Stores or updates a value by key.
141
+ * If the capacity is exceeded, the least recently used item (tail) is removed.
142
+ * @param key The key to store.
143
+ * @param value The value to store.
144
+ */
109
145
  set(key, value) {
110
- if (this.cache.has(key)) {
111
- this.cache.delete(key);
112
- } else if (this.cache.size >= this.capacity) {
113
- const oldestKey = this.cache.keys().next().value;
114
- if (oldestKey !== void 0) this.cache.delete(oldestKey);
146
+ const existing = this.map.get(key);
147
+ if (existing) {
148
+ existing.value = value;
149
+ this.promote(existing);
150
+ return;
115
151
  }
116
- this.cache.set(key, value);
117
- return this;
152
+ const newNode = { key, value, prev: null, next: null };
153
+ this.map.set(key, newNode);
154
+ this.prepend(newNode);
155
+ if (this.map.size > this.capacity && this.tail) {
156
+ this.map.delete(this.tail.key);
157
+ this.extract(this.tail);
158
+ }
159
+ }
160
+ /**
161
+ * Retrieves a value by key.
162
+ * Accessing the item moves it to the "most recently used" position.
163
+ * @param key The key to look for.
164
+ * @returns The value associated with the key, or undefined if not found.
165
+ */
166
+ get(key) {
167
+ const node = this.map.get(key);
168
+ if (!node) return void 0;
169
+ this.promote(node);
170
+ return node.value;
118
171
  }
172
+ /**
173
+ * Checks if a key exists in the cache without changing its access order.
174
+ * @param key The key to check.
175
+ * @returns True if the key exists, false otherwise.
176
+ */
119
177
  has(key) {
120
- return this.cache.has(key);
178
+ return this.map.has(key);
121
179
  }
180
+ /**
181
+ * Removes a key and its associated value from the cache.
182
+ * @param key The key to remove.
183
+ * @returns True if the key was found and removed, false otherwise.
184
+ */
122
185
  delete(key) {
123
- return this.cache.delete(key);
186
+ const node = this.map.get(key);
187
+ if (!node) return false;
188
+ this.extract(node);
189
+ this.map.delete(key);
190
+ return true;
124
191
  }
125
- clear() {
126
- this.cache.clear();
192
+ /**
193
+ * Returns an iterator of keys in the order of most recently used to least recently used.
194
+ * @returns An iterable iterator of keys.
195
+ */
196
+ *keys() {
197
+ let current = this.head;
198
+ while (current) {
199
+ yield current.key;
200
+ current = current.next;
201
+ }
127
202
  }
203
+ /**
204
+ * Returns the current number of items in the cache.
205
+ */
128
206
  get size() {
129
- return this.cache.size;
207
+ return this.map.size;
208
+ }
209
+ /**
210
+ * Clears all items from the cache.
211
+ */
212
+ clear() {
213
+ this.map.clear();
214
+ this.head = null;
215
+ this.tail = null;
130
216
  }
131
217
  };
132
218
  var MVCCTransaction = class {
@@ -1522,28 +1608,28 @@ var BPTreeTransaction = class _BPTreeTransaction {
1522
1608
  searchConfigs = {
1523
1609
  gt: {
1524
1610
  asc: {
1525
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1611
+ start: (tx, v) => tx.findUpperBoundLeaf(v[0]),
1526
1612
  end: () => null,
1527
1613
  direction: 1,
1528
1614
  earlyTerminate: false
1529
1615
  },
1530
1616
  desc: {
1531
1617
  start: (tx) => tx.rightestNode(),
1532
- end: (tx, v) => tx.insertableEndNode(v[0], -1),
1618
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], -1),
1533
1619
  direction: -1,
1534
1620
  earlyTerminate: true
1535
1621
  }
1536
1622
  },
1537
1623
  gte: {
1538
1624
  asc: {
1539
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1625
+ start: (tx, v) => tx.findLowerBoundLeaf(v[0]),
1540
1626
  end: () => null,
1541
1627
  direction: 1,
1542
1628
  earlyTerminate: false
1543
1629
  },
1544
1630
  desc: {
1545
1631
  start: (tx) => tx.rightestNode(),
1546
- end: (tx, v) => tx.insertableEndNode(v[0], -1),
1632
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], -1),
1547
1633
  direction: -1,
1548
1634
  earlyTerminate: true
1549
1635
  }
@@ -1551,12 +1637,12 @@ var BPTreeTransaction = class _BPTreeTransaction {
1551
1637
  lt: {
1552
1638
  asc: {
1553
1639
  start: (tx) => tx.leftestNode(),
1554
- end: (tx, v) => tx.insertableEndNode(v[0], 1),
1640
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1555
1641
  direction: 1,
1556
1642
  earlyTerminate: true
1557
1643
  },
1558
1644
  desc: {
1559
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1645
+ start: (tx, v) => tx.findLowerBoundLeaf(v[0]),
1560
1646
  end: () => null,
1561
1647
  direction: -1,
1562
1648
  earlyTerminate: false
@@ -1565,12 +1651,12 @@ var BPTreeTransaction = class _BPTreeTransaction {
1565
1651
  lte: {
1566
1652
  asc: {
1567
1653
  start: (tx) => tx.leftestNode(),
1568
- end: (tx, v) => tx.insertableEndNode(v[0], 1),
1654
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1569
1655
  direction: 1,
1570
1656
  earlyTerminate: true
1571
1657
  },
1572
1658
  desc: {
1573
- start: (tx, v) => tx.insertableRightestNodeByPrimary(v[0]),
1659
+ start: (tx, v) => tx.findUpperBoundLeaf(v[0]),
1574
1660
  end: () => null,
1575
1661
  direction: -1,
1576
1662
  earlyTerminate: false
@@ -1578,14 +1664,14 @@ var BPTreeTransaction = class _BPTreeTransaction {
1578
1664
  },
1579
1665
  equal: {
1580
1666
  asc: {
1581
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1582
- end: (tx, v) => tx.insertableEndNode(v[0], 1),
1667
+ start: (tx, v) => tx.findLowerBoundLeaf(v[0]),
1668
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1583
1669
  direction: 1,
1584
1670
  earlyTerminate: true
1585
1671
  },
1586
1672
  desc: {
1587
- start: (tx, v) => tx.insertableEndNode(v[0], 1),
1588
- end: (tx, v) => tx.insertableEndNode(v[0], -1),
1673
+ start: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1674
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], -1),
1589
1675
  direction: -1,
1590
1676
  earlyTerminate: true
1591
1677
  }
@@ -1606,42 +1692,42 @@ var BPTreeTransaction = class _BPTreeTransaction {
1606
1692
  },
1607
1693
  or: {
1608
1694
  asc: {
1609
- start: (tx, v) => tx.insertableNodeByPrimary(tx.lowestValue(v)),
1610
- end: (tx, v) => tx.insertableEndNode(tx.highestValue(v), 1),
1695
+ start: (tx, v) => tx.findLowerBoundLeaf(tx.lowestValue(v)),
1696
+ end: (tx, v) => tx.findOuterBoundaryLeaf(tx.highestValue(v), 1),
1611
1697
  direction: 1,
1612
1698
  earlyTerminate: false
1613
1699
  },
1614
1700
  desc: {
1615
- start: (tx, v) => tx.insertableEndNode(tx.highestValue(v), 1),
1616
- end: (tx, v) => tx.insertableEndNode(tx.lowestValue(v), -1),
1701
+ start: (tx, v) => tx.findOuterBoundaryLeaf(tx.highestValue(v), 1),
1702
+ end: (tx, v) => tx.findOuterBoundaryLeaf(tx.lowestValue(v), -1),
1617
1703
  direction: -1,
1618
1704
  earlyTerminate: false
1619
1705
  }
1620
1706
  },
1621
1707
  primaryGt: {
1622
1708
  asc: {
1623
- start: (tx, v) => tx.insertableRightestEndNodeByPrimary(v[0]),
1709
+ start: (tx, v) => tx.findUpperBoundLeaf(v[0]),
1624
1710
  end: () => null,
1625
1711
  direction: 1,
1626
1712
  earlyTerminate: false
1627
1713
  },
1628
1714
  desc: {
1629
1715
  start: (tx) => tx.rightestNode(),
1630
- end: (tx, v) => tx.insertableEndNode(v[0], -1),
1716
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], -1),
1631
1717
  direction: -1,
1632
1718
  earlyTerminate: true
1633
1719
  }
1634
1720
  },
1635
1721
  primaryGte: {
1636
1722
  asc: {
1637
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1723
+ start: (tx, v) => tx.findLowerBoundLeaf(v[0]),
1638
1724
  end: () => null,
1639
1725
  direction: 1,
1640
1726
  earlyTerminate: false
1641
1727
  },
1642
1728
  desc: {
1643
1729
  start: (tx) => tx.rightestNode(),
1644
- end: (tx, v) => tx.insertableEndNode(v[0], -1),
1730
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], -1),
1645
1731
  direction: -1,
1646
1732
  earlyTerminate: true
1647
1733
  }
@@ -1649,12 +1735,12 @@ var BPTreeTransaction = class _BPTreeTransaction {
1649
1735
  primaryLt: {
1650
1736
  asc: {
1651
1737
  start: (tx) => tx.leftestNode(),
1652
- end: (tx, v) => tx.insertableEndNode(v[0], 1),
1738
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1653
1739
  direction: 1,
1654
1740
  earlyTerminate: true
1655
1741
  },
1656
1742
  desc: {
1657
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1743
+ start: (tx, v) => tx.findLowerBoundLeaf(v[0]),
1658
1744
  end: () => null,
1659
1745
  direction: -1,
1660
1746
  earlyTerminate: false
@@ -1663,12 +1749,12 @@ var BPTreeTransaction = class _BPTreeTransaction {
1663
1749
  primaryLte: {
1664
1750
  asc: {
1665
1751
  start: (tx) => tx.leftestNode(),
1666
- end: (tx, v) => tx.insertableEndNode(v[0], 1),
1752
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1667
1753
  direction: 1,
1668
1754
  earlyTerminate: true
1669
1755
  },
1670
1756
  desc: {
1671
- start: (tx, v) => tx.insertableRightestNodeByPrimary(v[0]),
1757
+ start: (tx, v) => tx.findUpperBoundLeaf(v[0]),
1672
1758
  end: () => null,
1673
1759
  direction: -1,
1674
1760
  earlyTerminate: false
@@ -1676,14 +1762,14 @@ var BPTreeTransaction = class _BPTreeTransaction {
1676
1762
  },
1677
1763
  primaryEqual: {
1678
1764
  asc: {
1679
- start: (tx, v) => tx.insertableNodeByPrimary(v[0]),
1680
- end: (tx, v) => tx.insertableRightestEndNodeByPrimary(v[0]),
1765
+ start: (tx, v) => tx.findLowerBoundLeaf(v[0]),
1766
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], 1),
1681
1767
  direction: 1,
1682
1768
  earlyTerminate: true
1683
1769
  },
1684
1770
  desc: {
1685
- start: (tx, v) => tx.insertableRightestEndNodeByPrimary(v[0]),
1686
- end: (tx, v) => tx.insertableEndNode(v[0], -1),
1771
+ start: (tx, v) => tx.findUpperBoundLeaf(v[0]),
1772
+ end: (tx, v) => tx.findOuterBoundaryLeaf(v[0], -1),
1687
1773
  direction: -1,
1688
1774
  earlyTerminate: true
1689
1775
  }
@@ -1704,14 +1790,14 @@ var BPTreeTransaction = class _BPTreeTransaction {
1704
1790
  },
1705
1791
  primaryOr: {
1706
1792
  asc: {
1707
- start: (tx, v) => tx.insertableNodeByPrimary(tx.lowestPrimaryValue(v)),
1708
- end: (tx, v) => tx.insertableRightestEndNodeByPrimary(tx.highestPrimaryValue(v)),
1793
+ start: (tx, v) => tx.findLowerBoundLeaf(tx.lowestPrimaryValue(v)),
1794
+ end: (tx, v) => tx.findOuterBoundaryLeaf(tx.highestPrimaryValue(v), 1),
1709
1795
  direction: 1,
1710
1796
  earlyTerminate: false
1711
1797
  },
1712
1798
  desc: {
1713
- start: (tx, v) => tx.insertableRightestEndNodeByPrimary(tx.highestPrimaryValue(v)),
1714
- end: (tx, v) => tx.insertableEndNode(tx.lowestPrimaryValue(v), -1),
1799
+ start: (tx, v) => tx.findUpperBoundLeaf(tx.highestPrimaryValue(v)),
1800
+ end: (tx, v) => tx.findOuterBoundaryLeaf(tx.lowestPrimaryValue(v), -1),
1715
1801
  direction: -1,
1716
1802
  earlyTerminate: false
1717
1803
  }
@@ -1867,30 +1953,69 @@ var BPTreeTransaction = class _BPTreeTransaction {
1867
1953
  return JSON.parse(JSON.stringify(node));
1868
1954
  }
1869
1955
  /**
1870
- * Selects the best driver key from a condition object.
1871
- * The driver key determines the starting point and traversal direction for queries.
1872
- *
1956
+ * Resolves the best start/end configuration by independently examining
1957
+ * all conditions. Selects the tightest lower bound for start and the
1958
+ * tightest upper bound for end (in asc; reversed for desc).
1959
+ *
1873
1960
  * @param condition The condition to analyze.
1874
- * @returns The best driver key or null if no valid key found.
1961
+ * @param order The sort order ('asc' or 'desc').
1962
+ * @returns The resolved start/end keys, values, and traversal direction.
1875
1963
  */
1876
- getDriverKey(condition) {
1877
- if ("primaryEqual" in condition) return "primaryEqual";
1878
- if ("equal" in condition) return "equal";
1879
- if ("gt" in condition) return "gt";
1880
- if ("gte" in condition) return "gte";
1881
- if ("lt" in condition) return "lt";
1882
- if ("lte" in condition) return "lte";
1883
- if ("primaryGt" in condition) return "primaryGt";
1884
- if ("primaryGte" in condition) return "primaryGte";
1885
- if ("primaryLt" in condition) return "primaryLt";
1886
- if ("primaryLte" in condition) return "primaryLte";
1887
- if ("like" in condition) return "like";
1888
- if ("notEqual" in condition) return "notEqual";
1889
- if ("primaryNotEqual" in condition) return "primaryNotEqual";
1890
- if ("or" in condition) return "or";
1891
- if ("primaryOr" in condition) return "primaryOr";
1892
- return null;
1893
- }
1964
+ resolveStartEndConfigs(condition, order) {
1965
+ const direction = order === "asc" ? 1 : -1;
1966
+ const startCandidates = order === "asc" ? _BPTreeTransaction._lowerBoundKeys : _BPTreeTransaction._upperBoundKeys;
1967
+ const endCandidates = order === "asc" ? _BPTreeTransaction._upperBoundKeys : _BPTreeTransaction._lowerBoundKeys;
1968
+ let startKey = null;
1969
+ let endKey = null;
1970
+ let startValues = [];
1971
+ let endValues = [];
1972
+ for (let i = 0, len = startCandidates.length; i < len; i++) {
1973
+ const key = startCandidates[i];
1974
+ if (key in condition) {
1975
+ startKey = key;
1976
+ startValues = _BPTreeTransaction._multiValueKeys.includes(key) ? this.ensureValues(condition[key]) : [condition[key]];
1977
+ break;
1978
+ }
1979
+ }
1980
+ for (let i = 0, len = endCandidates.length; i < len; i++) {
1981
+ const key = endCandidates[i];
1982
+ if (key in condition) {
1983
+ endKey = key;
1984
+ endValues = _BPTreeTransaction._multiValueKeys.includes(key) ? this.ensureValues(condition[key]) : [condition[key]];
1985
+ break;
1986
+ }
1987
+ }
1988
+ return { startKey, endKey, startValues, endValues, direction };
1989
+ }
1990
+ // Lower bound providers, ordered by selectivity (tightest first)
1991
+ // Used for asc start / desc end
1992
+ static _lowerBoundKeys = [
1993
+ "primaryEqual",
1994
+ "equal",
1995
+ "primaryGt",
1996
+ "gt",
1997
+ "primaryGte",
1998
+ "gte",
1999
+ "primaryOr",
2000
+ "or"
2001
+ ];
2002
+ // Upper bound providers, ordered by selectivity (tightest first)
2003
+ // Used for asc end / desc start
2004
+ static _upperBoundKeys = [
2005
+ "primaryEqual",
2006
+ "equal",
2007
+ "primaryLt",
2008
+ "lt",
2009
+ "primaryLte",
2010
+ "lte",
2011
+ "primaryOr",
2012
+ "or"
2013
+ ];
2014
+ // Condition keys that accept multiple values (V[]) rather than a single value (V)
2015
+ static _multiValueKeys = [
2016
+ "or",
2017
+ "primaryOr"
2018
+ ];
1894
2019
  constructor(rootTx, mvccRoot, mvcc, strategy, comparator, option) {
1895
2020
  this.rootTx = rootTx === null ? this : rootTx;
1896
2021
  this.mvccRoot = mvccRoot;
@@ -2129,7 +2254,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2129
2254
  this._insertInParent(parentNode, midValue, newSiblingNodeRecursive);
2130
2255
  }
2131
2256
  }
2132
- insertableNode(value) {
2257
+ locateLeaf(value) {
2133
2258
  let node = this.getNode(this.rootId);
2134
2259
  while (!node.leaf) {
2135
2260
  const { index } = this._binarySearchValues(node.values, value, false, true);
@@ -2137,7 +2262,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2137
2262
  }
2138
2263
  return node;
2139
2264
  }
2140
- insertableNodeByPrimary(value) {
2265
+ findLowerBoundLeaf(value) {
2141
2266
  let node = this.getNode(this.rootId);
2142
2267
  while (!node.leaf) {
2143
2268
  const { index } = this._binarySearchValues(node.values, value, true, false);
@@ -2145,7 +2270,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2145
2270
  }
2146
2271
  return node;
2147
2272
  }
2148
- insertableRightestNodeByPrimary(value) {
2273
+ findUpperBoundLeaf(value) {
2149
2274
  let node = this.getNode(this.rootId);
2150
2275
  while (!node.leaf) {
2151
2276
  const { index } = this._binarySearchValues(node.values, value, true, true);
@@ -2153,15 +2278,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2153
2278
  }
2154
2279
  return node;
2155
2280
  }
2156
- insertableRightestEndNodeByPrimary(value) {
2157
- const node = this.insertableRightestNodeByPrimary(value);
2158
- if (!node.next) {
2159
- return null;
2160
- }
2161
- return this.getNode(node.next);
2162
- }
2163
- insertableEndNode(value, direction) {
2164
- const insertableNode = direction === -1 ? this.insertableNodeByPrimary(value) : this.insertableRightestNodeByPrimary(value);
2281
+ findOuterBoundaryLeaf(value, direction) {
2282
+ const insertableNode = direction === -1 ? this.findLowerBoundLeaf(value) : this.findUpperBoundLeaf(value);
2165
2283
  let key;
2166
2284
  switch (direction) {
2167
2285
  case -1:
@@ -2198,13 +2316,10 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2198
2316
  }
2199
2317
  return node;
2200
2318
  }
2201
- *getPairsGenerator(value, startNode, endNode, comparator, direction, earlyTerminate) {
2319
+ *getPairsGenerator(startNode, endNode, direction) {
2202
2320
  let node = startNode;
2203
- let done = false;
2204
- let hasMatched = false;
2205
- while (!done) {
2321
+ while (true) {
2206
2322
  if (endNode && node.id === endNode.id) {
2207
- done = true;
2208
2323
  break;
2209
2324
  }
2210
2325
  const len = node.values.length;
@@ -2212,14 +2327,8 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2212
2327
  for (let i = 0; i < len; i++) {
2213
2328
  const nValue = node.values[i];
2214
2329
  const keys = node.keys[i];
2215
- if (comparator(nValue, value)) {
2216
- hasMatched = true;
2217
- for (let j = 0; j < keys.length; j++) {
2218
- yield [keys[j], nValue];
2219
- }
2220
- } else if (earlyTerminate && hasMatched) {
2221
- done = true;
2222
- break;
2330
+ for (let j = 0, kLen = keys.length; j < kLen; j++) {
2331
+ yield [keys[j], nValue];
2223
2332
  }
2224
2333
  }
2225
2334
  } else {
@@ -2227,30 +2336,17 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2227
2336
  while (i--) {
2228
2337
  const nValue = node.values[i];
2229
2338
  const keys = node.keys[i];
2230
- if (comparator(nValue, value)) {
2231
- hasMatched = true;
2232
- let j = keys.length;
2233
- while (j--) {
2234
- yield [keys[j], nValue];
2235
- }
2236
- } else if (earlyTerminate && hasMatched) {
2237
- done = true;
2238
- break;
2339
+ let j = keys.length;
2340
+ while (j--) {
2341
+ yield [keys[j], nValue];
2239
2342
  }
2240
2343
  }
2241
2344
  }
2242
- if (done) break;
2243
2345
  if (direction === 1) {
2244
- if (!node.next) {
2245
- done = true;
2246
- break;
2247
- }
2346
+ if (!node.next) break;
2248
2347
  node = this.getNode(node.next);
2249
2348
  } else {
2250
- if (!node.prev) {
2251
- done = true;
2252
- break;
2253
- }
2349
+ if (!node.prev) break;
2254
2350
  node = this.getNode(node.prev);
2255
2351
  }
2256
2352
  }
@@ -2295,7 +2391,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2295
2391
  }
2296
2392
  }
2297
2393
  exists(key, value) {
2298
- const node = this.insertableNode(value);
2394
+ const node = this.locateLeaf(value);
2299
2395
  const { index, found } = this._binarySearchValues(node.values, value);
2300
2396
  if (found) {
2301
2397
  const keys = node.keys[index];
@@ -2339,49 +2435,36 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2339
2435
  }
2340
2436
  *whereStream(condition, options) {
2341
2437
  const { filterValues, limit, order = "asc" } = options ?? {};
2342
- const driverKey = this.getDriverKey(condition);
2343
- if (!driverKey) return;
2344
- const value = condition[driverKey];
2345
- const v = this.ensureValues(value);
2346
- const config = this.searchConfigs[driverKey][order];
2347
- let startNode = config.start(this, v);
2348
- let endNode = config.end(this, v);
2349
- const direction = config.direction;
2350
- const earlyTerminate = config.earlyTerminate;
2351
- if (order === "desc" && !startNode) {
2352
- startNode = this.rightestNode();
2353
- }
2354
- if (order === "asc" && !startNode) {
2355
- startNode = this.leftestNode();
2438
+ const conditionKeys = Object.keys(condition);
2439
+ if (conditionKeys.length === 0) return;
2440
+ const resolved = this.resolveStartEndConfigs(condition, order);
2441
+ const direction = resolved.direction;
2442
+ let startNode;
2443
+ if (resolved.startKey) {
2444
+ const startConfig = this.searchConfigs[resolved.startKey][order];
2445
+ startNode = startConfig.start(this, resolved.startValues);
2446
+ } else {
2447
+ startNode = order === "asc" ? this.leftestNode() : this.rightestNode();
2448
+ }
2449
+ let endNode = null;
2450
+ if (resolved.endKey) {
2451
+ const endConfig = this.searchConfigs[resolved.endKey][order];
2452
+ endNode = endConfig.end(this, resolved.endValues);
2356
2453
  }
2357
2454
  if (!startNode) return;
2358
- const comparator = this.verifierMap[driverKey];
2359
2455
  const generator = this.getPairsGenerator(
2360
- value,
2361
2456
  startNode,
2362
2457
  endNode,
2363
- comparator,
2364
- direction,
2365
- earlyTerminate
2458
+ direction
2366
2459
  );
2367
2460
  let count = 0;
2368
2461
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
2369
2462
  for (const pair of generator) {
2370
- const [k, v2] = pair;
2463
+ const [k, v] = pair;
2371
2464
  if (intersection && !intersection.has(k)) {
2372
2465
  continue;
2373
2466
  }
2374
- let isMatch = true;
2375
- for (const key in condition) {
2376
- if (key === driverKey) continue;
2377
- const verify = this.verifierMap[key];
2378
- const condValue = condition[key];
2379
- if (!verify(v2, condValue)) {
2380
- isMatch = false;
2381
- break;
2382
- }
2383
- }
2384
- if (isMatch) {
2467
+ if (this.verify(v, condition)) {
2385
2468
  yield pair;
2386
2469
  count++;
2387
2470
  if (limit !== void 0 && count >= limit) {
@@ -2405,7 +2488,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2405
2488
  return map;
2406
2489
  }
2407
2490
  insert(key, value) {
2408
- let before = this.insertableNode(value);
2491
+ let before = this.locateLeaf(value);
2409
2492
  before = this._insertAtLeaf(before, key, value);
2410
2493
  if (before.values.length === this.order) {
2411
2494
  let after = this._createNode(
@@ -2433,7 +2516,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2433
2516
  let currentLeaf = null;
2434
2517
  let modified = false;
2435
2518
  for (const [key, value] of sorted) {
2436
- const targetLeaf = this.insertableNode(value);
2519
+ const targetLeaf = this.locateLeaf(value);
2437
2520
  if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
2438
2521
  } else {
2439
2522
  if (currentLeaf !== null && modified) {
@@ -2675,7 +2758,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2675
2758
  if (value === void 0) {
2676
2759
  return;
2677
2760
  }
2678
- let node = this.insertableNodeByPrimary(value);
2761
+ let node = this.findLowerBoundLeaf(value);
2679
2762
  let found = false;
2680
2763
  while (true) {
2681
2764
  let i = node.values.length;
@@ -3265,7 +3348,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3265
3348
  await this._insertInParent(parentNode, midValue, newSiblingNodeRecursive);
3266
3349
  }
3267
3350
  }
3268
- async insertableNode(value) {
3351
+ async locateLeaf(value) {
3269
3352
  let node = await this.getNode(this.rootId);
3270
3353
  while (!node.leaf) {
3271
3354
  const { index } = this._binarySearchValues(node.values, value, false, true);
@@ -3273,7 +3356,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3273
3356
  }
3274
3357
  return node;
3275
3358
  }
3276
- async insertableNodeByPrimary(value) {
3359
+ async findLowerBoundLeaf(value) {
3277
3360
  let node = await this.getNode(this.rootId);
3278
3361
  while (!node.leaf) {
3279
3362
  const { index } = this._binarySearchValues(node.values, value, true, false);
@@ -3281,7 +3364,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3281
3364
  }
3282
3365
  return node;
3283
3366
  }
3284
- async insertableRightestNodeByPrimary(value) {
3367
+ async findUpperBoundLeaf(value) {
3285
3368
  let node = await this.getNode(this.rootId);
3286
3369
  while (!node.leaf) {
3287
3370
  const { index } = this._binarySearchValues(node.values, value, true, true);
@@ -3289,15 +3372,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3289
3372
  }
3290
3373
  return node;
3291
3374
  }
3292
- async insertableRightestEndNodeByPrimary(value) {
3293
- const node = await this.insertableRightestNodeByPrimary(value);
3294
- if (!node.next) {
3295
- return null;
3296
- }
3297
- return await this.getNode(node.next);
3298
- }
3299
- async insertableEndNode(value, direction) {
3300
- const insertableNode = direction === -1 ? await this.insertableNodeByPrimary(value) : await this.insertableRightestNodeByPrimary(value);
3375
+ async findOuterBoundaryLeaf(value, direction) {
3376
+ const insertableNode = direction === -1 ? await this.findLowerBoundLeaf(value) : await this.findUpperBoundLeaf(value);
3301
3377
  let key;
3302
3378
  switch (direction) {
3303
3379
  case -1:
@@ -3334,22 +3410,19 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3334
3410
  }
3335
3411
  return node;
3336
3412
  }
3337
- async *getPairsGenerator(value, startNode, endNode, comparator, direction, earlyTerminate) {
3413
+ async *getPairsGenerator(startNode, endNode, direction) {
3338
3414
  let node = startNode;
3339
- let done = false;
3340
- let hasMatched = false;
3341
3415
  let nextNodePromise = null;
3342
- while (!done) {
3416
+ while (true) {
3343
3417
  if (endNode && node.id === endNode.id) {
3344
- done = true;
3345
3418
  break;
3346
3419
  }
3347
3420
  if (direction === 1) {
3348
- if (node.next && !done) {
3421
+ if (node.next) {
3349
3422
  nextNodePromise = this.getNode(node.next);
3350
3423
  }
3351
3424
  } else {
3352
- if (node.prev && !done) {
3425
+ if (node.prev) {
3353
3426
  nextNodePromise = this.getNode(node.prev);
3354
3427
  }
3355
3428
  }
@@ -3358,14 +3431,8 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3358
3431
  for (let i = 0; i < len; i++) {
3359
3432
  const nValue = node.values[i];
3360
3433
  const keys = node.keys[i];
3361
- if (comparator(nValue, value)) {
3362
- hasMatched = true;
3363
- for (let j = 0; j < keys.length; j++) {
3364
- yield [keys[j], nValue];
3365
- }
3366
- } else if (earlyTerminate && hasMatched) {
3367
- done = true;
3368
- break;
3434
+ for (let j = 0, kLen = keys.length; j < kLen; j++) {
3435
+ yield [keys[j], nValue];
3369
3436
  }
3370
3437
  }
3371
3438
  } else {
@@ -3373,27 +3440,17 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3373
3440
  while (i--) {
3374
3441
  const nValue = node.values[i];
3375
3442
  const keys = node.keys[i];
3376
- if (comparator(nValue, value)) {
3377
- hasMatched = true;
3378
- let j = keys.length;
3379
- while (j--) {
3380
- yield [keys[j], nValue];
3381
- }
3382
- } else if (earlyTerminate && hasMatched) {
3383
- done = true;
3384
- break;
3443
+ let j = keys.length;
3444
+ while (j--) {
3445
+ yield [keys[j], nValue];
3385
3446
  }
3386
3447
  }
3387
3448
  }
3388
- if (done) {
3389
- if (nextNodePromise) await nextNodePromise;
3390
- break;
3391
- }
3392
3449
  if (nextNodePromise) {
3393
3450
  node = await nextNodePromise;
3394
3451
  nextNodePromise = null;
3395
3452
  } else {
3396
- done = true;
3453
+ break;
3397
3454
  }
3398
3455
  }
3399
3456
  }
@@ -3437,7 +3494,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3437
3494
  }
3438
3495
  }
3439
3496
  async exists(key, value) {
3440
- const node = await this.insertableNode(value);
3497
+ const node = await this.locateLeaf(value);
3441
3498
  const { index, found } = this._binarySearchValues(node.values, value);
3442
3499
  if (found) {
3443
3500
  const keys = node.keys[index];
@@ -3481,49 +3538,36 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3481
3538
  }
3482
3539
  async *whereStream(condition, options) {
3483
3540
  const { filterValues, limit, order = "asc" } = options ?? {};
3484
- const driverKey = this.getDriverKey(condition);
3485
- if (!driverKey) return;
3486
- const value = condition[driverKey];
3487
- const v = this.ensureValues(value);
3488
- const config = this.searchConfigs[driverKey][order];
3489
- let startNode = await config.start(this, v);
3490
- let endNode = await config.end(this, v);
3491
- const direction = config.direction;
3492
- const earlyTerminate = config.earlyTerminate;
3493
- if (order === "desc" && !startNode) {
3494
- startNode = await this.rightestNode();
3495
- }
3496
- if (order === "asc" && !startNode) {
3497
- startNode = await this.leftestNode();
3541
+ const conditionKeys = Object.keys(condition);
3542
+ if (conditionKeys.length === 0) return;
3543
+ const resolved = this.resolveStartEndConfigs(condition, order);
3544
+ const direction = resolved.direction;
3545
+ let startNode;
3546
+ if (resolved.startKey) {
3547
+ const startConfig = this.searchConfigs[resolved.startKey][order];
3548
+ startNode = await startConfig.start(this, resolved.startValues);
3549
+ } else {
3550
+ startNode = order === "asc" ? await this.leftestNode() : await this.rightestNode();
3551
+ }
3552
+ let endNode = null;
3553
+ if (resolved.endKey) {
3554
+ const endConfig = this.searchConfigs[resolved.endKey][order];
3555
+ endNode = await endConfig.end(this, resolved.endValues);
3498
3556
  }
3499
3557
  if (!startNode) return;
3500
- const comparator = this.verifierMap[driverKey];
3501
3558
  const generator = this.getPairsGenerator(
3502
- value,
3503
3559
  startNode,
3504
3560
  endNode,
3505
- comparator,
3506
- direction,
3507
- earlyTerminate
3561
+ direction
3508
3562
  );
3509
3563
  let count = 0;
3510
3564
  const intersection = filterValues && filterValues.size > 0 ? filterValues : null;
3511
3565
  for await (const pair of generator) {
3512
- const [k, v2] = pair;
3566
+ const [k, v] = pair;
3513
3567
  if (intersection && !intersection.has(k)) {
3514
3568
  continue;
3515
3569
  }
3516
- let isMatch = true;
3517
- for (const key in condition) {
3518
- if (key === driverKey) continue;
3519
- const verify = this.verifierMap[key];
3520
- const condValue = condition[key];
3521
- if (!verify(v2, condValue)) {
3522
- isMatch = false;
3523
- break;
3524
- }
3525
- }
3526
- if (isMatch) {
3570
+ if (this.verify(v, condition)) {
3527
3571
  yield pair;
3528
3572
  count++;
3529
3573
  if (limit !== void 0 && count >= limit) {
@@ -3548,7 +3592,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3548
3592
  }
3549
3593
  async insert(key, value) {
3550
3594
  return this.writeLock(0, async () => {
3551
- let before = await this.insertableNode(value);
3595
+ let before = await this.locateLeaf(value);
3552
3596
  before = await this._insertAtLeaf(before, key, value);
3553
3597
  if (before.values.length === this.order) {
3554
3598
  let after = await this._createNode(
@@ -3578,7 +3622,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3578
3622
  let currentLeaf = null;
3579
3623
  let modified = false;
3580
3624
  for (const [key, value] of sorted) {
3581
- const targetLeaf = await this.insertableNode(value);
3625
+ const targetLeaf = await this.locateLeaf(value);
3582
3626
  if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
3583
3627
  } else {
3584
3628
  if (currentLeaf !== null && modified) {
@@ -3822,7 +3866,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3822
3866
  if (value === void 0) {
3823
3867
  return;
3824
3868
  }
3825
- let node = await this.insertableNodeByPrimary(value);
3869
+ let node = await this.findLowerBoundLeaf(value);
3826
3870
  let found = false;
3827
3871
  while (true) {
3828
3872
  let i = node.values.length;