data-structure-typed 2.2.7 → 2.3.0

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.
Files changed (181) hide show
  1. package/.github/workflows/ci.yml +9 -0
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +14 -3
  4. package/README_CN.md +119 -275
  5. package/benchmark/report.html +1 -1
  6. package/benchmark/report.json +20 -324
  7. package/dist/cjs/index.cjs +689 -182
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs-legacy/index.cjs +693 -185
  10. package/dist/cjs-legacy/index.cjs.map +1 -1
  11. package/dist/esm/index.mjs +689 -182
  12. package/dist/esm/index.mjs.map +1 -1
  13. package/dist/esm-legacy/index.mjs +693 -185
  14. package/dist/esm-legacy/index.mjs.map +1 -1
  15. package/dist/leetcode/avl-tree-counter.mjs +2957 -0
  16. package/dist/leetcode/avl-tree-multi-map.mjs +2889 -0
  17. package/dist/leetcode/avl-tree.mjs +2720 -0
  18. package/dist/leetcode/binary-tree.mjs +1594 -0
  19. package/dist/leetcode/bst.mjs +2398 -0
  20. package/dist/leetcode/deque.mjs +683 -0
  21. package/dist/leetcode/directed-graph.mjs +1733 -0
  22. package/dist/leetcode/doubly-linked-list.mjs +709 -0
  23. package/dist/leetcode/hash-map.mjs +493 -0
  24. package/dist/leetcode/heap.mjs +542 -0
  25. package/dist/leetcode/max-heap.mjs +375 -0
  26. package/dist/leetcode/max-priority-queue.mjs +383 -0
  27. package/dist/leetcode/min-heap.mjs +363 -0
  28. package/dist/leetcode/min-priority-queue.mjs +371 -0
  29. package/dist/leetcode/priority-queue.mjs +363 -0
  30. package/dist/leetcode/queue.mjs +943 -0
  31. package/dist/leetcode/red-black-tree.mjs +2765 -0
  32. package/dist/leetcode/singly-linked-list.mjs +754 -0
  33. package/dist/leetcode/stack.mjs +217 -0
  34. package/dist/leetcode/tree-counter.mjs +3039 -0
  35. package/dist/leetcode/tree-multi-map.mjs +2913 -0
  36. package/dist/leetcode/trie.mjs +413 -0
  37. package/dist/leetcode/undirected-graph.mjs +1650 -0
  38. package/dist/types/data-structures/base/linear-base.d.ts +6 -6
  39. package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +1 -1
  40. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -2
  41. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +10 -10
  42. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +25 -27
  43. package/dist/types/data-structures/binary-tree/bst.d.ts +13 -12
  44. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +151 -21
  45. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +4 -4
  46. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
  47. package/dist/types/interfaces/binary-tree.d.ts +1 -1
  48. package/dist/umd/data-structure-typed.js +689 -181
  49. package/dist/umd/data-structure-typed.js.map +1 -1
  50. package/dist/umd/data-structure-typed.min.js +3 -3
  51. package/dist/umd/data-structure-typed.min.js.map +1 -1
  52. package/package.json +50 -172
  53. package/src/data-structures/base/linear-base.ts +2 -12
  54. package/src/data-structures/binary-tree/avl-tree-counter.ts +6 -6
  55. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +13 -13
  56. package/src/data-structures/binary-tree/avl-tree.ts +15 -15
  57. package/src/data-structures/binary-tree/binary-tree.ts +57 -60
  58. package/src/data-structures/binary-tree/bst.ts +100 -26
  59. package/src/data-structures/binary-tree/red-black-tree.ts +586 -76
  60. package/src/data-structures/binary-tree/tree-counter.ts +25 -13
  61. package/src/data-structures/binary-tree/tree-multi-map.ts +13 -13
  62. package/src/data-structures/queue/deque.ts +10 -0
  63. package/src/interfaces/binary-tree.ts +1 -1
  64. package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +1 -2
  65. package/test/unit/data-structures/base/iterable-element-base.coverage.test.ts +106 -0
  66. package/test/unit/data-structures/base/iterable-element-base.more-branches.coverage.test.ts +61 -0
  67. package/test/unit/data-structures/base/linear-base.array.coverage.test.ts +168 -0
  68. package/test/unit/data-structures/base/linear-base.concat-else.coverage.test.ts +82 -0
  69. package/test/unit/data-structures/base/linear-base.coverage.test.ts +72 -0
  70. package/test/unit/data-structures/base/linear-base.more-branches.coverage.test.ts +417 -0
  71. package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches-3.coverage.test.ts +146 -0
  72. package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches.coverage.test.ts +93 -0
  73. package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +30 -30
  74. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.coverage.test.ts +108 -0
  75. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.more-branches-2.coverage.test.ts +85 -0
  76. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +46 -46
  77. package/test/unit/data-structures/binary-tree/avl-tree-node.familyPosition-root-left.coverage.test.ts +17 -0
  78. package/test/unit/data-structures/binary-tree/avl-tree.more-branches-2.coverage.test.ts +99 -0
  79. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +43 -43
  80. package/test/unit/data-structures/binary-tree/binary-indexed-tree.more-branches.coverage.test.ts +18 -0
  81. package/test/unit/data-structures/binary-tree/binary-tree.more-branches.coverage.test.ts +56 -0
  82. package/test/unit/data-structures/binary-tree/binary-tree.remaining-branches.coverage.test.ts +229 -0
  83. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +151 -151
  84. package/test/unit/data-structures/binary-tree/bst.bound-by-predicate.coverage.test.ts +33 -0
  85. package/test/unit/data-structures/binary-tree/bst.coverage.test.ts +94 -0
  86. package/test/unit/data-structures/binary-tree/bst.deletebykey.coverage.test.ts +70 -0
  87. package/test/unit/data-structures/binary-tree/bst.deletewhere.coverage.test.ts +37 -0
  88. package/test/unit/data-structures/binary-tree/bst.floor-lower-predicate.coverage.test.ts +29 -0
  89. package/test/unit/data-structures/binary-tree/bst.floor-setmany.coverage.test.ts +72 -0
  90. package/test/unit/data-structures/binary-tree/bst.getnode.range-ensure.coverage.test.ts +22 -0
  91. package/test/unit/data-structures/binary-tree/bst.misc-branches.coverage.test.ts +100 -0
  92. package/test/unit/data-structures/binary-tree/bst.more-branches-2.coverage.test.ts +133 -0
  93. package/test/unit/data-structures/binary-tree/bst.more-branches-3.coverage.test.ts +45 -0
  94. package/test/unit/data-structures/binary-tree/bst.more-branches-4.coverage.test.ts +36 -0
  95. package/test/unit/data-structures/binary-tree/bst.more-branches-5.coverage.test.ts +40 -0
  96. package/test/unit/data-structures/binary-tree/bst.more.coverage.test.ts +39 -0
  97. package/test/unit/data-structures/binary-tree/bst.node-family.coverage.test.ts +29 -0
  98. package/test/unit/data-structures/binary-tree/bst.range-pruning.coverage.test.ts +43 -0
  99. package/test/unit/data-structures/binary-tree/bst.search-fastpath.coverage.test.ts +30 -0
  100. package/test/unit/data-structures/binary-tree/bst.test.ts +124 -154
  101. package/test/unit/data-structures/binary-tree/overall.test.ts +20 -20
  102. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-corruption-repair.coverage.test.ts +66 -0
  103. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-max-update.coverage.test.ts +18 -0
  104. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-null.coverage.test.ts +53 -0
  105. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-stale-cache.coverage.test.ts +25 -0
  106. package/test/unit/data-structures/binary-tree/red-black-tree.boundary-update.coverage.test.ts +23 -0
  107. package/test/unit/data-structures/binary-tree/red-black-tree.cache-delete.coverage.test.ts +49 -0
  108. package/test/unit/data-structures/binary-tree/red-black-tree.cache-edge.coverage.test.ts +37 -0
  109. package/test/unit/data-structures/binary-tree/red-black-tree.cache-stale-insert.coverage.test.ts +39 -0
  110. package/test/unit/data-structures/binary-tree/red-black-tree.coverage.test.ts +334 -0
  111. package/test/unit/data-structures/binary-tree/red-black-tree.delete-fixup.coverage.test.ts +68 -0
  112. package/test/unit/data-structures/binary-tree/red-black-tree.delete-successor.coverage.test.ts +75 -0
  113. package/test/unit/data-structures/binary-tree/red-black-tree.factories.coverage.test.ts +26 -0
  114. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-compare-update.coverage.test.ts +74 -0
  115. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-no-update.coverage.test.ts +44 -0
  116. package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-nullish.coverage.test.ts +61 -0
  117. package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-defined.coverage.test.ts +35 -0
  118. package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-undefined.coverage.test.ts +43 -0
  119. package/test/unit/data-structures/binary-tree/red-black-tree.hint-more.coverage.test.ts +99 -0
  120. package/test/unit/data-structures/binary-tree/red-black-tree.hint.coverage.test.ts +60 -0
  121. package/test/unit/data-structures/binary-tree/red-black-tree.insert-cache-nullish.coverage.test.ts +29 -0
  122. package/test/unit/data-structures/binary-tree/red-black-tree.insert-header-parent-nullish.coverage.test.ts +17 -0
  123. package/test/unit/data-structures/binary-tree/red-black-tree.internal-walk.coverage.test.ts +57 -0
  124. package/test/unit/data-structures/binary-tree/red-black-tree.minmax-cache.test.ts +65 -0
  125. package/test/unit/data-structures/binary-tree/red-black-tree.misc-inputs.coverage.test.ts +17 -0
  126. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-2.coverage.test.ts +121 -0
  127. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-3.coverage.test.ts +55 -0
  128. package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-4.coverage.test.ts +44 -0
  129. package/test/unit/data-structures/binary-tree/red-black-tree.predsucc.coverage.test.ts +40 -0
  130. package/test/unit/data-structures/binary-tree/red-black-tree.remaining-branches.coverage.test.ts +123 -0
  131. package/test/unit/data-structures/binary-tree/red-black-tree.set-inputs.coverage.test.ts +64 -0
  132. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-parent-cache.coverage.test.ts +79 -0
  133. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-remaining.coverage.test.ts +44 -0
  134. package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-uncovered.coverage.test.ts +74 -0
  135. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +141 -141
  136. package/test/unit/data-structures/binary-tree/red-black-tree.update-branches.coverage.test.ts +30 -0
  137. package/test/unit/data-structures/binary-tree/segment-tree.more-branches.coverage.test.ts +31 -0
  138. package/test/unit/data-structures/binary-tree/tree-counter.coverage.test.ts +115 -0
  139. package/test/unit/data-structures/binary-tree/tree-counter.more-branches.coverage.test.ts +244 -0
  140. package/test/unit/data-structures/binary-tree/tree-counter.test.ts +41 -39
  141. package/test/unit/data-structures/binary-tree/tree-multi-map.coverage.test.ts +104 -0
  142. package/test/unit/data-structures/binary-tree/tree-multi-map.more-branches-2.coverage.test.ts +59 -0
  143. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +145 -145
  144. package/test/unit/data-structures/graph/abstract-graph.more-branches-2.coverage.test.ts +40 -0
  145. package/test/unit/data-structures/graph/abstract-graph.more-branches-3.coverage.test.ts +65 -0
  146. package/test/unit/data-structures/graph/abstract-graph.more-branches-4.coverage.test.ts +98 -0
  147. package/test/unit/data-structures/graph/abstract-graph.more-branches-5.coverage.test.ts +51 -0
  148. package/test/unit/data-structures/graph/abstract-graph.more-branches.coverage.test.ts +62 -0
  149. package/test/unit/data-structures/graph/directed-graph.more-branches-2.coverage.test.ts +38 -0
  150. package/test/unit/data-structures/graph/directed-graph.more-branches-3.coverage.test.ts +25 -0
  151. package/test/unit/data-structures/graph/directed-graph.more-branches.coverage.test.ts +82 -0
  152. package/test/unit/data-structures/graph/map-graph.more-branches.coverage.test.ts +22 -0
  153. package/test/unit/data-structures/graph/undirected-graph.more-branches-2.coverage.test.ts +35 -0
  154. package/test/unit/data-structures/graph/undirected-graph.more-branches.coverage.test.ts +87 -0
  155. package/test/unit/data-structures/hash/hash-map.more-branches.coverage.test.ts +64 -0
  156. package/test/unit/data-structures/hash/hash-map.toEntryFn-branch.coverage.test.ts +9 -0
  157. package/test/unit/data-structures/heap/heap.misc-branches.coverage.test.ts +110 -0
  158. package/test/unit/data-structures/heap/heap.remaining-branches.coverage.test.ts +22 -0
  159. package/test/unit/data-structures/heap/max-heap.coverage.test.ts +29 -0
  160. package/test/unit/data-structures/linked-list/doubly-linked-list.more-branches.coverage.test.ts +72 -0
  161. package/test/unit/data-structures/linked-list/linked-list.unshiftMany-else.coverage.test.ts +15 -0
  162. package/test/unit/data-structures/linked-list/singly-linked-list.coverage.test.ts +221 -0
  163. package/test/unit/data-structures/linked-list/singly-linked-list.more-branches.coverage.test.ts +86 -0
  164. package/test/unit/data-structures/linked-list/skip-linked-list.more-branches.coverage.test.ts +31 -0
  165. package/test/unit/data-structures/matrix/matrix.more-branches.coverage.test.ts +81 -0
  166. package/test/unit/data-structures/matrix/matrix.pivotElement-nullish.coverage.test.ts +28 -0
  167. package/test/unit/data-structures/priority-queue/max-priority-queue.more-branches.coverage.test.ts +10 -0
  168. package/test/unit/data-structures/priority-queue/priority-queue.coverage.test.ts +21 -0
  169. package/test/unit/data-structures/queue/deque.coverage.test.ts +173 -0
  170. package/test/unit/data-structures/queue/deque.more-branches-2.coverage.test.ts +39 -0
  171. package/test/unit/data-structures/queue/deque.more-branches-3.coverage.test.ts +9 -0
  172. package/test/unit/data-structures/queue/deque.more-branches.coverage.test.ts +95 -0
  173. package/test/unit/data-structures/queue/queue.coverage.test.ts +138 -0
  174. package/test/unit/data-structures/queue/queue.more-branches-2.coverage.test.ts +27 -0
  175. package/test/unit/data-structures/stack/stack.coverage.test.ts +112 -0
  176. package/test/unit/data-structures/tree/tree.more-branches.coverage.test.ts +9 -0
  177. package/test/unit/data-structures/trie/trie.more-branches-2.coverage.test.ts +51 -0
  178. package/test/utils/patch.ts +33 -0
  179. package/tsup.config.js +50 -21
  180. package/tsup.umd.config.js +29 -0
  181. package/tsup.node.config.js +0 -83
@@ -1402,6 +1402,12 @@ var LinearLinkedBase = class extends LinearBase {
1402
1402
  }
1403
1403
  return -1;
1404
1404
  }
1405
+ /**
1406
+ * Concatenate lists/elements preserving order.
1407
+ * @param items - Elements or `LinearBase` instances.
1408
+ * @returns New list with combined elements (`this` type).
1409
+ * @remarks Time O(sum(length)), Space O(sum(length))
1410
+ */
1405
1411
  concat(...items) {
1406
1412
  const newList = this.clone();
1407
1413
  for (const item of items) {
@@ -4228,6 +4234,12 @@ var Deque = class extends LinearBase {
4228
4234
  */
4229
4235
  _setBucketSize(size) {
4230
4236
  this._bucketSize = size;
4237
+ if (this._length === 0) {
4238
+ this._buckets = [new Array(this._bucketSize)];
4239
+ this._bucketCount = 1;
4240
+ this._bucketFirst = this._bucketLast = 0;
4241
+ this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
4242
+ }
4231
4243
  }
4232
4244
  /**
4233
4245
  * (Protected) Iterate elements from front to back.
@@ -6993,9 +7005,9 @@ var BinaryTree = class extends IterableEntryBase {
6993
7005
  iterationType = "ITERATIVE";
6994
7006
  /**
6995
7007
  * Creates an instance of BinaryTree.
6996
- * @remarks Time O(N * M), where N is the number of items in `keysNodesEntriesOrRaws` and M is the tree size at insertion time (due to O(M) `add` operation). Space O(N) for storing the nodes.
7008
+ * @remarks Time O(N * M), where N is the number of items in `keysNodesEntriesOrRaws` and M is the tree size at insertion time (due to O(M) `set` operation). Space O(N) for storing the nodes.
6997
7009
  *
6998
- * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
7010
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
6999
7011
  * @param [options] - Configuration options for the tree.
7000
7012
  */
7001
7013
  constructor(keysNodesEntriesOrRaws = [], options) {
@@ -7008,7 +7020,7 @@ var BinaryTree = class extends IterableEntryBase {
7008
7020
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
7009
7021
  else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
7010
7022
  }
7011
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
7023
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
7012
7024
  }
7013
7025
  _isMapMode = true;
7014
7026
  /**
@@ -7222,10 +7234,20 @@ var BinaryTree = class extends IterableEntryBase {
7222
7234
  * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
7223
7235
  *
7224
7236
  * @param keyNodeOrEntry - The key, node, or entry to add.
7237
+ * @returns True if the addition was successful, false otherwise.
7238
+ */
7239
+ add(keyNodeOrEntry) {
7240
+ return this.set(keyNodeOrEntry);
7241
+ }
7242
+ /**
7243
+ * Adds or updates a new node to the tree.
7244
+ * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation sets the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
7245
+ *
7246
+ * @param keyNodeOrEntry - The key, node, or entry to set or update.
7225
7247
  * @param [value] - The value, if providing just a key.
7226
7248
  * @returns True if the addition was successful, false otherwise.
7227
7249
  */
7228
- add(keyNodeOrEntry, value) {
7250
+ set(keyNodeOrEntry, value) {
7229
7251
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
7230
7252
  if (newNode === void 0) return false;
7231
7253
  if (!this._root) {
@@ -7269,25 +7291,24 @@ var BinaryTree = class extends IterableEntryBase {
7269
7291
  return false;
7270
7292
  }
7271
7293
  /**
7272
- * Adds or updates a new node to the tree.
7273
- * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
7294
+ * Adds multiple items to the tree.
7295
+ * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
7274
7296
  *
7275
- * @param keyNodeOrEntry - The key, node, or entry to add or update.
7276
- * @param [value] - The value, if providing just a key.
7277
- * @returns True if the addition was successful, false otherwise.
7297
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
7298
+ * @returns An array of booleans indicating the success of each individual `set` operation.
7278
7299
  */
7279
- set(keyNodeOrEntry, value) {
7280
- return this.add(keyNodeOrEntry, value);
7300
+ addMany(keysNodesEntriesOrRaws) {
7301
+ return this.setMany(keysNodesEntriesOrRaws);
7281
7302
  }
7282
7303
  /**
7283
- * Adds multiple items to the tree.
7284
- * @remarks Time O(N * M), where N is the number of items to add and M is the size of the tree at insertion (due to O(M) `add` operation). Space O(M) (from `add`) + O(N) (for the `inserted` array).
7304
+ * Adds or updates multiple items to the tree.
7305
+ * @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
7285
7306
  *
7286
- * @param keysNodesEntriesOrRaws - An iterable of items to add.
7307
+ * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
7287
7308
  * @param [values] - An optional parallel iterable of values.
7288
- * @returns An array of booleans indicating the success of each individual `add` operation.
7309
+ * @returns An array of booleans indicating the success of each individual `set` operation.
7289
7310
  */
7290
- addMany(keysNodesEntriesOrRaws, values) {
7311
+ setMany(keysNodesEntriesOrRaws, values) {
7291
7312
  const inserted = [];
7292
7313
  let valuesIterator;
7293
7314
  if (values) {
@@ -7302,52 +7323,41 @@ var BinaryTree = class extends IterableEntryBase {
7302
7323
  }
7303
7324
  }
7304
7325
  if (this.isRaw(keyNodeEntryOrRaw)) keyNodeEntryOrRaw = this._toEntryFn(keyNodeEntryOrRaw);
7305
- inserted.push(this.add(keyNodeEntryOrRaw, value));
7326
+ inserted.push(this.set(keyNodeEntryOrRaw, value));
7306
7327
  }
7307
7328
  return inserted;
7308
7329
  }
7309
7330
  /**
7310
- * Adds or updates multiple items to the tree.
7311
- * @remarks Time O(N * M), where N is the number of items to add and M is the size of the tree at insertion (due to O(M) `add` operation). Space O(M) (from `add`) + O(N) (for the `inserted` array).
7312
- *
7313
- * @param keysNodesEntriesOrRaws - An iterable of items to add or update.
7314
- * @param [values] - An optional parallel iterable of values.
7315
- * @returns An array of booleans indicating the success of each individual `add` operation.
7316
- */
7317
- setMany(keysNodesEntriesOrRaws, values) {
7318
- return this.addMany(keysNodesEntriesOrRaws, values);
7319
- }
7320
- /**
7321
- * Merges another tree into this one by adding all its nodes.
7322
- * @remarks Time O(N * M), same as `addMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `add`).
7331
+ * Merges another tree into this one by seting all its nodes.
7332
+ * @remarks Time O(N * M), same as `setMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `set`).
7323
7333
  *
7324
7334
  * @param anotherTree - The tree to merge.
7325
7335
  */
7326
7336
  merge(anotherTree) {
7327
- this.addMany(anotherTree, []);
7337
+ this.setMany(anotherTree, []);
7328
7338
  }
7329
7339
  /**
7330
7340
  * Clears the tree and refills it with new items.
7331
- * @remarks Time O(N) (for `clear`) + O(N * M) (for `addMany`) = O(N * M). Space O(M) (from `addMany`).
7341
+ * @remarks Time O(N) (for `clear`) + O(N * M) (for `setMany`) = O(N * M). Space O(M) (from `setMany`).
7332
7342
  *
7333
- * @param keysNodesEntriesOrRaws - An iterable of items to add.
7343
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
7334
7344
  * @param [values] - An optional parallel iterable of values.
7335
7345
  */
7336
7346
  refill(keysNodesEntriesOrRaws, values) {
7337
7347
  this.clear();
7338
- this.addMany(keysNodesEntriesOrRaws, values);
7348
+ this.setMany(keysNodesEntriesOrRaws, values);
7339
7349
  }
7340
7350
  /**
7341
7351
  * Deletes a node from the tree.
7342
7352
  * @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
7343
7353
  *
7344
- * @param keyNodeOrEntry - The node to delete.
7354
+ * @param keyNodeEntryRawOrPredicate - The node to delete.
7345
7355
  * @returns An array containing deletion results (for compatibility with self-balancing trees).
7346
7356
  */
7347
- delete(keyNodeOrEntry) {
7357
+ delete(keyNodeEntryRawOrPredicate) {
7348
7358
  const deletedResult = [];
7349
7359
  if (!this._root) return deletedResult;
7350
- const curr = this.getNode(keyNodeOrEntry);
7360
+ const curr = this.getNode(keyNodeEntryRawOrPredicate);
7351
7361
  if (!curr) return deletedResult;
7352
7362
  const parent = curr?.parent;
7353
7363
  let needBalanced;
@@ -7530,7 +7540,7 @@ var BinaryTree = class extends IterableEntryBase {
7530
7540
  }
7531
7541
  return true;
7532
7542
  }, "checkBST");
7533
- const isStandardBST = checkBST(false);
7543
+ const isStandardBST = checkBST();
7534
7544
  const isInverseBST = checkBST(true);
7535
7545
  return isStandardBST || isInverseBST;
7536
7546
  }
@@ -8000,7 +8010,7 @@ var BinaryTree = class extends IterableEntryBase {
8000
8010
  }
8001
8011
  /**
8002
8012
  * Clones the tree.
8003
- * @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `add`, and `add` is O(M)). Space O(N) for the new tree and the BFS queue.
8013
+ * @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `set`, and `set` is O(M)). Space O(N) for the new tree and the BFS queue.
8004
8014
  *
8005
8015
  * @returns A new, cloned instance of the tree.
8006
8016
  */
@@ -8011,7 +8021,7 @@ var BinaryTree = class extends IterableEntryBase {
8011
8021
  }
8012
8022
  /**
8013
8023
  * Creates a new tree containing only the entries that satisfy the predicate.
8014
- * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `add` for each item). Space O(N) for the new tree.
8024
+ * @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `set` for each item). Space O(N) for the new tree.
8015
8025
  *
8016
8026
  * @param predicate - A function to test each [key, value] pair.
8017
8027
  * @param [thisArg] - `this` context for the predicate.
@@ -8020,7 +8030,7 @@ var BinaryTree = class extends IterableEntryBase {
8020
8030
  filter(predicate, thisArg) {
8021
8031
  const out = this._createInstance();
8022
8032
  let i = 0;
8023
- for (const [k, v] of this) if (predicate.call(thisArg, v, k, i++, this)) out.add([k, v]);
8033
+ for (const [k, v] of this) if (predicate.call(thisArg, v, k, i++, this)) out.set([k, v]);
8024
8034
  return out;
8025
8035
  }
8026
8036
  /**
@@ -8038,7 +8048,7 @@ var BinaryTree = class extends IterableEntryBase {
8038
8048
  map(cb, options, thisArg) {
8039
8049
  const out = this._createLike([], options);
8040
8050
  let i = 0;
8041
- for (const [k, v] of this) out.add(cb.call(thisArg, v, k, i++, this));
8051
+ for (const [k, v] of this) out.set(cb.call(thisArg, v, k, i++, this));
8042
8052
  return out;
8043
8053
  }
8044
8054
  /**
@@ -8290,18 +8300,18 @@ var BinaryTree = class extends IterableEntryBase {
8290
8300
  return [this.createNode(keyNodeOrEntry, value), value];
8291
8301
  }
8292
8302
  /**
8293
- * (Protected) Helper for cloning. Performs a BFS and adds all nodes to the new tree.
8294
- * @remarks Time O(N * M) (O(N) BFS + O(M) `add` for each node).
8303
+ * (Protected) Helper for cloning. Performs a BFS and sets all nodes to the new tree.
8304
+ * @remarks Time O(N * M) (O(N) BFS + O(M) `set` for each node).
8295
8305
  *
8296
8306
  * @param cloned - The new, empty tree instance to populate.
8297
8307
  */
8298
8308
  _clone(cloned) {
8299
8309
  this.bfs(
8300
8310
  (node) => {
8301
- if (node === null) cloned.add(null);
8311
+ if (node === null) cloned.set(null);
8302
8312
  else {
8303
- if (this._isMapMode) cloned.add([node.key, this._store.get(node.key)]);
8304
- else cloned.add([node.key, node.value]);
8313
+ if (this._isMapMode) cloned.set([node.key, this._store.get(node.key)]);
8314
+ else cloned.set([node.key, node.value]);
8305
8315
  }
8306
8316
  },
8307
8317
  this._root,
@@ -8634,7 +8644,7 @@ var BST = class extends BinaryTree {
8634
8644
  * Creates an instance of BST.
8635
8645
  * @remarks Time O(N log N) or O(N^2) depending on `isBalanceAdd` in `addMany` and input order. Space O(N).
8636
8646
  *
8637
- * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
8647
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
8638
8648
  * @param [options] - Configuration options for the BST, including comparator.
8639
8649
  */
8640
8650
  constructor(keysNodesEntriesOrRaws = [], options) {
@@ -8648,7 +8658,7 @@ var BST = class extends BinaryTree {
8648
8658
  } else {
8649
8659
  this._comparator = this._createDefaultComparator();
8650
8660
  }
8651
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
8661
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
8652
8662
  }
8653
8663
  _root = void 0;
8654
8664
  /**
@@ -8768,7 +8778,39 @@ var BST = class extends BinaryTree {
8768
8778
  * @returns The first matching node, or undefined if not found.
8769
8779
  */
8770
8780
  getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
8771
- return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? void 0;
8781
+ if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) return void 0;
8782
+ if (this._isPredicate(keyNodeEntryOrPredicate)) {
8783
+ return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? void 0;
8784
+ }
8785
+ if (keyNodeEntryOrPredicate instanceof Range) {
8786
+ return this.getNodes(
8787
+ keyNodeEntryOrPredicate,
8788
+ true,
8789
+ startNode,
8790
+ iterationType
8791
+ )[0] ?? void 0;
8792
+ }
8793
+ let targetKey;
8794
+ if (this.isNode(keyNodeEntryOrPredicate)) {
8795
+ targetKey = keyNodeEntryOrPredicate.key;
8796
+ } else if (this.isEntry(keyNodeEntryOrPredicate)) {
8797
+ const k = keyNodeEntryOrPredicate[0];
8798
+ if (k === null || k === void 0) return void 0;
8799
+ targetKey = k;
8800
+ } else {
8801
+ targetKey = keyNodeEntryOrPredicate;
8802
+ }
8803
+ const start = this.ensureNode(startNode);
8804
+ if (!start) return void 0;
8805
+ const NIL = this._NIL;
8806
+ let cur = start;
8807
+ const cmpFn = this._comparator;
8808
+ while (cur && cur !== NIL) {
8809
+ const c = cmpFn(targetKey, cur.key);
8810
+ if (c === 0) return cur;
8811
+ cur = c < 0 ? cur._left : cur._right;
8812
+ }
8813
+ return void 0;
8772
8814
  }
8773
8815
  /**
8774
8816
  * Searches the tree for nodes matching a predicate, key, or range.
@@ -8789,8 +8831,30 @@ var BST = class extends BinaryTree {
8789
8831
  if (keyNodeEntryOrPredicate === null) return [];
8790
8832
  startNode = this.ensureNode(startNode);
8791
8833
  if (!startNode) return [];
8792
- let predicate;
8793
8834
  const isRange = this.isRange(keyNodeEntryOrPredicate);
8835
+ const isPred = !isRange && this._isPredicate(keyNodeEntryOrPredicate);
8836
+ if (!isRange && !isPred) {
8837
+ let targetKey;
8838
+ if (this.isNode(keyNodeEntryOrPredicate)) {
8839
+ targetKey = keyNodeEntryOrPredicate.key;
8840
+ } else if (this.isEntry(keyNodeEntryOrPredicate)) {
8841
+ const k = keyNodeEntryOrPredicate[0];
8842
+ if (k !== null && k !== void 0) targetKey = k;
8843
+ } else {
8844
+ targetKey = keyNodeEntryOrPredicate;
8845
+ }
8846
+ if (targetKey === void 0) return [];
8847
+ const NIL = this._NIL;
8848
+ const cmpFn = this._comparator;
8849
+ let cur = startNode;
8850
+ while (cur && cur !== NIL) {
8851
+ const c = cmpFn(targetKey, cur.key);
8852
+ if (c === 0) return [callback(cur)];
8853
+ cur = c < 0 ? cur._left : cur._right;
8854
+ }
8855
+ return [];
8856
+ }
8857
+ let predicate;
8794
8858
  if (isRange) {
8795
8859
  predicate = /* @__PURE__ */ __name((node) => {
8796
8860
  if (!node) return false;
@@ -8864,11 +8928,11 @@ var BST = class extends BinaryTree {
8864
8928
  * Adds a new node to the BST based on key comparison.
8865
8929
  * @remarks Time O(log N), where H is tree height. O(N) worst-case (unbalanced tree), O(log N) average. Space O(1).
8866
8930
  *
8867
- * @param keyNodeOrEntry - The key, node, or entry to add.
8931
+ * @param keyNodeOrEntry - The key, node, or entry to set.
8868
8932
  * @param [value] - The value, if providing just a key.
8869
8933
  * @returns True if the addition was successful, false otherwise.
8870
8934
  */
8871
- add(keyNodeOrEntry, value) {
8935
+ set(keyNodeOrEntry, value) {
8872
8936
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
8873
8937
  if (newNode === void 0) return false;
8874
8938
  if (this._root === void 0) {
@@ -8905,24 +8969,24 @@ var BST = class extends BinaryTree {
8905
8969
  }
8906
8970
  /**
8907
8971
  * Adds multiple items to the tree.
8908
- * @remarks If `isBalanceAdd` is true, sorts the input and builds a balanced tree. Time O(N log N) (due to sort and balanced add).
8972
+ * @remarks If `isBalanceAdd` is true, sorts the input and builds a balanced tree. Time O(N log N) (due to sort and balanced set).
8909
8973
  * If false, adds items one by one. Time O(N * H), which is O(N^2) worst-case.
8910
8974
  * Space O(N) for sorting and recursion/iteration stack.
8911
8975
  *
8912
- * @param keysNodesEntriesOrRaws - An iterable of items to add.
8976
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
8913
8977
  * @param [values] - An optional parallel iterable of values.
8914
8978
  * @param [isBalanceAdd=true] - If true, builds a balanced tree from the items.
8915
- * @param [iterationType=this.iterationType] - The traversal method for balanced add (recursive or iterative).
8916
- * @returns An array of booleans indicating the success of each individual `add` operation.
8979
+ * @param [iterationType=this.iterationType] - The traversal method for balanced set (recursive or iterative).
8980
+ * @returns An array of booleans indicating the success of each individual `set` operation.
8917
8981
  */
8918
- addMany(keysNodesEntriesOrRaws, values, isBalanceAdd = true, iterationType = this.iterationType) {
8982
+ setMany(keysNodesEntriesOrRaws, values, isBalanceAdd = true, iterationType = this.iterationType) {
8919
8983
  const inserted = [];
8920
8984
  const valuesIterator = values?.[Symbol.iterator]();
8921
8985
  if (!isBalanceAdd) {
8922
8986
  for (let kve of keysNodesEntriesOrRaws) {
8923
8987
  const val = valuesIterator?.next().value;
8924
8988
  if (this.isRaw(kve)) kve = this._toEntryFn(kve);
8925
- inserted.push(this.add(kve, val));
8989
+ inserted.push(this.set(kve, val));
8926
8990
  }
8927
8991
  return inserted;
8928
8992
  }
@@ -8950,9 +9014,9 @@ var BST = class extends BinaryTree {
8950
9014
  const { key, value, orgIndex } = arr[mid];
8951
9015
  if (this.isRaw(key)) {
8952
9016
  const entry = this._toEntryFn(key);
8953
- inserted[orgIndex] = this.add(entry);
9017
+ inserted[orgIndex] = this.set(entry);
8954
9018
  } else {
8955
- inserted[orgIndex] = this.add(key, value);
9019
+ inserted[orgIndex] = this.set(key, value);
8956
9020
  }
8957
9021
  _dfs(arr.slice(0, mid));
8958
9022
  _dfs(arr.slice(mid + 1));
@@ -8969,9 +9033,9 @@ var BST = class extends BinaryTree {
8969
9033
  const { key, value, orgIndex } = sorted[m];
8970
9034
  if (this.isRaw(key)) {
8971
9035
  const entry = this._toEntryFn(key);
8972
- inserted[orgIndex] = this.add(entry);
9036
+ inserted[orgIndex] = this.set(entry);
8973
9037
  } else {
8974
- inserted[orgIndex] = this.add(key, value);
9038
+ inserted[orgIndex] = this.set(key, value);
8975
9039
  }
8976
9040
  stack.push([m + 1, r]);
8977
9041
  stack.push([l, m - 1]);
@@ -9246,7 +9310,7 @@ var BST = class extends BinaryTree {
9246
9310
  const out = this._createLike([], options);
9247
9311
  let index = 0;
9248
9312
  for (const [key, value] of this) {
9249
- out.add(callback.call(thisArg, value, key, index++, this));
9313
+ out.set(callback.call(thisArg, value, key, index++, this));
9250
9314
  }
9251
9315
  return out;
9252
9316
  }
@@ -9712,7 +9776,7 @@ var BST = class extends BinaryTree {
9712
9776
  succ.left = node.left;
9713
9777
  if (succ.left) succ.left.parent = succ;
9714
9778
  }
9715
- this._size = Math.max(0, (this._size ?? 0) - 1);
9779
+ this._size = Math.max(0, this._size - 1);
9716
9780
  return true;
9717
9781
  }
9718
9782
  };
@@ -10433,14 +10497,14 @@ var AVLTree = class extends BST {
10433
10497
  }
10434
10498
  /**
10435
10499
  * Creates an instance of AVLTree.
10436
- * @remarks Time O(N log N) (from `addMany` with balanced add). Space O(N).
10500
+ * @remarks Time O(N log N) (from `setMany` with balanced set). Space O(N).
10437
10501
  *
10438
- * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
10502
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
10439
10503
  * @param [options] - Configuration options for the AVL tree.
10440
10504
  */
10441
10505
  constructor(keysNodesEntriesOrRaws = [], options) {
10442
10506
  super([], options);
10443
- if (keysNodesEntriesOrRaws) super.addMany(keysNodesEntriesOrRaws);
10507
+ if (keysNodesEntriesOrRaws) super.setMany(keysNodesEntriesOrRaws);
10444
10508
  }
10445
10509
  /**
10446
10510
  * (Protected) Creates a new AVL tree node.
@@ -10464,16 +10528,16 @@ var AVLTree = class extends BST {
10464
10528
  return keyNodeOrEntry instanceof AVLTreeNode;
10465
10529
  }
10466
10530
  /**
10467
- * Adds a new node to the AVL tree and balances the tree path.
10468
- * @remarks Time O(log N) (O(H) for BST add + O(H) for `_balancePath`). Space O(H) for path/recursion.
10531
+ * Sets a new node to the AVL tree and balances the tree path.
10532
+ * @remarks Time O(log N) (O(H) for BST set + O(H) for `_balancePath`). Space O(H) for path/recursion.
10469
10533
  *
10470
- * @param keyNodeOrEntry - The key, node, or entry to add.
10534
+ * @param keyNodeOrEntry - The key, node, or entry to set.
10471
10535
  * @param [value] - The value, if providing just a key.
10472
10536
  * @returns True if the addition was successful, false otherwise.
10473
10537
  */
10474
- add(keyNodeOrEntry, value) {
10538
+ set(keyNodeOrEntry, value) {
10475
10539
  if (keyNodeOrEntry === null) return false;
10476
- const inserted = super.add(keyNodeOrEntry, value);
10540
+ const inserted = super.set(keyNodeOrEntry, value);
10477
10541
  if (inserted) this._balancePath(keyNodeOrEntry);
10478
10542
  return inserted;
10479
10543
  }
@@ -10525,7 +10589,7 @@ var AVLTree = class extends BST {
10525
10589
  }
10526
10590
  /**
10527
10591
  * Creates a new AVLTree by mapping each [key, value] pair.
10528
- * @remarks Time O(N log N) (O(N) iteration + O(log M) `add` for each item into the new tree). Space O(N) for the new tree.
10592
+ * @remarks Time O(N log N) (O(N) iteration + O(log M) `set` for each item into the new tree). Space O(N) for the new tree.
10529
10593
  *
10530
10594
  * @template MK - New key type.
10531
10595
  * @template MV - New value type.
@@ -10539,7 +10603,7 @@ var AVLTree = class extends BST {
10539
10603
  const out = this._createLike([], options);
10540
10604
  let index = 0;
10541
10605
  for (const [key, value] of this) {
10542
- out.add(callback.call(thisArg, value, key, index++, this));
10606
+ out.set(callback.call(thisArg, value, key, index++, this));
10543
10607
  }
10544
10608
  return out;
10545
10609
  }
@@ -10828,12 +10892,11 @@ var RedBlackTreeNode = class {
10828
10892
  value;
10829
10893
  parent = void 0;
10830
10894
  /**
10831
- * Create a Red-Black Tree and optionally bulk-insert items.
10832
- * @remarks Time O(n log n), Space O(n)
10833
- * @param key - See parameter type for details.
10834
- * @param [value]- See parameter type for details.
10835
- * @param color - See parameter type for details.
10836
- * @returns New RedBlackTree instance.
10895
+ * Create a Red-Black Tree node.
10896
+ * @remarks Time O(1), Space O(1)
10897
+ * @param key - Node key.
10898
+ * @param [value] - Node value (unused in map mode trees).
10899
+ * @param color - Node color.
10837
10900
  */
10838
10901
  constructor(key, value, color = "BLACK") {
10839
10902
  this.key = key;
@@ -10964,11 +11027,33 @@ var RedBlackTree = class extends BST {
10964
11027
  constructor(keysNodesEntriesOrRaws = [], options) {
10965
11028
  super([], options);
10966
11029
  this._root = this.NIL;
11030
+ this._header = new RedBlackTreeNode(void 0, void 0, "BLACK");
11031
+ this._header.parent = this.NIL;
11032
+ this._header._left = this.NIL;
11033
+ this._header._right = this.NIL;
10967
11034
  if (keysNodesEntriesOrRaws) {
10968
- this.addMany(keysNodesEntriesOrRaws);
11035
+ this.setMany(keysNodesEntriesOrRaws);
10969
11036
  }
10970
11037
  }
10971
11038
  _root;
11039
+ /**
11040
+ * (Internal) Header sentinel:
11041
+ * - header.parent -> root
11042
+ * - header._left -> min (or NIL)
11043
+ * - header._right -> max (or NIL)
11044
+ *
11045
+ * IMPORTANT:
11046
+ * - This header is NOT part of the actual tree.
11047
+ * - Do NOT use `header.left` / `header.right` accessors for wiring: those setters update `NIL.parent`
11048
+ * and can corrupt sentinel invariants / cause hangs. Only touch `header._left/_right`.
11049
+ */
11050
+ _header;
11051
+ /**
11052
+ * (Internal) Cache of the current minimum and maximum nodes.
11053
+ * Used for fast-path insert/update when keys are monotonic or near-boundary.
11054
+ */
11055
+ _minNode;
11056
+ _maxNode;
10972
11057
  /**
10973
11058
  * Get the current root node.
10974
11059
  * @remarks Time O(1), Space O(1)
@@ -11002,18 +11087,387 @@ var RedBlackTree = class extends BST {
11002
11087
  * @remarks Time O(n), Space O(1)
11003
11088
  * @returns void
11004
11089
  */
11090
+ /**
11091
+ * Remove all nodes and clear internal caches.
11092
+ * @remarks Time O(n) average, Space O(1)
11093
+ */
11005
11094
  clear() {
11006
11095
  super.clear();
11007
11096
  this._root = this.NIL;
11097
+ this._header.parent = this.NIL;
11098
+ this._setMinCache(void 0);
11099
+ this._setMaxCache(void 0);
11008
11100
  }
11009
11101
  /**
11010
- * Insert or replace an entry using BST order and red-black fix-up.
11011
- * @remarks Time O(log n), Space O(1)
11012
- * @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
11013
- * @param [value]- See parameter type for details.
11014
- * @returns True if inserted or updated; false if ignored.
11102
+ * (Internal) Find a node by key using a tight BST walk (no allocations).
11103
+ *
11104
+ * NOTE: This uses `header.parent` as the canonical root pointer.
11105
+ * @remarks Time O(log n) average, Space O(1)
11106
+ */
11107
+ _findNodeByKey(key) {
11108
+ const NIL = this.NIL;
11109
+ const cmp = this._compare.bind(this);
11110
+ let cur = this._header.parent ?? NIL;
11111
+ while (cur !== NIL) {
11112
+ const c = cmp(key, cur.key);
11113
+ if (c < 0) cur = cur.left ?? NIL;
11114
+ else if (c > 0) cur = cur.right ?? NIL;
11115
+ else return cur;
11116
+ }
11117
+ return void 0;
11118
+ }
11119
+ /**
11120
+ * (Internal) In-order predecessor of a node in a BST.
11121
+ * @remarks Time O(log n) average, Space O(1)
11122
+ */
11123
+ _predecessorOf(node) {
11124
+ const NIL = this.NIL;
11125
+ if (node.left && node.left !== NIL) {
11126
+ let cur2 = node.left;
11127
+ while (cur2.right && cur2.right !== NIL) cur2 = cur2.right;
11128
+ return cur2;
11129
+ }
11130
+ let cur = node;
11131
+ let p = node.parent;
11132
+ while (p && cur === p.left) {
11133
+ cur = p;
11134
+ p = p.parent;
11135
+ }
11136
+ return p;
11137
+ }
11138
+ /**
11139
+ * (Internal) In-order successor of a node in a BST.
11140
+ * @remarks Time O(log n) average, Space O(1)
11141
+ */
11142
+ _successorOf(node) {
11143
+ const NIL = this.NIL;
11144
+ if (node.right && node.right !== NIL) {
11145
+ let cur2 = node.right;
11146
+ while (cur2.left && cur2.left !== NIL) cur2 = cur2.left;
11147
+ return cur2;
11148
+ }
11149
+ let cur = node;
11150
+ let p = node.parent;
11151
+ while (p && cur === p.right) {
11152
+ cur = p;
11153
+ p = p.parent;
11154
+ }
11155
+ return p;
11156
+ }
11157
+ /**
11158
+ * (Internal) Attach a new node directly under a known parent/side (no search).
11159
+ *
11160
+ * This is a performance-oriented helper used by boundary fast paths and hinted insertion.
11161
+ * It will:
11162
+ * - wire parent/child pointers (using accessors, so parent pointers are updated)
11163
+ * - initialize children to NIL
11164
+ * - mark the new node RED, then run insert fix-up
11165
+ *
11166
+ * Precondition: the chosen slot (parent.left/parent.right) is empty (NIL/null/undefined).
11167
+ * @remarks Time O(log n) average, Space O(1)
11168
+ */
11169
+ _attachNewNode(parent, side, node) {
11170
+ const NIL = this.NIL;
11171
+ node.parent = parent;
11172
+ if (side === "left") parent.left = node;
11173
+ else parent.right = node;
11174
+ node.left = NIL;
11175
+ node.right = NIL;
11176
+ node.color = "RED";
11177
+ this._insertFixup(node);
11178
+ if (this.isRealNode(this._root)) this._root.color = "BLACK";
11179
+ }
11180
+ /**
11181
+ * (Internal) a single source of truth for min/max is header._left/_right.
11182
+ * Keep legacy _minNode/_maxNode mirrored for compatibility.
11183
+ * @remarks Time O(1), Space O(1)
11184
+ */
11185
+ /**
11186
+ * (Internal) Update min cache pointers (header._left is the canonical min pointer).
11187
+ * @remarks Time O(1), Space O(1)
11188
+ */
11189
+ _setMinCache(node) {
11190
+ this._minNode = node;
11191
+ this._header._left = node ?? this.NIL;
11192
+ }
11193
+ /**
11194
+ * (Internal) Update max cache pointers (header._right is the canonical max pointer).
11195
+ * @remarks Time O(1), Space O(1)
11196
+ */
11197
+ _setMaxCache(node) {
11198
+ this._maxNode = node;
11199
+ this._header._right = node ?? this.NIL;
11200
+ }
11201
+ /**
11202
+ * (Internal) Core set implementation returning the affected node.
11203
+ *
11204
+ * Hot path goals:
11205
+ * - Avoid double walks (search+insert): do a single traversal that either updates or inserts.
11206
+ * - Use header min/max caches to fast-path boundary inserts.
11207
+ * - Keep header._left/_right as canonical min/max pointers.
11208
+ *
11209
+ * Return value:
11210
+ * - `{ node, created:false }` when an existing key is updated
11211
+ * - `{ node, created:true }` when a new node is inserted
11212
+ * - `undefined` only on unexpected internal failure.
11213
+ * @remarks Time O(log n) average, Space O(1)
11214
+ */
11215
+ _setKVNode(key, nextValue) {
11216
+ const NIL = this.NIL;
11217
+ const comparator = this._comparator;
11218
+ const header = this._header;
11219
+ const minN = header._left ?? NIL;
11220
+ if (minN !== NIL) {
11221
+ const cMin = comparator(key, minN.key);
11222
+ if (cMin === 0) {
11223
+ if (this._isMapMode) {
11224
+ if (nextValue !== void 0) this._store.set(key, nextValue);
11225
+ else this._setValue(key, nextValue);
11226
+ } else minN.value = nextValue;
11227
+ return { node: minN, created: false };
11228
+ }
11229
+ const minL = minN.left;
11230
+ if (cMin < 0 && (minL === NIL || minL === null || minL === void 0)) {
11231
+ const newNode2 = this.createNode(key, nextValue);
11232
+ this._attachNewNode(minN, "left", newNode2);
11233
+ if (this._isMapMode) {
11234
+ if (nextValue !== void 0) this._store.set(newNode2.key, nextValue);
11235
+ else this._setValue(newNode2.key, nextValue);
11236
+ }
11237
+ this._size++;
11238
+ this._setMinCache(newNode2);
11239
+ if (header._right === NIL) this._setMaxCache(newNode2);
11240
+ return { node: newNode2, created: true };
11241
+ }
11242
+ if (cMin > 0) {
11243
+ const maxN = header._right ?? NIL;
11244
+ const cMax = comparator(key, maxN.key);
11245
+ if (cMax === 0) {
11246
+ if (this._isMapMode) {
11247
+ if (nextValue !== void 0) this._store.set(key, nextValue);
11248
+ else this._setValue(key, nextValue);
11249
+ } else maxN.value = nextValue;
11250
+ return { node: maxN, created: false };
11251
+ }
11252
+ const maxR = maxN.right;
11253
+ if (cMax > 0 && (maxR === NIL || maxR === null || maxR === void 0)) {
11254
+ const newNode2 = this.createNode(key, nextValue);
11255
+ this._attachNewNode(maxN, "right", newNode2);
11256
+ if (this._isMapMode) {
11257
+ if (nextValue !== void 0) this._store.set(newNode2.key, nextValue);
11258
+ else this._setValue(newNode2.key, nextValue);
11259
+ }
11260
+ this._size++;
11261
+ this._setMaxCache(newNode2);
11262
+ if (header._left === NIL) this._setMinCache(newNode2);
11263
+ return { node: newNode2, created: true };
11264
+ }
11265
+ }
11266
+ }
11267
+ const cmp = comparator;
11268
+ const isMapMode = this._isMapMode;
11269
+ const store = this._store;
11270
+ let current = this._header.parent ?? NIL;
11271
+ let parent;
11272
+ let lastCompared = 0;
11273
+ while (current !== NIL) {
11274
+ parent = current;
11275
+ lastCompared = cmp(key, current.key);
11276
+ if (lastCompared < 0) current = current.left ?? NIL;
11277
+ else if (lastCompared > 0) current = current.right ?? NIL;
11278
+ else {
11279
+ if (isMapMode) {
11280
+ if (nextValue !== void 0) store.set(key, nextValue);
11281
+ else this._setValue(key, nextValue);
11282
+ } else {
11283
+ current.value = nextValue;
11284
+ }
11285
+ return { node: current, created: false };
11286
+ }
11287
+ }
11288
+ const newNode = this.createNode(key, nextValue);
11289
+ newNode.parent = parent;
11290
+ if (!parent) {
11291
+ this._setRoot(newNode);
11292
+ } else if (lastCompared < 0) {
11293
+ parent.left = newNode;
11294
+ } else {
11295
+ parent.right = newNode;
11296
+ }
11297
+ newNode.left = NIL;
11298
+ newNode.right = NIL;
11299
+ newNode.color = "RED";
11300
+ this._insertFixup(newNode);
11301
+ if (this.isRealNode(this._root)) this._root.color = "BLACK";
11302
+ else return void 0;
11303
+ if (isMapMode) {
11304
+ if (nextValue !== void 0) store.set(newNode.key, nextValue);
11305
+ else this._setValue(newNode.key, nextValue);
11306
+ }
11307
+ this._size++;
11308
+ const hMin = this._header._left ?? NIL;
11309
+ const hMax = this._header._right ?? NIL;
11310
+ if (hMin === NIL || hMax === NIL) {
11311
+ this._setMinCache(newNode);
11312
+ this._setMaxCache(newNode);
11313
+ } else if (parent === hMax && lastCompared > 0) {
11314
+ this._setMaxCache(newNode);
11315
+ } else if (parent === hMin && lastCompared < 0) {
11316
+ this._setMinCache(newNode);
11317
+ } else {
11318
+ if (cmp(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11319
+ if (cmp(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11320
+ }
11321
+ return { node: newNode, created: true };
11322
+ }
11323
+ /**
11324
+ * (Internal) Boolean wrapper around `_setKVNode`.
11325
+ *
11326
+ * Includes a map-mode update fast-path:
11327
+ * - If `isMapMode=true` and the key already exists in `_store`, then updating the value does not
11328
+ * require any tree search/rotation (tree shape depends only on key).
11329
+ * - This path is intentionally limited to `nextValue !== undefined` to preserve existing
11330
+ * semantics for `undefined` values.
11331
+ * @remarks Time O(log n) average, Space O(1)
11332
+ */
11333
+ _setKV(key, nextValue) {
11334
+ if (this._isMapMode && nextValue !== void 0) {
11335
+ const store = this._store;
11336
+ if (store.has(key)) {
11337
+ store.set(key, nextValue);
11338
+ return true;
11339
+ }
11340
+ }
11341
+ return this._setKVNode(key, nextValue) !== void 0;
11342
+ }
11343
+ /**
11344
+ * Insert/update using a hint node to speed up nearby insertions.
11345
+ *
11346
+ * close to the expected insertion position (often the previously returned node in a loop).
11347
+ *
11348
+ * When the hint is a good fit (sorted / nearly-sorted insertion), this can avoid most of the
11349
+ * normal root-to-leaf search and reduce constant factors.
11350
+ *
11351
+ * When the hint does not match (random workloads), this will fall back to the normal set path.
11352
+ * @remarks Time O(log n) average, Space O(1)
11015
11353
  */
11016
- add(keyNodeOrEntry, value) {
11354
+ setWithHintNode(key, value, hint) {
11355
+ if (!hint || !this.isRealNode(hint)) {
11356
+ return this._setKVNode(key, value)?.node;
11357
+ }
11358
+ const cmp = this._compare.bind(this);
11359
+ const c0 = cmp(key, hint.key);
11360
+ if (c0 === 0) {
11361
+ if (this._isMapMode) {
11362
+ if (value !== void 0) this._store.set(key, value);
11363
+ else this._setValue(key, value);
11364
+ } else hint.value = value;
11365
+ return hint;
11366
+ }
11367
+ if (c0 < 0) {
11368
+ if (!this.isRealNode(hint.left)) {
11369
+ const newNode = this.createNode(key, value);
11370
+ if (!this.isRealNode(newNode)) return void 0;
11371
+ this._attachNewNode(hint, "left", newNode);
11372
+ if (this._isMapMode) {
11373
+ if (value !== void 0) this._store.set(key, value);
11374
+ else this._setValue(key, value);
11375
+ }
11376
+ this._size++;
11377
+ const NIL = this.NIL;
11378
+ const hMin = this._header._left ?? NIL;
11379
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11380
+ const hMax = this._header._right ?? NIL;
11381
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11382
+ return newNode;
11383
+ }
11384
+ const pred = this._predecessorOf(hint);
11385
+ if (pred && cmp(pred.key, key) >= 0) {
11386
+ return this._setKVNode(key, value)?.node;
11387
+ }
11388
+ if (pred && !this.isRealNode(pred.right)) {
11389
+ const newNode = this.createNode(key, value);
11390
+ if (!this.isRealNode(newNode)) return void 0;
11391
+ this._attachNewNode(pred, "right", newNode);
11392
+ if (this._isMapMode) {
11393
+ if (value !== void 0) this._store.set(key, value);
11394
+ else this._setValue(key, value);
11395
+ }
11396
+ this._size++;
11397
+ const NIL = this.NIL;
11398
+ const hMin = this._header._left ?? NIL;
11399
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11400
+ const hMax = this._header._right ?? NIL;
11401
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11402
+ return newNode;
11403
+ }
11404
+ return this._setKVNode(key, value)?.node;
11405
+ }
11406
+ if (!this.isRealNode(hint.right)) {
11407
+ const newNode = this.createNode(key, value);
11408
+ if (!this.isRealNode(newNode)) return void 0;
11409
+ this._attachNewNode(hint, "right", newNode);
11410
+ if (this._isMapMode) {
11411
+ if (value !== void 0) this._store.set(key, value);
11412
+ else this._setValue(key, value);
11413
+ }
11414
+ this._size++;
11415
+ const NIL = this.NIL;
11416
+ const hMin = this._header._left ?? NIL;
11417
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11418
+ const hMax = this._header._right ?? NIL;
11419
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11420
+ return newNode;
11421
+ }
11422
+ const succ = this._successorOf(hint);
11423
+ if (succ && cmp(succ.key, key) <= 0) {
11424
+ return this._setKVNode(key, value)?.node;
11425
+ }
11426
+ if (succ && !this.isRealNode(succ.left)) {
11427
+ const newNode = this.createNode(key, value);
11428
+ if (!this.isRealNode(newNode)) return void 0;
11429
+ this._attachNewNode(succ, "left", newNode);
11430
+ if (this._isMapMode) {
11431
+ if (value !== void 0) this._store.set(key, value);
11432
+ else this._setValue(key, value);
11433
+ }
11434
+ this._size++;
11435
+ const NIL = this.NIL;
11436
+ const hMin = this._header._left ?? NIL;
11437
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11438
+ const hMax = this._header._right ?? NIL;
11439
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11440
+ return newNode;
11441
+ }
11442
+ return this._setKVNode(key, value)?.node;
11443
+ }
11444
+ /**
11445
+ * Boolean wrapper for setWithHintNode.
11446
+ * @remarks Time O(log n) average, Space O(1)
11447
+ */
11448
+ setWithHint(key, value, hint) {
11449
+ return this.setWithHintNode(key, value, hint) !== void 0;
11450
+ }
11451
+ /**
11452
+ * Insert or update a key/value (map mode) or key-only (set mode).
11453
+ *
11454
+ * This method is optimized for:
11455
+ * - monotonic inserts via min/max boundary fast paths
11456
+ * - updates via a single-pass search (no double walk)
11457
+ *
11458
+ * @remarks Time O(log n) average, Space O(1)
11459
+ */
11460
+ set(keyNodeOrEntry, value) {
11461
+ if (!this.isNode(keyNodeOrEntry)) {
11462
+ if (keyNodeOrEntry === null || keyNodeOrEntry === void 0) return false;
11463
+ if (this.isEntry(keyNodeOrEntry)) {
11464
+ const key = keyNodeOrEntry[0];
11465
+ if (key === null || key === void 0) return false;
11466
+ const nextValue = value ?? keyNodeOrEntry[1];
11467
+ return this._setKV(key, nextValue);
11468
+ }
11469
+ return this._setKV(keyNodeOrEntry, value);
11470
+ }
11017
11471
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
11018
11472
  if (!this.isRealNode(newNode)) return false;
11019
11473
  const insertStatus = this._insert(newNode);
@@ -11035,19 +11489,23 @@ var RedBlackTree = class extends BST {
11035
11489
  }
11036
11490
  /**
11037
11491
  * Delete a node by key/node/entry and rebalance as needed.
11038
- * @remarks Time O(log n), Space O(1)
11039
- * @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node to delete.
11492
+ * @remarks Time O(log n) average, Space O(1)
11493
+ * @param keyNodeEntryRawOrPredicate - Key, node, or [key, value] entry identifying the node to delete.
11040
11494
  * @returns Array with deletion metadata (removed node, rebalancing hint if any).
11041
11495
  */
11042
- delete(keyNodeOrEntry) {
11043
- if (keyNodeOrEntry === null) return [];
11496
+ delete(keyNodeEntryRawOrPredicate) {
11497
+ if (keyNodeEntryRawOrPredicate === null) return [];
11044
11498
  const results = [];
11045
11499
  let nodeToDelete;
11046
- if (this._isPredicate(keyNodeOrEntry)) nodeToDelete = this.getNode(keyNodeOrEntry);
11047
- else nodeToDelete = this.isRealNode(keyNodeOrEntry) ? keyNodeOrEntry : this.getNode(keyNodeOrEntry);
11500
+ if (this._isPredicate(keyNodeEntryRawOrPredicate)) nodeToDelete = this.getNode(keyNodeEntryRawOrPredicate);
11501
+ else nodeToDelete = this.isRealNode(keyNodeEntryRawOrPredicate) ? keyNodeEntryRawOrPredicate : this.getNode(keyNodeEntryRawOrPredicate);
11048
11502
  if (!nodeToDelete) {
11049
11503
  return results;
11050
11504
  }
11505
+ const willDeleteMin = nodeToDelete === this._minNode;
11506
+ const willDeleteMax = nodeToDelete === this._maxNode;
11507
+ const nextMin = willDeleteMin ? this._successorOf(nodeToDelete) : void 0;
11508
+ const nextMax = willDeleteMax ? this._predecessorOf(nodeToDelete) : void 0;
11051
11509
  let originalColor = nodeToDelete.color;
11052
11510
  let replacementNode;
11053
11511
  if (!this.isRealNode(nodeToDelete.left)) {
@@ -11086,6 +11544,19 @@ var RedBlackTree = class extends BST {
11086
11544
  }
11087
11545
  if (this._isMapMode) this._store.delete(nodeToDelete.key);
11088
11546
  this._size--;
11547
+ if (this._size <= 0) {
11548
+ this._setMinCache(void 0);
11549
+ this._setMaxCache(void 0);
11550
+ } else {
11551
+ if (willDeleteMin) this._setMinCache(nextMin);
11552
+ if (willDeleteMax) this._setMaxCache(nextMax);
11553
+ if (!this._minNode || !this.isRealNode(this._minNode)) {
11554
+ this._setMinCache(this.isRealNode(this._root) ? this.getLeftMost((n) => n, this._root) : void 0);
11555
+ }
11556
+ if (!this._maxNode || !this.isRealNode(this._maxNode)) {
11557
+ this._setMaxCache(this.isRealNode(this._root) ? this.getRightMost((n) => n, this._root) : void 0);
11558
+ }
11559
+ }
11089
11560
  if (originalColor === "BLACK") {
11090
11561
  this._deleteFixup(replacementNode);
11091
11562
  }
@@ -11094,7 +11565,7 @@ var RedBlackTree = class extends BST {
11094
11565
  }
11095
11566
  /**
11096
11567
  * Transform entries into a like-kind red-black tree with possibly different key/value types.
11097
- * @remarks Time O(n), Space O(n)
11568
+ * @remarks Time O(n) average, Space O(n)
11098
11569
  * @template MK
11099
11570
  * @template MV
11100
11571
  * @template MR
@@ -11107,44 +11578,65 @@ var RedBlackTree = class extends BST {
11107
11578
  const out = this._createLike([], options);
11108
11579
  let index = 0;
11109
11580
  for (const [key, value] of this) {
11110
- out.add(callback.call(thisArg, value, key, index++, this));
11581
+ out.set(callback.call(thisArg, value, key, index++, this));
11111
11582
  }
11112
11583
  return out;
11113
11584
  }
11585
+ /**
11586
+ * (Internal) Create an empty instance of the same concrete tree type.
11587
+ * @remarks Time O(1) average, Space O(1)
11588
+ */
11114
11589
  _createInstance(options) {
11115
11590
  const Ctor = this.constructor;
11116
11591
  return new Ctor([], { ...this._snapshotOptions(), ...options ?? {} });
11117
11592
  }
11593
+ /**
11594
+ * (Internal) Create a like-kind tree (same concrete class) populated from an iterable.
11595
+ * @remarks Time O(m log m) average (m = iterable length), Space O(m)
11596
+ */
11118
11597
  _createLike(iter = [], options) {
11119
11598
  const Ctor = this.constructor;
11120
11599
  return new Ctor(iter, { ...this._snapshotOptions(), ...options ?? {} });
11121
11600
  }
11601
+ /**
11602
+ * (Internal) Set the root pointer and keep header.parent in sync.
11603
+ * @remarks Time O(1), Space O(1)
11604
+ */
11122
11605
  _setRoot(v) {
11606
+ const NIL = this.NIL;
11123
11607
  if (v) {
11124
11608
  v.parent = void 0;
11125
11609
  }
11126
11610
  this._root = v;
11611
+ this._header.parent = v ?? NIL;
11127
11612
  }
11613
+ /**
11614
+ * (Internal) Replace a node in place while preserving its color.
11615
+ * @remarks Time O(1) average, Space O(1)
11616
+ */
11128
11617
  _replaceNode(oldNode, newNode) {
11129
11618
  newNode.color = oldNode.color;
11130
11619
  return super._replaceNode(oldNode, newNode);
11131
11620
  }
11132
11621
  /**
11133
11622
  * (Protected) Standard BST insert followed by red-black fix-up.
11134
- * @remarks Time O(log n), Space O(1)
11623
+ * @remarks Time O(log n) average, Space O(1)
11135
11624
  * @param node - Node to insert.
11136
11625
  * @returns Status string: 'CREATED' or 'UPDATED'.
11137
11626
  */
11138
11627
  _insert(node) {
11139
- let current = this.root ?? this.NIL;
11140
- let parent = void 0;
11141
- while (current !== this.NIL) {
11628
+ const NIL = this.NIL;
11629
+ const cmp = this._compare.bind(this);
11630
+ let current = this._header.parent ?? NIL;
11631
+ let parent;
11632
+ let lastCompared = 0;
11633
+ while (current !== NIL) {
11142
11634
  parent = current;
11143
- const compared = this._compare(node.key, current.key);
11144
- if (compared < 0) {
11145
- current = current.left ?? this.NIL;
11146
- } else if (compared > 0) {
11147
- current = current.right ?? this.NIL;
11635
+ lastCompared = cmp(node.key, current.key);
11636
+ if (lastCompared < 0) {
11637
+ current = current.left ?? NIL;
11638
+ } else if (lastCompared > 0) {
11639
+ current = current.right ?? NIL;
11148
11640
  } else {
11149
11641
  this._replaceNode(current, node);
11150
11642
  return "UPDATED";
@@ -11153,13 +11645,13 @@ var RedBlackTree = class extends BST {
11153
11645
  node.parent = parent;
11154
11646
  if (!parent) {
11155
11647
  this._setRoot(node);
11156
- } else if (this._compare(node.key, parent.key) < 0) {
11648
+ } else if (lastCompared < 0) {
11157
11649
  parent.left = node;
11158
11650
  } else {
11159
11651
  parent.right = node;
11160
11652
  }
11161
- node.left = this.NIL;
11162
- node.right = this.NIL;
11653
+ node.left = NIL;
11654
+ node.right = NIL;
11163
11655
  node.color = "RED";
11164
11656
  this._insertFixup(node);
11165
11657
  return "CREATED";
@@ -11185,55 +11677,66 @@ var RedBlackTree = class extends BST {
11185
11677
  }
11186
11678
  /**
11187
11679
  * (Protected) Restore red-black properties after insertion (recolor/rotate).
11188
- * @remarks Time O(log n), Space O(1)
11680
+ * @remarks Time O(log n) average, Space O(1)
11189
11681
  * @param z - Recently inserted node.
11190
11682
  * @returns void
11191
11683
  */
11192
11684
  _insertFixup(z) {
11193
- while (z?.parent?.color === "RED") {
11194
- if (z.parent === z.parent.parent?.left) {
11195
- const y = z.parent.parent.right;
11685
+ const leftRotate = this._leftRotate.bind(this);
11686
+ const rightRotate = this._rightRotate.bind(this);
11687
+ while (z) {
11688
+ const p = z.parent;
11689
+ if (!p || p.color !== "RED") break;
11690
+ const gp = p.parent;
11691
+ if (!gp) break;
11692
+ if (p === gp.left) {
11693
+ const y = gp.right;
11196
11694
  if (y?.color === "RED") {
11197
- z.parent.color = "BLACK";
11695
+ p.color = "BLACK";
11198
11696
  y.color = "BLACK";
11199
- z.parent.parent.color = "RED";
11200
- z = z.parent.parent;
11201
- } else {
11202
- if (z === z.parent.right) {
11203
- z = z.parent;
11204
- this._leftRotate(z);
11205
- }
11206
- if (z && z.parent && z.parent.parent) {
11207
- z.parent.color = "BLACK";
11208
- z.parent.parent.color = "RED";
11209
- this._rightRotate(z.parent.parent);
11210
- }
11697
+ gp.color = "RED";
11698
+ z = gp;
11699
+ continue;
11700
+ }
11701
+ if (z === p.right) {
11702
+ z = p;
11703
+ leftRotate(z);
11704
+ }
11705
+ const p2 = z?.parent;
11706
+ const gp2 = p2?.parent;
11707
+ if (p2 && gp2) {
11708
+ p2.color = "BLACK";
11709
+ gp2.color = "RED";
11710
+ rightRotate(gp2);
11211
11711
  }
11212
11712
  } else {
11213
- const y = z?.parent?.parent?.left ?? void 0;
11713
+ const y = gp.left;
11214
11714
  if (y?.color === "RED") {
11215
- z.parent.color = "BLACK";
11715
+ p.color = "BLACK";
11216
11716
  y.color = "BLACK";
11217
- z.parent.parent.color = "RED";
11218
- z = z.parent.parent;
11219
- } else {
11220
- if (z === z.parent.left) {
11221
- z = z.parent;
11222
- this._rightRotate(z);
11223
- }
11224
- if (z && z.parent && z.parent.parent) {
11225
- z.parent.color = "BLACK";
11226
- z.parent.parent.color = "RED";
11227
- this._leftRotate(z.parent.parent);
11228
- }
11717
+ gp.color = "RED";
11718
+ z = gp;
11719
+ continue;
11720
+ }
11721
+ if (z === p.left) {
11722
+ z = p;
11723
+ rightRotate(z);
11724
+ }
11725
+ const p2 = z?.parent;
11726
+ const gp2 = p2?.parent;
11727
+ if (p2 && gp2) {
11728
+ p2.color = "BLACK";
11729
+ gp2.color = "RED";
11730
+ leftRotate(gp2);
11229
11731
  }
11230
11732
  }
11733
+ break;
11231
11734
  }
11232
11735
  if (this.isRealNode(this._root)) this._root.color = "BLACK";
11233
11736
  }
11234
11737
  /**
11235
11738
  * (Protected) Restore red-black properties after deletion (recolor/rotate).
11236
- * @remarks Time O(log n), Space O(1)
11739
+ * @remarks Time O(log n) average, Space O(1)
11237
11740
  * @param node - Child that replaced the deleted node (may be undefined).
11238
11741
  * @returns void
11239
11742
  */
@@ -11495,7 +11998,7 @@ var AVLTreeMultiMap = class extends AVLTree {
11495
11998
  constructor(keysNodesEntriesOrRaws = [], options) {
11496
11999
  super([], { ...options, isMapMode: true });
11497
12000
  if (keysNodesEntriesOrRaws) {
11498
- this.addMany(keysNodesEntriesOrRaws);
12001
+ this.setMany(keysNodesEntriesOrRaws);
11499
12002
  }
11500
12003
  }
11501
12004
  createNode(key, value = []) {
@@ -11515,27 +12018,27 @@ var AVLTreeMultiMap = class extends AVLTree {
11515
12018
  * Insert a value or a list of values into the multimap. If the key exists, values are appended.
11516
12019
  * @remarks Time O(log N + M), Space O(1)
11517
12020
  * @param keyNodeOrEntry - Key, node, or [key, values] entry.
11518
- * @param [value] - Single value to add when a bare key is provided.
12021
+ * @param [value] - Single value to set when a bare key is provided.
11519
12022
  * @returns True if inserted or appended; false if ignored.
11520
12023
  */
11521
- add(keyNodeOrEntry, value) {
11522
- if (this.isRealNode(keyNodeOrEntry)) return super.add(keyNodeOrEntry);
12024
+ set(keyNodeOrEntry, value) {
12025
+ if (this.isRealNode(keyNodeOrEntry)) return super.set(keyNodeOrEntry);
11523
12026
  const _commonAdd = /* @__PURE__ */ __name((key, values) => {
11524
12027
  if (key === void 0 || key === null) return false;
11525
- const _addToValues = /* @__PURE__ */ __name(() => {
12028
+ const _setToValues = /* @__PURE__ */ __name(() => {
11526
12029
  const existingValues = this.get(key);
11527
12030
  if (existingValues !== void 0 && values !== void 0) {
11528
12031
  for (const value2 of values) existingValues.push(value2);
11529
12032
  return true;
11530
12033
  }
11531
12034
  return false;
11532
- }, "_addToValues");
11533
- const _addByNode = /* @__PURE__ */ __name(() => {
12035
+ }, "_setToValues");
12036
+ const _setByNode = /* @__PURE__ */ __name(() => {
11534
12037
  const existingNode = this.getNode(key);
11535
12038
  if (this.isRealNode(existingNode)) {
11536
12039
  const existingValues = this.get(existingNode);
11537
12040
  if (existingValues === void 0) {
11538
- super.add(key, values);
12041
+ super.set(key, values);
11539
12042
  return true;
11540
12043
  }
11541
12044
  if (values !== void 0) {
@@ -11545,13 +12048,13 @@ var AVLTreeMultiMap = class extends AVLTree {
11545
12048
  return false;
11546
12049
  }
11547
12050
  } else {
11548
- return super.add(key, values);
12051
+ return super.set(key, values);
11549
12052
  }
11550
- }, "_addByNode");
12053
+ }, "_setByNode");
11551
12054
  if (this._isMapMode) {
11552
- return _addByNode() || _addToValues();
12055
+ return _setByNode() || _setToValues();
11553
12056
  }
11554
- return _addToValues() || _addByNode();
12057
+ return _setToValues() || _setByNode();
11555
12058
  }, "_commonAdd");
11556
12059
  if (this.isEntry(keyNodeOrEntry)) {
11557
12060
  const [key, values] = keyNodeOrEntry;
@@ -11619,7 +12122,7 @@ var AVLTreeMultiMap = class extends AVLTree {
11619
12122
  map(callback, options, thisArg) {
11620
12123
  const out = this._createLike([], options);
11621
12124
  let i = 0;
11622
- for (const [k, v] of this) out.add(callback.call(thisArg, v, k, i++, this));
12125
+ for (const [k, v] of this) out.set(callback.call(thisArg, v, k, i++, this));
11623
12126
  return out;
11624
12127
  }
11625
12128
  /**
@@ -11802,7 +12305,7 @@ var TreeMultiMap = class extends RedBlackTree {
11802
12305
  constructor(keysNodesEntriesOrRaws = [], options) {
11803
12306
  super([], { ...options });
11804
12307
  if (keysNodesEntriesOrRaws) {
11805
- this.addMany(keysNodesEntriesOrRaws);
12308
+ this.setMany(keysNodesEntriesOrRaws);
11806
12309
  }
11807
12310
  }
11808
12311
  createNode(key, value = []) {
@@ -11822,27 +12325,27 @@ var TreeMultiMap = class extends RedBlackTree {
11822
12325
  * Insert a value or a list of values into the multimap. If the key exists, values are appended.
11823
12326
  * @remarks Time O(log N + M), Space O(1)
11824
12327
  * @param keyNodeOrEntry - Key, node, or [key, values] entry.
11825
- * @param [value] - Single value to add when a bare key is provided.
12328
+ * @param [value] - Single value to set when a bare key is provided.
11826
12329
  * @returns True if inserted or appended; false if ignored.
11827
12330
  */
11828
- add(keyNodeOrEntry, value) {
11829
- if (this.isRealNode(keyNodeOrEntry)) return super.add(keyNodeOrEntry);
12331
+ set(keyNodeOrEntry, value) {
12332
+ if (this.isRealNode(keyNodeOrEntry)) return super.set(keyNodeOrEntry);
11830
12333
  const _commonAdd = /* @__PURE__ */ __name((key, values) => {
11831
12334
  if (key === void 0 || key === null) return false;
11832
- const _addToValues = /* @__PURE__ */ __name(() => {
12335
+ const _setToValues = /* @__PURE__ */ __name(() => {
11833
12336
  const existingValues = this.get(key);
11834
12337
  if (existingValues !== void 0 && values !== void 0) {
11835
12338
  for (const value2 of values) existingValues.push(value2);
11836
12339
  return true;
11837
12340
  }
11838
12341
  return false;
11839
- }, "_addToValues");
11840
- const _addByNode = /* @__PURE__ */ __name(() => {
12342
+ }, "_setToValues");
12343
+ const _setByNode = /* @__PURE__ */ __name(() => {
11841
12344
  const existingNode = this.getNode(key);
11842
12345
  if (this.isRealNode(existingNode)) {
11843
12346
  const existingValues = this.get(existingNode);
11844
12347
  if (existingValues === void 0) {
11845
- super.add(key, values);
12348
+ super.set(key, values);
11846
12349
  return true;
11847
12350
  }
11848
12351
  if (values !== void 0) {
@@ -11852,13 +12355,13 @@ var TreeMultiMap = class extends RedBlackTree {
11852
12355
  return false;
11853
12356
  }
11854
12357
  } else {
11855
- return super.add(key, values);
12358
+ return super.set(key, values);
11856
12359
  }
11857
- }, "_addByNode");
12360
+ }, "_setByNode");
11858
12361
  if (this._isMapMode) {
11859
- return _addByNode() || _addToValues();
12362
+ return _setByNode() || _setToValues();
11860
12363
  }
11861
- return _addToValues() || _addByNode();
12364
+ return _setToValues() || _setByNode();
11862
12365
  }, "_commonAdd");
11863
12366
  if (this.isEntry(keyNodeOrEntry)) {
11864
12367
  const [key, values] = keyNodeOrEntry;
@@ -11898,7 +12401,7 @@ var TreeMultiMap = class extends RedBlackTree {
11898
12401
  map(callback, options, thisArg) {
11899
12402
  const out = this._createLike([], options);
11900
12403
  let i = 0;
11901
- for (const [k, v] of this) out.add(callback.call(thisArg, v, k, i++, this));
12404
+ for (const [k, v] of this) out.set(callback.call(thisArg, v, k, i++, this));
11902
12405
  return out;
11903
12406
  }
11904
12407
  /**
@@ -12083,7 +12586,7 @@ var TreeCounter = class extends RedBlackTree {
12083
12586
  */
12084
12587
  constructor(keysNodesEntriesOrRaws = [], options) {
12085
12588
  super([], options);
12086
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
12589
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
12087
12590
  }
12088
12591
  _count = 0;
12089
12592
  /**
@@ -12123,10 +12626,10 @@ var TreeCounter = class extends RedBlackTree {
12123
12626
  * @param [count] - How much to increase the node's count (default 1).
12124
12627
  * @returns True if inserted/updated; false if ignored.
12125
12628
  */
12126
- add(keyNodeOrEntry, value, count = 1) {
12629
+ set(keyNodeOrEntry, value, count = 1) {
12127
12630
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value, count);
12128
12631
  const orgCount = newNode?.count || 0;
12129
- const isSuccessAdded = super.add(newNode, newValue);
12632
+ const isSuccessAdded = super.set(newNode, newValue);
12130
12633
  if (isSuccessAdded) {
12131
12634
  this._count += orgCount;
12132
12635
  return true;
@@ -12137,16 +12640,16 @@ var TreeCounter = class extends RedBlackTree {
12137
12640
  /**
12138
12641
  * Delete a node (or decrement its count) and rebalance if needed.
12139
12642
  * @remarks Time O(log N), Space O(1)
12140
- * @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node.
12643
+ * @param keyNodeEntryRawOrPredicate - Key, node, or [key, value] entry identifying the node.
12141
12644
  * @param [ignoreCount] - If true, remove the node regardless of its count.
12142
12645
  * @returns Array of deletion results including deleted node and a rebalance hint when present.
12143
12646
  */
12144
- delete(keyNodeOrEntry, ignoreCount = false) {
12145
- if (keyNodeOrEntry === null) return [];
12647
+ delete(keyNodeEntryRawOrPredicate, ignoreCount = false) {
12648
+ if (keyNodeEntryRawOrPredicate === null) return [];
12146
12649
  const results = [];
12147
12650
  let nodeToDelete;
12148
- if (this._isPredicate(keyNodeOrEntry)) nodeToDelete = this.getNode(keyNodeOrEntry);
12149
- else nodeToDelete = this.isRealNode(keyNodeOrEntry) ? keyNodeOrEntry : this.getNode(keyNodeOrEntry);
12651
+ if (this._isPredicate(keyNodeEntryRawOrPredicate)) nodeToDelete = this.getNode(keyNodeEntryRawOrPredicate);
12652
+ else nodeToDelete = this.isRealNode(keyNodeEntryRawOrPredicate) ? keyNodeEntryRawOrPredicate : this.getNode(keyNodeEntryRawOrPredicate);
12150
12653
  if (!nodeToDelete) {
12151
12654
  return results;
12152
12655
  }
@@ -12189,7 +12692,6 @@ var TreeCounter = class extends RedBlackTree {
12189
12692
  if (ignoreCount || nodeToDelete.count <= 1) {
12190
12693
  if (successor.right !== null) {
12191
12694
  this._transplant(successor, successor.right);
12192
- this._count -= nodeToDelete.count;
12193
12695
  }
12194
12696
  } else {
12195
12697
  nodeToDelete.count--;
@@ -12279,7 +12781,7 @@ var TreeCounter = class extends RedBlackTree {
12279
12781
  const out = this._createLike([], options);
12280
12782
  let index = 0;
12281
12783
  for (const [key, value] of this) {
12282
- out.add(callback.call(thisArg, value, key, index++, this));
12784
+ out.set(callback.call(thisArg, value, key, index++, this));
12283
12785
  }
12284
12786
  return out;
12285
12787
  }
@@ -12292,6 +12794,11 @@ var TreeCounter = class extends RedBlackTree {
12292
12794
  const out = this._createInstance();
12293
12795
  this._clone(out);
12294
12796
  out._count = this._count;
12797
+ for (const node of this.dfs((n) => n, "IN")) {
12798
+ if (!node) continue;
12799
+ const outNode = out.getNode(node.key);
12800
+ if (outNode) outNode.count = node.count;
12801
+ }
12295
12802
  return out;
12296
12803
  }
12297
12804
  /**
@@ -12535,7 +13042,7 @@ var AVLTreeCounter = class extends AVLTree {
12535
13042
  */
12536
13043
  constructor(keysNodesEntriesOrRaws = [], options) {
12537
13044
  super([], options);
12538
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
13045
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
12539
13046
  }
12540
13047
  _count = 0;
12541
13048
  get count() {
@@ -12570,11 +13077,11 @@ var AVLTreeCounter = class extends AVLTree {
12570
13077
  * @param [count] - How much to increase the node's count (default 1).
12571
13078
  * @returns True if inserted/updated; false if ignored.
12572
13079
  */
12573
- add(keyNodeOrEntry, value, count = 1) {
13080
+ set(keyNodeOrEntry, value, count = 1) {
12574
13081
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value, count);
12575
13082
  if (newNode === void 0) return false;
12576
13083
  const orgNodeCount = newNode?.count || 0;
12577
- const inserted = super.add(newNode, newValue);
13084
+ const inserted = super.set(newNode, newValue);
12578
13085
  if (inserted) {
12579
13086
  this._count += orgNodeCount;
12580
13087
  }
@@ -12682,9 +13189,9 @@ var AVLTreeCounter = class extends AVLTree {
12682
13189
  clone() {
12683
13190
  const out = this._createInstance();
12684
13191
  if (this._isMapMode) {
12685
- this.bfs((node) => out.add(node.key, void 0, node.count));
13192
+ this.bfs((node) => out.set(node.key, void 0, node.count));
12686
13193
  } else {
12687
- this.bfs((node) => out.add(node.key, node.value, node.count));
13194
+ this.bfs((node) => out.set(node.key, node.value, node.count));
12688
13195
  }
12689
13196
  if (this._isMapMode) out._store = this._store;
12690
13197
  return out;
@@ -12704,7 +13211,7 @@ var AVLTreeCounter = class extends AVLTree {
12704
13211
  const out = this._createLike([], options);
12705
13212
  let index = 0;
12706
13213
  for (const [key, value] of this) {
12707
- out.add(callback.call(thisArg, value, key, index++, this));
13214
+ out.set(callback.call(thisArg, value, key, index++, this));
12708
13215
  }
12709
13216
  return out;
12710
13217
  }