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
@@ -1404,6 +1404,12 @@ var LinearLinkedBase = class extends LinearBase {
1404
1404
  }
1405
1405
  return -1;
1406
1406
  }
1407
+ /**
1408
+ * Concatenate lists/elements preserving order.
1409
+ * @param items - Elements or `LinearBase` instances.
1410
+ * @returns New list with combined elements (`this` type).
1411
+ * @remarks Time O(sum(length)), Space O(sum(length))
1412
+ */
1407
1413
  concat(...items) {
1408
1414
  const newList = this.clone();
1409
1415
  for (const item of items) {
@@ -4230,6 +4236,12 @@ var Deque = class extends LinearBase {
4230
4236
  */
4231
4237
  _setBucketSize(size) {
4232
4238
  this._bucketSize = size;
4239
+ if (this._length === 0) {
4240
+ this._buckets = [new Array(this._bucketSize)];
4241
+ this._bucketCount = 1;
4242
+ this._bucketFirst = this._bucketLast = 0;
4243
+ this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
4244
+ }
4233
4245
  }
4234
4246
  /**
4235
4247
  * (Protected) Iterate elements from front to back.
@@ -6995,9 +7007,9 @@ var BinaryTree = class extends IterableEntryBase {
6995
7007
  iterationType = "ITERATIVE";
6996
7008
  /**
6997
7009
  * Creates an instance of BinaryTree.
6998
- * @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.
7010
+ * @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.
6999
7011
  *
7000
- * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
7012
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
7001
7013
  * @param [options] - Configuration options for the tree.
7002
7014
  */
7003
7015
  constructor(keysNodesEntriesOrRaws = [], options) {
@@ -7010,7 +7022,7 @@ var BinaryTree = class extends IterableEntryBase {
7010
7022
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
7011
7023
  else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
7012
7024
  }
7013
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
7025
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
7014
7026
  }
7015
7027
  _isMapMode = true;
7016
7028
  /**
@@ -7224,10 +7236,20 @@ var BinaryTree = class extends IterableEntryBase {
7224
7236
  * @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).
7225
7237
  *
7226
7238
  * @param keyNodeOrEntry - The key, node, or entry to add.
7239
+ * @returns True if the addition was successful, false otherwise.
7240
+ */
7241
+ add(keyNodeOrEntry) {
7242
+ return this.set(keyNodeOrEntry);
7243
+ }
7244
+ /**
7245
+ * Adds or updates a new node to the tree.
7246
+ * @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).
7247
+ *
7248
+ * @param keyNodeOrEntry - The key, node, or entry to set or update.
7227
7249
  * @param [value] - The value, if providing just a key.
7228
7250
  * @returns True if the addition was successful, false otherwise.
7229
7251
  */
7230
- add(keyNodeOrEntry, value) {
7252
+ set(keyNodeOrEntry, value) {
7231
7253
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
7232
7254
  if (newNode === void 0) return false;
7233
7255
  if (!this._root) {
@@ -7271,25 +7293,24 @@ var BinaryTree = class extends IterableEntryBase {
7271
7293
  return false;
7272
7294
  }
7273
7295
  /**
7274
- * Adds or updates a new node to the tree.
7275
- * @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).
7296
+ * Adds multiple items to the tree.
7297
+ * @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).
7276
7298
  *
7277
- * @param keyNodeOrEntry - The key, node, or entry to add or update.
7278
- * @param [value] - The value, if providing just a key.
7279
- * @returns True if the addition was successful, false otherwise.
7299
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
7300
+ * @returns An array of booleans indicating the success of each individual `set` operation.
7280
7301
  */
7281
- set(keyNodeOrEntry, value) {
7282
- return this.add(keyNodeOrEntry, value);
7302
+ addMany(keysNodesEntriesOrRaws) {
7303
+ return this.setMany(keysNodesEntriesOrRaws);
7283
7304
  }
7284
7305
  /**
7285
- * Adds multiple items to the tree.
7286
- * @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).
7306
+ * Adds or updates multiple items to the tree.
7307
+ * @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).
7287
7308
  *
7288
- * @param keysNodesEntriesOrRaws - An iterable of items to add.
7309
+ * @param keysNodesEntriesOrRaws - An iterable of items to set or update.
7289
7310
  * @param [values] - An optional parallel iterable of values.
7290
- * @returns An array of booleans indicating the success of each individual `add` operation.
7311
+ * @returns An array of booleans indicating the success of each individual `set` operation.
7291
7312
  */
7292
- addMany(keysNodesEntriesOrRaws, values) {
7313
+ setMany(keysNodesEntriesOrRaws, values) {
7293
7314
  const inserted = [];
7294
7315
  let valuesIterator;
7295
7316
  if (values) {
@@ -7304,52 +7325,41 @@ var BinaryTree = class extends IterableEntryBase {
7304
7325
  }
7305
7326
  }
7306
7327
  if (this.isRaw(keyNodeEntryOrRaw)) keyNodeEntryOrRaw = this._toEntryFn(keyNodeEntryOrRaw);
7307
- inserted.push(this.add(keyNodeEntryOrRaw, value));
7328
+ inserted.push(this.set(keyNodeEntryOrRaw, value));
7308
7329
  }
7309
7330
  return inserted;
7310
7331
  }
7311
7332
  /**
7312
- * Adds or updates multiple items to the tree.
7313
- * @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).
7314
- *
7315
- * @param keysNodesEntriesOrRaws - An iterable of items to add or update.
7316
- * @param [values] - An optional parallel iterable of values.
7317
- * @returns An array of booleans indicating the success of each individual `add` operation.
7318
- */
7319
- setMany(keysNodesEntriesOrRaws, values) {
7320
- return this.addMany(keysNodesEntriesOrRaws, values);
7321
- }
7322
- /**
7323
- * Merges another tree into this one by adding all its nodes.
7324
- * @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`).
7333
+ * Merges another tree into this one by seting all its nodes.
7334
+ * @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`).
7325
7335
  *
7326
7336
  * @param anotherTree - The tree to merge.
7327
7337
  */
7328
7338
  merge(anotherTree) {
7329
- this.addMany(anotherTree, []);
7339
+ this.setMany(anotherTree, []);
7330
7340
  }
7331
7341
  /**
7332
7342
  * Clears the tree and refills it with new items.
7333
- * @remarks Time O(N) (for `clear`) + O(N * M) (for `addMany`) = O(N * M). Space O(M) (from `addMany`).
7343
+ * @remarks Time O(N) (for `clear`) + O(N * M) (for `setMany`) = O(N * M). Space O(M) (from `setMany`).
7334
7344
  *
7335
- * @param keysNodesEntriesOrRaws - An iterable of items to add.
7345
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
7336
7346
  * @param [values] - An optional parallel iterable of values.
7337
7347
  */
7338
7348
  refill(keysNodesEntriesOrRaws, values) {
7339
7349
  this.clear();
7340
- this.addMany(keysNodesEntriesOrRaws, values);
7350
+ this.setMany(keysNodesEntriesOrRaws, values);
7341
7351
  }
7342
7352
  /**
7343
7353
  * Deletes a node from the tree.
7344
7354
  * @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).
7345
7355
  *
7346
- * @param keyNodeOrEntry - The node to delete.
7356
+ * @param keyNodeEntryRawOrPredicate - The node to delete.
7347
7357
  * @returns An array containing deletion results (for compatibility with self-balancing trees).
7348
7358
  */
7349
- delete(keyNodeOrEntry) {
7359
+ delete(keyNodeEntryRawOrPredicate) {
7350
7360
  const deletedResult = [];
7351
7361
  if (!this._root) return deletedResult;
7352
- const curr = this.getNode(keyNodeOrEntry);
7362
+ const curr = this.getNode(keyNodeEntryRawOrPredicate);
7353
7363
  if (!curr) return deletedResult;
7354
7364
  const parent = curr?.parent;
7355
7365
  let needBalanced;
@@ -7532,7 +7542,7 @@ var BinaryTree = class extends IterableEntryBase {
7532
7542
  }
7533
7543
  return true;
7534
7544
  }, "checkBST");
7535
- const isStandardBST = checkBST(false);
7545
+ const isStandardBST = checkBST();
7536
7546
  const isInverseBST = checkBST(true);
7537
7547
  return isStandardBST || isInverseBST;
7538
7548
  }
@@ -8002,7 +8012,7 @@ var BinaryTree = class extends IterableEntryBase {
8002
8012
  }
8003
8013
  /**
8004
8014
  * Clones the tree.
8005
- * @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.
8015
+ * @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.
8006
8016
  *
8007
8017
  * @returns A new, cloned instance of the tree.
8008
8018
  */
@@ -8013,7 +8023,7 @@ var BinaryTree = class extends IterableEntryBase {
8013
8023
  }
8014
8024
  /**
8015
8025
  * Creates a new tree containing only the entries that satisfy the predicate.
8016
- * @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.
8026
+ * @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.
8017
8027
  *
8018
8028
  * @param predicate - A function to test each [key, value] pair.
8019
8029
  * @param [thisArg] - `this` context for the predicate.
@@ -8022,7 +8032,7 @@ var BinaryTree = class extends IterableEntryBase {
8022
8032
  filter(predicate, thisArg) {
8023
8033
  const out = this._createInstance();
8024
8034
  let i = 0;
8025
- for (const [k, v] of this) if (predicate.call(thisArg, v, k, i++, this)) out.add([k, v]);
8035
+ for (const [k, v] of this) if (predicate.call(thisArg, v, k, i++, this)) out.set([k, v]);
8026
8036
  return out;
8027
8037
  }
8028
8038
  /**
@@ -8040,7 +8050,7 @@ var BinaryTree = class extends IterableEntryBase {
8040
8050
  map(cb, options, thisArg) {
8041
8051
  const out = this._createLike([], options);
8042
8052
  let i = 0;
8043
- for (const [k, v] of this) out.add(cb.call(thisArg, v, k, i++, this));
8053
+ for (const [k, v] of this) out.set(cb.call(thisArg, v, k, i++, this));
8044
8054
  return out;
8045
8055
  }
8046
8056
  /**
@@ -8292,18 +8302,18 @@ var BinaryTree = class extends IterableEntryBase {
8292
8302
  return [this.createNode(keyNodeOrEntry, value), value];
8293
8303
  }
8294
8304
  /**
8295
- * (Protected) Helper for cloning. Performs a BFS and adds all nodes to the new tree.
8296
- * @remarks Time O(N * M) (O(N) BFS + O(M) `add` for each node).
8305
+ * (Protected) Helper for cloning. Performs a BFS and sets all nodes to the new tree.
8306
+ * @remarks Time O(N * M) (O(N) BFS + O(M) `set` for each node).
8297
8307
  *
8298
8308
  * @param cloned - The new, empty tree instance to populate.
8299
8309
  */
8300
8310
  _clone(cloned) {
8301
8311
  this.bfs(
8302
8312
  (node) => {
8303
- if (node === null) cloned.add(null);
8313
+ if (node === null) cloned.set(null);
8304
8314
  else {
8305
- if (this._isMapMode) cloned.add([node.key, this._store.get(node.key)]);
8306
- else cloned.add([node.key, node.value]);
8315
+ if (this._isMapMode) cloned.set([node.key, this._store.get(node.key)]);
8316
+ else cloned.set([node.key, node.value]);
8307
8317
  }
8308
8318
  },
8309
8319
  this._root,
@@ -8636,7 +8646,7 @@ var BST = class extends BinaryTree {
8636
8646
  * Creates an instance of BST.
8637
8647
  * @remarks Time O(N log N) or O(N^2) depending on `isBalanceAdd` in `addMany` and input order. Space O(N).
8638
8648
  *
8639
- * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
8649
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
8640
8650
  * @param [options] - Configuration options for the BST, including comparator.
8641
8651
  */
8642
8652
  constructor(keysNodesEntriesOrRaws = [], options) {
@@ -8650,7 +8660,7 @@ var BST = class extends BinaryTree {
8650
8660
  } else {
8651
8661
  this._comparator = this._createDefaultComparator();
8652
8662
  }
8653
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
8663
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
8654
8664
  }
8655
8665
  _root = void 0;
8656
8666
  /**
@@ -8770,7 +8780,39 @@ var BST = class extends BinaryTree {
8770
8780
  * @returns The first matching node, or undefined if not found.
8771
8781
  */
8772
8782
  getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
8773
- return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? void 0;
8783
+ if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === void 0) return void 0;
8784
+ if (this._isPredicate(keyNodeEntryOrPredicate)) {
8785
+ return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? void 0;
8786
+ }
8787
+ if (keyNodeEntryOrPredicate instanceof Range) {
8788
+ return this.getNodes(
8789
+ keyNodeEntryOrPredicate,
8790
+ true,
8791
+ startNode,
8792
+ iterationType
8793
+ )[0] ?? void 0;
8794
+ }
8795
+ let targetKey;
8796
+ if (this.isNode(keyNodeEntryOrPredicate)) {
8797
+ targetKey = keyNodeEntryOrPredicate.key;
8798
+ } else if (this.isEntry(keyNodeEntryOrPredicate)) {
8799
+ const k = keyNodeEntryOrPredicate[0];
8800
+ if (k === null || k === void 0) return void 0;
8801
+ targetKey = k;
8802
+ } else {
8803
+ targetKey = keyNodeEntryOrPredicate;
8804
+ }
8805
+ const start = this.ensureNode(startNode);
8806
+ if (!start) return void 0;
8807
+ const NIL = this._NIL;
8808
+ let cur = start;
8809
+ const cmpFn = this._comparator;
8810
+ while (cur && cur !== NIL) {
8811
+ const c = cmpFn(targetKey, cur.key);
8812
+ if (c === 0) return cur;
8813
+ cur = c < 0 ? cur._left : cur._right;
8814
+ }
8815
+ return void 0;
8774
8816
  }
8775
8817
  /**
8776
8818
  * Searches the tree for nodes matching a predicate, key, or range.
@@ -8791,8 +8833,30 @@ var BST = class extends BinaryTree {
8791
8833
  if (keyNodeEntryOrPredicate === null) return [];
8792
8834
  startNode = this.ensureNode(startNode);
8793
8835
  if (!startNode) return [];
8794
- let predicate;
8795
8836
  const isRange = this.isRange(keyNodeEntryOrPredicate);
8837
+ const isPred = !isRange && this._isPredicate(keyNodeEntryOrPredicate);
8838
+ if (!isRange && !isPred) {
8839
+ let targetKey;
8840
+ if (this.isNode(keyNodeEntryOrPredicate)) {
8841
+ targetKey = keyNodeEntryOrPredicate.key;
8842
+ } else if (this.isEntry(keyNodeEntryOrPredicate)) {
8843
+ const k = keyNodeEntryOrPredicate[0];
8844
+ if (k !== null && k !== void 0) targetKey = k;
8845
+ } else {
8846
+ targetKey = keyNodeEntryOrPredicate;
8847
+ }
8848
+ if (targetKey === void 0) return [];
8849
+ const NIL = this._NIL;
8850
+ const cmpFn = this._comparator;
8851
+ let cur = startNode;
8852
+ while (cur && cur !== NIL) {
8853
+ const c = cmpFn(targetKey, cur.key);
8854
+ if (c === 0) return [callback(cur)];
8855
+ cur = c < 0 ? cur._left : cur._right;
8856
+ }
8857
+ return [];
8858
+ }
8859
+ let predicate;
8796
8860
  if (isRange) {
8797
8861
  predicate = /* @__PURE__ */ __name((node) => {
8798
8862
  if (!node) return false;
@@ -8866,11 +8930,11 @@ var BST = class extends BinaryTree {
8866
8930
  * Adds a new node to the BST based on key comparison.
8867
8931
  * @remarks Time O(log N), where H is tree height. O(N) worst-case (unbalanced tree), O(log N) average. Space O(1).
8868
8932
  *
8869
- * @param keyNodeOrEntry - The key, node, or entry to add.
8933
+ * @param keyNodeOrEntry - The key, node, or entry to set.
8870
8934
  * @param [value] - The value, if providing just a key.
8871
8935
  * @returns True if the addition was successful, false otherwise.
8872
8936
  */
8873
- add(keyNodeOrEntry, value) {
8937
+ set(keyNodeOrEntry, value) {
8874
8938
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
8875
8939
  if (newNode === void 0) return false;
8876
8940
  if (this._root === void 0) {
@@ -8907,24 +8971,24 @@ var BST = class extends BinaryTree {
8907
8971
  }
8908
8972
  /**
8909
8973
  * Adds multiple items to the tree.
8910
- * @remarks If `isBalanceAdd` is true, sorts the input and builds a balanced tree. Time O(N log N) (due to sort and balanced add).
8974
+ * @remarks If `isBalanceAdd` is true, sorts the input and builds a balanced tree. Time O(N log N) (due to sort and balanced set).
8911
8975
  * If false, adds items one by one. Time O(N * H), which is O(N^2) worst-case.
8912
8976
  * Space O(N) for sorting and recursion/iteration stack.
8913
8977
  *
8914
- * @param keysNodesEntriesOrRaws - An iterable of items to add.
8978
+ * @param keysNodesEntriesOrRaws - An iterable of items to set.
8915
8979
  * @param [values] - An optional parallel iterable of values.
8916
8980
  * @param [isBalanceAdd=true] - If true, builds a balanced tree from the items.
8917
- * @param [iterationType=this.iterationType] - The traversal method for balanced add (recursive or iterative).
8918
- * @returns An array of booleans indicating the success of each individual `add` operation.
8981
+ * @param [iterationType=this.iterationType] - The traversal method for balanced set (recursive or iterative).
8982
+ * @returns An array of booleans indicating the success of each individual `set` operation.
8919
8983
  */
8920
- addMany(keysNodesEntriesOrRaws, values, isBalanceAdd = true, iterationType = this.iterationType) {
8984
+ setMany(keysNodesEntriesOrRaws, values, isBalanceAdd = true, iterationType = this.iterationType) {
8921
8985
  const inserted = [];
8922
8986
  const valuesIterator = values?.[Symbol.iterator]();
8923
8987
  if (!isBalanceAdd) {
8924
8988
  for (let kve of keysNodesEntriesOrRaws) {
8925
8989
  const val = valuesIterator?.next().value;
8926
8990
  if (this.isRaw(kve)) kve = this._toEntryFn(kve);
8927
- inserted.push(this.add(kve, val));
8991
+ inserted.push(this.set(kve, val));
8928
8992
  }
8929
8993
  return inserted;
8930
8994
  }
@@ -8952,9 +9016,9 @@ var BST = class extends BinaryTree {
8952
9016
  const { key, value, orgIndex } = arr[mid];
8953
9017
  if (this.isRaw(key)) {
8954
9018
  const entry = this._toEntryFn(key);
8955
- inserted[orgIndex] = this.add(entry);
9019
+ inserted[orgIndex] = this.set(entry);
8956
9020
  } else {
8957
- inserted[orgIndex] = this.add(key, value);
9021
+ inserted[orgIndex] = this.set(key, value);
8958
9022
  }
8959
9023
  _dfs(arr.slice(0, mid));
8960
9024
  _dfs(arr.slice(mid + 1));
@@ -8971,9 +9035,9 @@ var BST = class extends BinaryTree {
8971
9035
  const { key, value, orgIndex } = sorted[m];
8972
9036
  if (this.isRaw(key)) {
8973
9037
  const entry = this._toEntryFn(key);
8974
- inserted[orgIndex] = this.add(entry);
9038
+ inserted[orgIndex] = this.set(entry);
8975
9039
  } else {
8976
- inserted[orgIndex] = this.add(key, value);
9040
+ inserted[orgIndex] = this.set(key, value);
8977
9041
  }
8978
9042
  stack.push([m + 1, r]);
8979
9043
  stack.push([l, m - 1]);
@@ -9248,7 +9312,7 @@ var BST = class extends BinaryTree {
9248
9312
  const out = this._createLike([], options);
9249
9313
  let index = 0;
9250
9314
  for (const [key, value] of this) {
9251
- out.add(callback.call(thisArg, value, key, index++, this));
9315
+ out.set(callback.call(thisArg, value, key, index++, this));
9252
9316
  }
9253
9317
  return out;
9254
9318
  }
@@ -9714,7 +9778,7 @@ var BST = class extends BinaryTree {
9714
9778
  succ.left = node.left;
9715
9779
  if (succ.left) succ.left.parent = succ;
9716
9780
  }
9717
- this._size = Math.max(0, (this._size ?? 0) - 1);
9781
+ this._size = Math.max(0, this._size - 1);
9718
9782
  return true;
9719
9783
  }
9720
9784
  };
@@ -10435,14 +10499,14 @@ var AVLTree = class extends BST {
10435
10499
  }
10436
10500
  /**
10437
10501
  * Creates an instance of AVLTree.
10438
- * @remarks Time O(N log N) (from `addMany` with balanced add). Space O(N).
10502
+ * @remarks Time O(N log N) (from `setMany` with balanced set). Space O(N).
10439
10503
  *
10440
- * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
10504
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to set.
10441
10505
  * @param [options] - Configuration options for the AVL tree.
10442
10506
  */
10443
10507
  constructor(keysNodesEntriesOrRaws = [], options) {
10444
10508
  super([], options);
10445
- if (keysNodesEntriesOrRaws) super.addMany(keysNodesEntriesOrRaws);
10509
+ if (keysNodesEntriesOrRaws) super.setMany(keysNodesEntriesOrRaws);
10446
10510
  }
10447
10511
  /**
10448
10512
  * (Protected) Creates a new AVL tree node.
@@ -10466,16 +10530,16 @@ var AVLTree = class extends BST {
10466
10530
  return keyNodeOrEntry instanceof AVLTreeNode;
10467
10531
  }
10468
10532
  /**
10469
- * Adds a new node to the AVL tree and balances the tree path.
10470
- * @remarks Time O(log N) (O(H) for BST add + O(H) for `_balancePath`). Space O(H) for path/recursion.
10533
+ * Sets a new node to the AVL tree and balances the tree path.
10534
+ * @remarks Time O(log N) (O(H) for BST set + O(H) for `_balancePath`). Space O(H) for path/recursion.
10471
10535
  *
10472
- * @param keyNodeOrEntry - The key, node, or entry to add.
10536
+ * @param keyNodeOrEntry - The key, node, or entry to set.
10473
10537
  * @param [value] - The value, if providing just a key.
10474
10538
  * @returns True if the addition was successful, false otherwise.
10475
10539
  */
10476
- add(keyNodeOrEntry, value) {
10540
+ set(keyNodeOrEntry, value) {
10477
10541
  if (keyNodeOrEntry === null) return false;
10478
- const inserted = super.add(keyNodeOrEntry, value);
10542
+ const inserted = super.set(keyNodeOrEntry, value);
10479
10543
  if (inserted) this._balancePath(keyNodeOrEntry);
10480
10544
  return inserted;
10481
10545
  }
@@ -10527,7 +10591,7 @@ var AVLTree = class extends BST {
10527
10591
  }
10528
10592
  /**
10529
10593
  * Creates a new AVLTree by mapping each [key, value] pair.
10530
- * @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.
10594
+ * @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.
10531
10595
  *
10532
10596
  * @template MK - New key type.
10533
10597
  * @template MV - New value type.
@@ -10541,7 +10605,7 @@ var AVLTree = class extends BST {
10541
10605
  const out = this._createLike([], options);
10542
10606
  let index = 0;
10543
10607
  for (const [key, value] of this) {
10544
- out.add(callback.call(thisArg, value, key, index++, this));
10608
+ out.set(callback.call(thisArg, value, key, index++, this));
10545
10609
  }
10546
10610
  return out;
10547
10611
  }
@@ -10830,12 +10894,11 @@ var RedBlackTreeNode = class {
10830
10894
  value;
10831
10895
  parent = void 0;
10832
10896
  /**
10833
- * Create a Red-Black Tree and optionally bulk-insert items.
10834
- * @remarks Time O(n log n), Space O(n)
10835
- * @param key - See parameter type for details.
10836
- * @param [value]- See parameter type for details.
10837
- * @param color - See parameter type for details.
10838
- * @returns New RedBlackTree instance.
10897
+ * Create a Red-Black Tree node.
10898
+ * @remarks Time O(1), Space O(1)
10899
+ * @param key - Node key.
10900
+ * @param [value] - Node value (unused in map mode trees).
10901
+ * @param color - Node color.
10839
10902
  */
10840
10903
  constructor(key, value, color = "BLACK") {
10841
10904
  this.key = key;
@@ -10966,11 +11029,33 @@ var RedBlackTree = class extends BST {
10966
11029
  constructor(keysNodesEntriesOrRaws = [], options) {
10967
11030
  super([], options);
10968
11031
  this._root = this.NIL;
11032
+ this._header = new RedBlackTreeNode(void 0, void 0, "BLACK");
11033
+ this._header.parent = this.NIL;
11034
+ this._header._left = this.NIL;
11035
+ this._header._right = this.NIL;
10969
11036
  if (keysNodesEntriesOrRaws) {
10970
- this.addMany(keysNodesEntriesOrRaws);
11037
+ this.setMany(keysNodesEntriesOrRaws);
10971
11038
  }
10972
11039
  }
10973
11040
  _root;
11041
+ /**
11042
+ * (Internal) Header sentinel:
11043
+ * - header.parent -> root
11044
+ * - header._left -> min (or NIL)
11045
+ * - header._right -> max (or NIL)
11046
+ *
11047
+ * IMPORTANT:
11048
+ * - This header is NOT part of the actual tree.
11049
+ * - Do NOT use `header.left` / `header.right` accessors for wiring: those setters update `NIL.parent`
11050
+ * and can corrupt sentinel invariants / cause hangs. Only touch `header._left/_right`.
11051
+ */
11052
+ _header;
11053
+ /**
11054
+ * (Internal) Cache of the current minimum and maximum nodes.
11055
+ * Used for fast-path insert/update when keys are monotonic or near-boundary.
11056
+ */
11057
+ _minNode;
11058
+ _maxNode;
10974
11059
  /**
10975
11060
  * Get the current root node.
10976
11061
  * @remarks Time O(1), Space O(1)
@@ -11004,18 +11089,387 @@ var RedBlackTree = class extends BST {
11004
11089
  * @remarks Time O(n), Space O(1)
11005
11090
  * @returns void
11006
11091
  */
11092
+ /**
11093
+ * Remove all nodes and clear internal caches.
11094
+ * @remarks Time O(n) average, Space O(1)
11095
+ */
11007
11096
  clear() {
11008
11097
  super.clear();
11009
11098
  this._root = this.NIL;
11099
+ this._header.parent = this.NIL;
11100
+ this._setMinCache(void 0);
11101
+ this._setMaxCache(void 0);
11010
11102
  }
11011
11103
  /**
11012
- * Insert or replace an entry using BST order and red-black fix-up.
11013
- * @remarks Time O(log n), Space O(1)
11014
- * @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
11015
- * @param [value]- See parameter type for details.
11016
- * @returns True if inserted or updated; false if ignored.
11104
+ * (Internal) Find a node by key using a tight BST walk (no allocations).
11105
+ *
11106
+ * NOTE: This uses `header.parent` as the canonical root pointer.
11107
+ * @remarks Time O(log n) average, Space O(1)
11108
+ */
11109
+ _findNodeByKey(key) {
11110
+ const NIL = this.NIL;
11111
+ const cmp = this._compare.bind(this);
11112
+ let cur = this._header.parent ?? NIL;
11113
+ while (cur !== NIL) {
11114
+ const c = cmp(key, cur.key);
11115
+ if (c < 0) cur = cur.left ?? NIL;
11116
+ else if (c > 0) cur = cur.right ?? NIL;
11117
+ else return cur;
11118
+ }
11119
+ return void 0;
11120
+ }
11121
+ /**
11122
+ * (Internal) In-order predecessor of a node in a BST.
11123
+ * @remarks Time O(log n) average, Space O(1)
11124
+ */
11125
+ _predecessorOf(node) {
11126
+ const NIL = this.NIL;
11127
+ if (node.left && node.left !== NIL) {
11128
+ let cur2 = node.left;
11129
+ while (cur2.right && cur2.right !== NIL) cur2 = cur2.right;
11130
+ return cur2;
11131
+ }
11132
+ let cur = node;
11133
+ let p = node.parent;
11134
+ while (p && cur === p.left) {
11135
+ cur = p;
11136
+ p = p.parent;
11137
+ }
11138
+ return p;
11139
+ }
11140
+ /**
11141
+ * (Internal) In-order successor of a node in a BST.
11142
+ * @remarks Time O(log n) average, Space O(1)
11143
+ */
11144
+ _successorOf(node) {
11145
+ const NIL = this.NIL;
11146
+ if (node.right && node.right !== NIL) {
11147
+ let cur2 = node.right;
11148
+ while (cur2.left && cur2.left !== NIL) cur2 = cur2.left;
11149
+ return cur2;
11150
+ }
11151
+ let cur = node;
11152
+ let p = node.parent;
11153
+ while (p && cur === p.right) {
11154
+ cur = p;
11155
+ p = p.parent;
11156
+ }
11157
+ return p;
11158
+ }
11159
+ /**
11160
+ * (Internal) Attach a new node directly under a known parent/side (no search).
11161
+ *
11162
+ * This is a performance-oriented helper used by boundary fast paths and hinted insertion.
11163
+ * It will:
11164
+ * - wire parent/child pointers (using accessors, so parent pointers are updated)
11165
+ * - initialize children to NIL
11166
+ * - mark the new node RED, then run insert fix-up
11167
+ *
11168
+ * Precondition: the chosen slot (parent.left/parent.right) is empty (NIL/null/undefined).
11169
+ * @remarks Time O(log n) average, Space O(1)
11170
+ */
11171
+ _attachNewNode(parent, side, node) {
11172
+ const NIL = this.NIL;
11173
+ node.parent = parent;
11174
+ if (side === "left") parent.left = node;
11175
+ else parent.right = node;
11176
+ node.left = NIL;
11177
+ node.right = NIL;
11178
+ node.color = "RED";
11179
+ this._insertFixup(node);
11180
+ if (this.isRealNode(this._root)) this._root.color = "BLACK";
11181
+ }
11182
+ /**
11183
+ * (Internal) a single source of truth for min/max is header._left/_right.
11184
+ * Keep legacy _minNode/_maxNode mirrored for compatibility.
11185
+ * @remarks Time O(1), Space O(1)
11186
+ */
11187
+ /**
11188
+ * (Internal) Update min cache pointers (header._left is the canonical min pointer).
11189
+ * @remarks Time O(1), Space O(1)
11190
+ */
11191
+ _setMinCache(node) {
11192
+ this._minNode = node;
11193
+ this._header._left = node ?? this.NIL;
11194
+ }
11195
+ /**
11196
+ * (Internal) Update max cache pointers (header._right is the canonical max pointer).
11197
+ * @remarks Time O(1), Space O(1)
11198
+ */
11199
+ _setMaxCache(node) {
11200
+ this._maxNode = node;
11201
+ this._header._right = node ?? this.NIL;
11202
+ }
11203
+ /**
11204
+ * (Internal) Core set implementation returning the affected node.
11205
+ *
11206
+ * Hot path goals:
11207
+ * - Avoid double walks (search+insert): do a single traversal that either updates or inserts.
11208
+ * - Use header min/max caches to fast-path boundary inserts.
11209
+ * - Keep header._left/_right as canonical min/max pointers.
11210
+ *
11211
+ * Return value:
11212
+ * - `{ node, created:false }` when an existing key is updated
11213
+ * - `{ node, created:true }` when a new node is inserted
11214
+ * - `undefined` only on unexpected internal failure.
11215
+ * @remarks Time O(log n) average, Space O(1)
11216
+ */
11217
+ _setKVNode(key, nextValue) {
11218
+ const NIL = this.NIL;
11219
+ const comparator = this._comparator;
11220
+ const header = this._header;
11221
+ const minN = header._left ?? NIL;
11222
+ if (minN !== NIL) {
11223
+ const cMin = comparator(key, minN.key);
11224
+ if (cMin === 0) {
11225
+ if (this._isMapMode) {
11226
+ if (nextValue !== void 0) this._store.set(key, nextValue);
11227
+ else this._setValue(key, nextValue);
11228
+ } else minN.value = nextValue;
11229
+ return { node: minN, created: false };
11230
+ }
11231
+ const minL = minN.left;
11232
+ if (cMin < 0 && (minL === NIL || minL === null || minL === void 0)) {
11233
+ const newNode2 = this.createNode(key, nextValue);
11234
+ this._attachNewNode(minN, "left", newNode2);
11235
+ if (this._isMapMode) {
11236
+ if (nextValue !== void 0) this._store.set(newNode2.key, nextValue);
11237
+ else this._setValue(newNode2.key, nextValue);
11238
+ }
11239
+ this._size++;
11240
+ this._setMinCache(newNode2);
11241
+ if (header._right === NIL) this._setMaxCache(newNode2);
11242
+ return { node: newNode2, created: true };
11243
+ }
11244
+ if (cMin > 0) {
11245
+ const maxN = header._right ?? NIL;
11246
+ const cMax = comparator(key, maxN.key);
11247
+ if (cMax === 0) {
11248
+ if (this._isMapMode) {
11249
+ if (nextValue !== void 0) this._store.set(key, nextValue);
11250
+ else this._setValue(key, nextValue);
11251
+ } else maxN.value = nextValue;
11252
+ return { node: maxN, created: false };
11253
+ }
11254
+ const maxR = maxN.right;
11255
+ if (cMax > 0 && (maxR === NIL || maxR === null || maxR === void 0)) {
11256
+ const newNode2 = this.createNode(key, nextValue);
11257
+ this._attachNewNode(maxN, "right", newNode2);
11258
+ if (this._isMapMode) {
11259
+ if (nextValue !== void 0) this._store.set(newNode2.key, nextValue);
11260
+ else this._setValue(newNode2.key, nextValue);
11261
+ }
11262
+ this._size++;
11263
+ this._setMaxCache(newNode2);
11264
+ if (header._left === NIL) this._setMinCache(newNode2);
11265
+ return { node: newNode2, created: true };
11266
+ }
11267
+ }
11268
+ }
11269
+ const cmp = comparator;
11270
+ const isMapMode = this._isMapMode;
11271
+ const store = this._store;
11272
+ let current = this._header.parent ?? NIL;
11273
+ let parent;
11274
+ let lastCompared = 0;
11275
+ while (current !== NIL) {
11276
+ parent = current;
11277
+ lastCompared = cmp(key, current.key);
11278
+ if (lastCompared < 0) current = current.left ?? NIL;
11279
+ else if (lastCompared > 0) current = current.right ?? NIL;
11280
+ else {
11281
+ if (isMapMode) {
11282
+ if (nextValue !== void 0) store.set(key, nextValue);
11283
+ else this._setValue(key, nextValue);
11284
+ } else {
11285
+ current.value = nextValue;
11286
+ }
11287
+ return { node: current, created: false };
11288
+ }
11289
+ }
11290
+ const newNode = this.createNode(key, nextValue);
11291
+ newNode.parent = parent;
11292
+ if (!parent) {
11293
+ this._setRoot(newNode);
11294
+ } else if (lastCompared < 0) {
11295
+ parent.left = newNode;
11296
+ } else {
11297
+ parent.right = newNode;
11298
+ }
11299
+ newNode.left = NIL;
11300
+ newNode.right = NIL;
11301
+ newNode.color = "RED";
11302
+ this._insertFixup(newNode);
11303
+ if (this.isRealNode(this._root)) this._root.color = "BLACK";
11304
+ else return void 0;
11305
+ if (isMapMode) {
11306
+ if (nextValue !== void 0) store.set(newNode.key, nextValue);
11307
+ else this._setValue(newNode.key, nextValue);
11308
+ }
11309
+ this._size++;
11310
+ const hMin = this._header._left ?? NIL;
11311
+ const hMax = this._header._right ?? NIL;
11312
+ if (hMin === NIL || hMax === NIL) {
11313
+ this._setMinCache(newNode);
11314
+ this._setMaxCache(newNode);
11315
+ } else if (parent === hMax && lastCompared > 0) {
11316
+ this._setMaxCache(newNode);
11317
+ } else if (parent === hMin && lastCompared < 0) {
11318
+ this._setMinCache(newNode);
11319
+ } else {
11320
+ if (cmp(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11321
+ if (cmp(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11322
+ }
11323
+ return { node: newNode, created: true };
11324
+ }
11325
+ /**
11326
+ * (Internal) Boolean wrapper around `_setKVNode`.
11327
+ *
11328
+ * Includes a map-mode update fast-path:
11329
+ * - If `isMapMode=true` and the key already exists in `_store`, then updating the value does not
11330
+ * require any tree search/rotation (tree shape depends only on key).
11331
+ * - This path is intentionally limited to `nextValue !== undefined` to preserve existing
11332
+ * semantics for `undefined` values.
11333
+ * @remarks Time O(log n) average, Space O(1)
11334
+ */
11335
+ _setKV(key, nextValue) {
11336
+ if (this._isMapMode && nextValue !== void 0) {
11337
+ const store = this._store;
11338
+ if (store.has(key)) {
11339
+ store.set(key, nextValue);
11340
+ return true;
11341
+ }
11342
+ }
11343
+ return this._setKVNode(key, nextValue) !== void 0;
11344
+ }
11345
+ /**
11346
+ * Insert/update using a hint node to speed up nearby insertions.
11347
+ *
11348
+ * close to the expected insertion position (often the previously returned node in a loop).
11349
+ *
11350
+ * When the hint is a good fit (sorted / nearly-sorted insertion), this can avoid most of the
11351
+ * normal root-to-leaf search and reduce constant factors.
11352
+ *
11353
+ * When the hint does not match (random workloads), this will fall back to the normal set path.
11354
+ * @remarks Time O(log n) average, Space O(1)
11017
11355
  */
11018
- add(keyNodeOrEntry, value) {
11356
+ setWithHintNode(key, value, hint) {
11357
+ if (!hint || !this.isRealNode(hint)) {
11358
+ return this._setKVNode(key, value)?.node;
11359
+ }
11360
+ const cmp = this._compare.bind(this);
11361
+ const c0 = cmp(key, hint.key);
11362
+ if (c0 === 0) {
11363
+ if (this._isMapMode) {
11364
+ if (value !== void 0) this._store.set(key, value);
11365
+ else this._setValue(key, value);
11366
+ } else hint.value = value;
11367
+ return hint;
11368
+ }
11369
+ if (c0 < 0) {
11370
+ if (!this.isRealNode(hint.left)) {
11371
+ const newNode = this.createNode(key, value);
11372
+ if (!this.isRealNode(newNode)) return void 0;
11373
+ this._attachNewNode(hint, "left", newNode);
11374
+ if (this._isMapMode) {
11375
+ if (value !== void 0) this._store.set(key, value);
11376
+ else this._setValue(key, value);
11377
+ }
11378
+ this._size++;
11379
+ const NIL = this.NIL;
11380
+ const hMin = this._header._left ?? NIL;
11381
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11382
+ const hMax = this._header._right ?? NIL;
11383
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11384
+ return newNode;
11385
+ }
11386
+ const pred = this._predecessorOf(hint);
11387
+ if (pred && cmp(pred.key, key) >= 0) {
11388
+ return this._setKVNode(key, value)?.node;
11389
+ }
11390
+ if (pred && !this.isRealNode(pred.right)) {
11391
+ const newNode = this.createNode(key, value);
11392
+ if (!this.isRealNode(newNode)) return void 0;
11393
+ this._attachNewNode(pred, "right", newNode);
11394
+ if (this._isMapMode) {
11395
+ if (value !== void 0) this._store.set(key, value);
11396
+ else this._setValue(key, value);
11397
+ }
11398
+ this._size++;
11399
+ const NIL = this.NIL;
11400
+ const hMin = this._header._left ?? NIL;
11401
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11402
+ const hMax = this._header._right ?? NIL;
11403
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11404
+ return newNode;
11405
+ }
11406
+ return this._setKVNode(key, value)?.node;
11407
+ }
11408
+ if (!this.isRealNode(hint.right)) {
11409
+ const newNode = this.createNode(key, value);
11410
+ if (!this.isRealNode(newNode)) return void 0;
11411
+ this._attachNewNode(hint, "right", newNode);
11412
+ if (this._isMapMode) {
11413
+ if (value !== void 0) this._store.set(key, value);
11414
+ else this._setValue(key, value);
11415
+ }
11416
+ this._size++;
11417
+ const NIL = this.NIL;
11418
+ const hMin = this._header._left ?? NIL;
11419
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11420
+ const hMax = this._header._right ?? NIL;
11421
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11422
+ return newNode;
11423
+ }
11424
+ const succ = this._successorOf(hint);
11425
+ if (succ && cmp(succ.key, key) <= 0) {
11426
+ return this._setKVNode(key, value)?.node;
11427
+ }
11428
+ if (succ && !this.isRealNode(succ.left)) {
11429
+ const newNode = this.createNode(key, value);
11430
+ if (!this.isRealNode(newNode)) return void 0;
11431
+ this._attachNewNode(succ, "left", newNode);
11432
+ if (this._isMapMode) {
11433
+ if (value !== void 0) this._store.set(key, value);
11434
+ else this._setValue(key, value);
11435
+ }
11436
+ this._size++;
11437
+ const NIL = this.NIL;
11438
+ const hMin = this._header._left ?? NIL;
11439
+ if (hMin === NIL || this._compare(newNode.key, hMin.key) < 0) this._setMinCache(newNode);
11440
+ const hMax = this._header._right ?? NIL;
11441
+ if (hMax === NIL || this._compare(newNode.key, hMax.key) > 0) this._setMaxCache(newNode);
11442
+ return newNode;
11443
+ }
11444
+ return this._setKVNode(key, value)?.node;
11445
+ }
11446
+ /**
11447
+ * Boolean wrapper for setWithHintNode.
11448
+ * @remarks Time O(log n) average, Space O(1)
11449
+ */
11450
+ setWithHint(key, value, hint) {
11451
+ return this.setWithHintNode(key, value, hint) !== void 0;
11452
+ }
11453
+ /**
11454
+ * Insert or update a key/value (map mode) or key-only (set mode).
11455
+ *
11456
+ * This method is optimized for:
11457
+ * - monotonic inserts via min/max boundary fast paths
11458
+ * - updates via a single-pass search (no double walk)
11459
+ *
11460
+ * @remarks Time O(log n) average, Space O(1)
11461
+ */
11462
+ set(keyNodeOrEntry, value) {
11463
+ if (!this.isNode(keyNodeOrEntry)) {
11464
+ if (keyNodeOrEntry === null || keyNodeOrEntry === void 0) return false;
11465
+ if (this.isEntry(keyNodeOrEntry)) {
11466
+ const key = keyNodeOrEntry[0];
11467
+ if (key === null || key === void 0) return false;
11468
+ const nextValue = value ?? keyNodeOrEntry[1];
11469
+ return this._setKV(key, nextValue);
11470
+ }
11471
+ return this._setKV(keyNodeOrEntry, value);
11472
+ }
11019
11473
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
11020
11474
  if (!this.isRealNode(newNode)) return false;
11021
11475
  const insertStatus = this._insert(newNode);
@@ -11037,19 +11491,23 @@ var RedBlackTree = class extends BST {
11037
11491
  }
11038
11492
  /**
11039
11493
  * Delete a node by key/node/entry and rebalance as needed.
11040
- * @remarks Time O(log n), Space O(1)
11041
- * @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node to delete.
11494
+ * @remarks Time O(log n) average, Space O(1)
11495
+ * @param keyNodeEntryRawOrPredicate - Key, node, or [key, value] entry identifying the node to delete.
11042
11496
  * @returns Array with deletion metadata (removed node, rebalancing hint if any).
11043
11497
  */
11044
- delete(keyNodeOrEntry) {
11045
- if (keyNodeOrEntry === null) return [];
11498
+ delete(keyNodeEntryRawOrPredicate) {
11499
+ if (keyNodeEntryRawOrPredicate === null) return [];
11046
11500
  const results = [];
11047
11501
  let nodeToDelete;
11048
- if (this._isPredicate(keyNodeOrEntry)) nodeToDelete = this.getNode(keyNodeOrEntry);
11049
- else nodeToDelete = this.isRealNode(keyNodeOrEntry) ? keyNodeOrEntry : this.getNode(keyNodeOrEntry);
11502
+ if (this._isPredicate(keyNodeEntryRawOrPredicate)) nodeToDelete = this.getNode(keyNodeEntryRawOrPredicate);
11503
+ else nodeToDelete = this.isRealNode(keyNodeEntryRawOrPredicate) ? keyNodeEntryRawOrPredicate : this.getNode(keyNodeEntryRawOrPredicate);
11050
11504
  if (!nodeToDelete) {
11051
11505
  return results;
11052
11506
  }
11507
+ const willDeleteMin = nodeToDelete === this._minNode;
11508
+ const willDeleteMax = nodeToDelete === this._maxNode;
11509
+ const nextMin = willDeleteMin ? this._successorOf(nodeToDelete) : void 0;
11510
+ const nextMax = willDeleteMax ? this._predecessorOf(nodeToDelete) : void 0;
11053
11511
  let originalColor = nodeToDelete.color;
11054
11512
  let replacementNode;
11055
11513
  if (!this.isRealNode(nodeToDelete.left)) {
@@ -11088,6 +11546,19 @@ var RedBlackTree = class extends BST {
11088
11546
  }
11089
11547
  if (this._isMapMode) this._store.delete(nodeToDelete.key);
11090
11548
  this._size--;
11549
+ if (this._size <= 0) {
11550
+ this._setMinCache(void 0);
11551
+ this._setMaxCache(void 0);
11552
+ } else {
11553
+ if (willDeleteMin) this._setMinCache(nextMin);
11554
+ if (willDeleteMax) this._setMaxCache(nextMax);
11555
+ if (!this._minNode || !this.isRealNode(this._minNode)) {
11556
+ this._setMinCache(this.isRealNode(this._root) ? this.getLeftMost((n) => n, this._root) : void 0);
11557
+ }
11558
+ if (!this._maxNode || !this.isRealNode(this._maxNode)) {
11559
+ this._setMaxCache(this.isRealNode(this._root) ? this.getRightMost((n) => n, this._root) : void 0);
11560
+ }
11561
+ }
11091
11562
  if (originalColor === "BLACK") {
11092
11563
  this._deleteFixup(replacementNode);
11093
11564
  }
@@ -11096,7 +11567,7 @@ var RedBlackTree = class extends BST {
11096
11567
  }
11097
11568
  /**
11098
11569
  * Transform entries into a like-kind red-black tree with possibly different key/value types.
11099
- * @remarks Time O(n), Space O(n)
11570
+ * @remarks Time O(n) average, Space O(n)
11100
11571
  * @template MK
11101
11572
  * @template MV
11102
11573
  * @template MR
@@ -11109,44 +11580,65 @@ var RedBlackTree = class extends BST {
11109
11580
  const out = this._createLike([], options);
11110
11581
  let index = 0;
11111
11582
  for (const [key, value] of this) {
11112
- out.add(callback.call(thisArg, value, key, index++, this));
11583
+ out.set(callback.call(thisArg, value, key, index++, this));
11113
11584
  }
11114
11585
  return out;
11115
11586
  }
11587
+ /**
11588
+ * (Internal) Create an empty instance of the same concrete tree type.
11589
+ * @remarks Time O(1) average, Space O(1)
11590
+ */
11116
11591
  _createInstance(options) {
11117
11592
  const Ctor = this.constructor;
11118
11593
  return new Ctor([], { ...this._snapshotOptions(), ...options ?? {} });
11119
11594
  }
11595
+ /**
11596
+ * (Internal) Create a like-kind tree (same concrete class) populated from an iterable.
11597
+ * @remarks Time O(m log m) average (m = iterable length), Space O(m)
11598
+ */
11120
11599
  _createLike(iter = [], options) {
11121
11600
  const Ctor = this.constructor;
11122
11601
  return new Ctor(iter, { ...this._snapshotOptions(), ...options ?? {} });
11123
11602
  }
11603
+ /**
11604
+ * (Internal) Set the root pointer and keep header.parent in sync.
11605
+ * @remarks Time O(1), Space O(1)
11606
+ */
11124
11607
  _setRoot(v) {
11608
+ const NIL = this.NIL;
11125
11609
  if (v) {
11126
11610
  v.parent = void 0;
11127
11611
  }
11128
11612
  this._root = v;
11613
+ this._header.parent = v ?? NIL;
11129
11614
  }
11615
+ /**
11616
+ * (Internal) Replace a node in place while preserving its color.
11617
+ * @remarks Time O(1) average, Space O(1)
11618
+ */
11130
11619
  _replaceNode(oldNode, newNode) {
11131
11620
  newNode.color = oldNode.color;
11132
11621
  return super._replaceNode(oldNode, newNode);
11133
11622
  }
11134
11623
  /**
11135
11624
  * (Protected) Standard BST insert followed by red-black fix-up.
11136
- * @remarks Time O(log n), Space O(1)
11625
+ * @remarks Time O(log n) average, Space O(1)
11137
11626
  * @param node - Node to insert.
11138
11627
  * @returns Status string: 'CREATED' or 'UPDATED'.
11139
11628
  */
11140
11629
  _insert(node) {
11141
- let current = this.root ?? this.NIL;
11142
- let parent = void 0;
11143
- while (current !== this.NIL) {
11630
+ const NIL = this.NIL;
11631
+ const cmp = this._compare.bind(this);
11632
+ let current = this._header.parent ?? NIL;
11633
+ let parent;
11634
+ let lastCompared = 0;
11635
+ while (current !== NIL) {
11144
11636
  parent = current;
11145
- const compared = this._compare(node.key, current.key);
11146
- if (compared < 0) {
11147
- current = current.left ?? this.NIL;
11148
- } else if (compared > 0) {
11149
- current = current.right ?? this.NIL;
11637
+ lastCompared = cmp(node.key, current.key);
11638
+ if (lastCompared < 0) {
11639
+ current = current.left ?? NIL;
11640
+ } else if (lastCompared > 0) {
11641
+ current = current.right ?? NIL;
11150
11642
  } else {
11151
11643
  this._replaceNode(current, node);
11152
11644
  return "UPDATED";
@@ -11155,13 +11647,13 @@ var RedBlackTree = class extends BST {
11155
11647
  node.parent = parent;
11156
11648
  if (!parent) {
11157
11649
  this._setRoot(node);
11158
- } else if (this._compare(node.key, parent.key) < 0) {
11650
+ } else if (lastCompared < 0) {
11159
11651
  parent.left = node;
11160
11652
  } else {
11161
11653
  parent.right = node;
11162
11654
  }
11163
- node.left = this.NIL;
11164
- node.right = this.NIL;
11655
+ node.left = NIL;
11656
+ node.right = NIL;
11165
11657
  node.color = "RED";
11166
11658
  this._insertFixup(node);
11167
11659
  return "CREATED";
@@ -11187,55 +11679,66 @@ var RedBlackTree = class extends BST {
11187
11679
  }
11188
11680
  /**
11189
11681
  * (Protected) Restore red-black properties after insertion (recolor/rotate).
11190
- * @remarks Time O(log n), Space O(1)
11682
+ * @remarks Time O(log n) average, Space O(1)
11191
11683
  * @param z - Recently inserted node.
11192
11684
  * @returns void
11193
11685
  */
11194
11686
  _insertFixup(z) {
11195
- while (z?.parent?.color === "RED") {
11196
- if (z.parent === z.parent.parent?.left) {
11197
- const y = z.parent.parent.right;
11687
+ const leftRotate = this._leftRotate.bind(this);
11688
+ const rightRotate = this._rightRotate.bind(this);
11689
+ while (z) {
11690
+ const p = z.parent;
11691
+ if (!p || p.color !== "RED") break;
11692
+ const gp = p.parent;
11693
+ if (!gp) break;
11694
+ if (p === gp.left) {
11695
+ const y = gp.right;
11198
11696
  if (y?.color === "RED") {
11199
- z.parent.color = "BLACK";
11697
+ p.color = "BLACK";
11200
11698
  y.color = "BLACK";
11201
- z.parent.parent.color = "RED";
11202
- z = z.parent.parent;
11203
- } else {
11204
- if (z === z.parent.right) {
11205
- z = z.parent;
11206
- this._leftRotate(z);
11207
- }
11208
- if (z && z.parent && z.parent.parent) {
11209
- z.parent.color = "BLACK";
11210
- z.parent.parent.color = "RED";
11211
- this._rightRotate(z.parent.parent);
11212
- }
11699
+ gp.color = "RED";
11700
+ z = gp;
11701
+ continue;
11702
+ }
11703
+ if (z === p.right) {
11704
+ z = p;
11705
+ leftRotate(z);
11706
+ }
11707
+ const p2 = z?.parent;
11708
+ const gp2 = p2?.parent;
11709
+ if (p2 && gp2) {
11710
+ p2.color = "BLACK";
11711
+ gp2.color = "RED";
11712
+ rightRotate(gp2);
11213
11713
  }
11214
11714
  } else {
11215
- const y = z?.parent?.parent?.left ?? void 0;
11715
+ const y = gp.left;
11216
11716
  if (y?.color === "RED") {
11217
- z.parent.color = "BLACK";
11717
+ p.color = "BLACK";
11218
11718
  y.color = "BLACK";
11219
- z.parent.parent.color = "RED";
11220
- z = z.parent.parent;
11221
- } else {
11222
- if (z === z.parent.left) {
11223
- z = z.parent;
11224
- this._rightRotate(z);
11225
- }
11226
- if (z && z.parent && z.parent.parent) {
11227
- z.parent.color = "BLACK";
11228
- z.parent.parent.color = "RED";
11229
- this._leftRotate(z.parent.parent);
11230
- }
11719
+ gp.color = "RED";
11720
+ z = gp;
11721
+ continue;
11722
+ }
11723
+ if (z === p.left) {
11724
+ z = p;
11725
+ rightRotate(z);
11726
+ }
11727
+ const p2 = z?.parent;
11728
+ const gp2 = p2?.parent;
11729
+ if (p2 && gp2) {
11730
+ p2.color = "BLACK";
11731
+ gp2.color = "RED";
11732
+ leftRotate(gp2);
11231
11733
  }
11232
11734
  }
11735
+ break;
11233
11736
  }
11234
11737
  if (this.isRealNode(this._root)) this._root.color = "BLACK";
11235
11738
  }
11236
11739
  /**
11237
11740
  * (Protected) Restore red-black properties after deletion (recolor/rotate).
11238
- * @remarks Time O(log n), Space O(1)
11741
+ * @remarks Time O(log n) average, Space O(1)
11239
11742
  * @param node - Child that replaced the deleted node (may be undefined).
11240
11743
  * @returns void
11241
11744
  */
@@ -11497,7 +12000,7 @@ var AVLTreeMultiMap = class extends AVLTree {
11497
12000
  constructor(keysNodesEntriesOrRaws = [], options) {
11498
12001
  super([], { ...options, isMapMode: true });
11499
12002
  if (keysNodesEntriesOrRaws) {
11500
- this.addMany(keysNodesEntriesOrRaws);
12003
+ this.setMany(keysNodesEntriesOrRaws);
11501
12004
  }
11502
12005
  }
11503
12006
  createNode(key, value = []) {
@@ -11517,27 +12020,27 @@ var AVLTreeMultiMap = class extends AVLTree {
11517
12020
  * Insert a value or a list of values into the multimap. If the key exists, values are appended.
11518
12021
  * @remarks Time O(log N + M), Space O(1)
11519
12022
  * @param keyNodeOrEntry - Key, node, or [key, values] entry.
11520
- * @param [value] - Single value to add when a bare key is provided.
12023
+ * @param [value] - Single value to set when a bare key is provided.
11521
12024
  * @returns True if inserted or appended; false if ignored.
11522
12025
  */
11523
- add(keyNodeOrEntry, value) {
11524
- if (this.isRealNode(keyNodeOrEntry)) return super.add(keyNodeOrEntry);
12026
+ set(keyNodeOrEntry, value) {
12027
+ if (this.isRealNode(keyNodeOrEntry)) return super.set(keyNodeOrEntry);
11525
12028
  const _commonAdd = /* @__PURE__ */ __name((key, values) => {
11526
12029
  if (key === void 0 || key === null) return false;
11527
- const _addToValues = /* @__PURE__ */ __name(() => {
12030
+ const _setToValues = /* @__PURE__ */ __name(() => {
11528
12031
  const existingValues = this.get(key);
11529
12032
  if (existingValues !== void 0 && values !== void 0) {
11530
12033
  for (const value2 of values) existingValues.push(value2);
11531
12034
  return true;
11532
12035
  }
11533
12036
  return false;
11534
- }, "_addToValues");
11535
- const _addByNode = /* @__PURE__ */ __name(() => {
12037
+ }, "_setToValues");
12038
+ const _setByNode = /* @__PURE__ */ __name(() => {
11536
12039
  const existingNode = this.getNode(key);
11537
12040
  if (this.isRealNode(existingNode)) {
11538
12041
  const existingValues = this.get(existingNode);
11539
12042
  if (existingValues === void 0) {
11540
- super.add(key, values);
12043
+ super.set(key, values);
11541
12044
  return true;
11542
12045
  }
11543
12046
  if (values !== void 0) {
@@ -11547,13 +12050,13 @@ var AVLTreeMultiMap = class extends AVLTree {
11547
12050
  return false;
11548
12051
  }
11549
12052
  } else {
11550
- return super.add(key, values);
12053
+ return super.set(key, values);
11551
12054
  }
11552
- }, "_addByNode");
12055
+ }, "_setByNode");
11553
12056
  if (this._isMapMode) {
11554
- return _addByNode() || _addToValues();
12057
+ return _setByNode() || _setToValues();
11555
12058
  }
11556
- return _addToValues() || _addByNode();
12059
+ return _setToValues() || _setByNode();
11557
12060
  }, "_commonAdd");
11558
12061
  if (this.isEntry(keyNodeOrEntry)) {
11559
12062
  const [key, values] = keyNodeOrEntry;
@@ -11621,7 +12124,7 @@ var AVLTreeMultiMap = class extends AVLTree {
11621
12124
  map(callback, options, thisArg) {
11622
12125
  const out = this._createLike([], options);
11623
12126
  let i = 0;
11624
- for (const [k, v] of this) out.add(callback.call(thisArg, v, k, i++, this));
12127
+ for (const [k, v] of this) out.set(callback.call(thisArg, v, k, i++, this));
11625
12128
  return out;
11626
12129
  }
11627
12130
  /**
@@ -11804,7 +12307,7 @@ var TreeMultiMap = class extends RedBlackTree {
11804
12307
  constructor(keysNodesEntriesOrRaws = [], options) {
11805
12308
  super([], { ...options });
11806
12309
  if (keysNodesEntriesOrRaws) {
11807
- this.addMany(keysNodesEntriesOrRaws);
12310
+ this.setMany(keysNodesEntriesOrRaws);
11808
12311
  }
11809
12312
  }
11810
12313
  createNode(key, value = []) {
@@ -11824,27 +12327,27 @@ var TreeMultiMap = class extends RedBlackTree {
11824
12327
  * Insert a value or a list of values into the multimap. If the key exists, values are appended.
11825
12328
  * @remarks Time O(log N + M), Space O(1)
11826
12329
  * @param keyNodeOrEntry - Key, node, or [key, values] entry.
11827
- * @param [value] - Single value to add when a bare key is provided.
12330
+ * @param [value] - Single value to set when a bare key is provided.
11828
12331
  * @returns True if inserted or appended; false if ignored.
11829
12332
  */
11830
- add(keyNodeOrEntry, value) {
11831
- if (this.isRealNode(keyNodeOrEntry)) return super.add(keyNodeOrEntry);
12333
+ set(keyNodeOrEntry, value) {
12334
+ if (this.isRealNode(keyNodeOrEntry)) return super.set(keyNodeOrEntry);
11832
12335
  const _commonAdd = /* @__PURE__ */ __name((key, values) => {
11833
12336
  if (key === void 0 || key === null) return false;
11834
- const _addToValues = /* @__PURE__ */ __name(() => {
12337
+ const _setToValues = /* @__PURE__ */ __name(() => {
11835
12338
  const existingValues = this.get(key);
11836
12339
  if (existingValues !== void 0 && values !== void 0) {
11837
12340
  for (const value2 of values) existingValues.push(value2);
11838
12341
  return true;
11839
12342
  }
11840
12343
  return false;
11841
- }, "_addToValues");
11842
- const _addByNode = /* @__PURE__ */ __name(() => {
12344
+ }, "_setToValues");
12345
+ const _setByNode = /* @__PURE__ */ __name(() => {
11843
12346
  const existingNode = this.getNode(key);
11844
12347
  if (this.isRealNode(existingNode)) {
11845
12348
  const existingValues = this.get(existingNode);
11846
12349
  if (existingValues === void 0) {
11847
- super.add(key, values);
12350
+ super.set(key, values);
11848
12351
  return true;
11849
12352
  }
11850
12353
  if (values !== void 0) {
@@ -11854,13 +12357,13 @@ var TreeMultiMap = class extends RedBlackTree {
11854
12357
  return false;
11855
12358
  }
11856
12359
  } else {
11857
- return super.add(key, values);
12360
+ return super.set(key, values);
11858
12361
  }
11859
- }, "_addByNode");
12362
+ }, "_setByNode");
11860
12363
  if (this._isMapMode) {
11861
- return _addByNode() || _addToValues();
12364
+ return _setByNode() || _setToValues();
11862
12365
  }
11863
- return _addToValues() || _addByNode();
12366
+ return _setToValues() || _setByNode();
11864
12367
  }, "_commonAdd");
11865
12368
  if (this.isEntry(keyNodeOrEntry)) {
11866
12369
  const [key, values] = keyNodeOrEntry;
@@ -11900,7 +12403,7 @@ var TreeMultiMap = class extends RedBlackTree {
11900
12403
  map(callback, options, thisArg) {
11901
12404
  const out = this._createLike([], options);
11902
12405
  let i = 0;
11903
- for (const [k, v] of this) out.add(callback.call(thisArg, v, k, i++, this));
12406
+ for (const [k, v] of this) out.set(callback.call(thisArg, v, k, i++, this));
11904
12407
  return out;
11905
12408
  }
11906
12409
  /**
@@ -12085,7 +12588,7 @@ var TreeCounter = class extends RedBlackTree {
12085
12588
  */
12086
12589
  constructor(keysNodesEntriesOrRaws = [], options) {
12087
12590
  super([], options);
12088
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
12591
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
12089
12592
  }
12090
12593
  _count = 0;
12091
12594
  /**
@@ -12125,10 +12628,10 @@ var TreeCounter = class extends RedBlackTree {
12125
12628
  * @param [count] - How much to increase the node's count (default 1).
12126
12629
  * @returns True if inserted/updated; false if ignored.
12127
12630
  */
12128
- add(keyNodeOrEntry, value, count = 1) {
12631
+ set(keyNodeOrEntry, value, count = 1) {
12129
12632
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value, count);
12130
12633
  const orgCount = newNode?.count || 0;
12131
- const isSuccessAdded = super.add(newNode, newValue);
12634
+ const isSuccessAdded = super.set(newNode, newValue);
12132
12635
  if (isSuccessAdded) {
12133
12636
  this._count += orgCount;
12134
12637
  return true;
@@ -12139,16 +12642,16 @@ var TreeCounter = class extends RedBlackTree {
12139
12642
  /**
12140
12643
  * Delete a node (or decrement its count) and rebalance if needed.
12141
12644
  * @remarks Time O(log N), Space O(1)
12142
- * @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node.
12645
+ * @param keyNodeEntryRawOrPredicate - Key, node, or [key, value] entry identifying the node.
12143
12646
  * @param [ignoreCount] - If true, remove the node regardless of its count.
12144
12647
  * @returns Array of deletion results including deleted node and a rebalance hint when present.
12145
12648
  */
12146
- delete(keyNodeOrEntry, ignoreCount = false) {
12147
- if (keyNodeOrEntry === null) return [];
12649
+ delete(keyNodeEntryRawOrPredicate, ignoreCount = false) {
12650
+ if (keyNodeEntryRawOrPredicate === null) return [];
12148
12651
  const results = [];
12149
12652
  let nodeToDelete;
12150
- if (this._isPredicate(keyNodeOrEntry)) nodeToDelete = this.getNode(keyNodeOrEntry);
12151
- else nodeToDelete = this.isRealNode(keyNodeOrEntry) ? keyNodeOrEntry : this.getNode(keyNodeOrEntry);
12653
+ if (this._isPredicate(keyNodeEntryRawOrPredicate)) nodeToDelete = this.getNode(keyNodeEntryRawOrPredicate);
12654
+ else nodeToDelete = this.isRealNode(keyNodeEntryRawOrPredicate) ? keyNodeEntryRawOrPredicate : this.getNode(keyNodeEntryRawOrPredicate);
12152
12655
  if (!nodeToDelete) {
12153
12656
  return results;
12154
12657
  }
@@ -12191,7 +12694,6 @@ var TreeCounter = class extends RedBlackTree {
12191
12694
  if (ignoreCount || nodeToDelete.count <= 1) {
12192
12695
  if (successor.right !== null) {
12193
12696
  this._transplant(successor, successor.right);
12194
- this._count -= nodeToDelete.count;
12195
12697
  }
12196
12698
  } else {
12197
12699
  nodeToDelete.count--;
@@ -12281,7 +12783,7 @@ var TreeCounter = class extends RedBlackTree {
12281
12783
  const out = this._createLike([], options);
12282
12784
  let index = 0;
12283
12785
  for (const [key, value] of this) {
12284
- out.add(callback.call(thisArg, value, key, index++, this));
12786
+ out.set(callback.call(thisArg, value, key, index++, this));
12285
12787
  }
12286
12788
  return out;
12287
12789
  }
@@ -12294,6 +12796,11 @@ var TreeCounter = class extends RedBlackTree {
12294
12796
  const out = this._createInstance();
12295
12797
  this._clone(out);
12296
12798
  out._count = this._count;
12799
+ for (const node of this.dfs((n) => n, "IN")) {
12800
+ if (!node) continue;
12801
+ const outNode = out.getNode(node.key);
12802
+ if (outNode) outNode.count = node.count;
12803
+ }
12297
12804
  return out;
12298
12805
  }
12299
12806
  /**
@@ -12537,7 +13044,7 @@ var AVLTreeCounter = class extends AVLTree {
12537
13044
  */
12538
13045
  constructor(keysNodesEntriesOrRaws = [], options) {
12539
13046
  super([], options);
12540
- if (keysNodesEntriesOrRaws) this.addMany(keysNodesEntriesOrRaws);
13047
+ if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
12541
13048
  }
12542
13049
  _count = 0;
12543
13050
  get count() {
@@ -12572,11 +13079,11 @@ var AVLTreeCounter = class extends AVLTree {
12572
13079
  * @param [count] - How much to increase the node's count (default 1).
12573
13080
  * @returns True if inserted/updated; false if ignored.
12574
13081
  */
12575
- add(keyNodeOrEntry, value, count = 1) {
13082
+ set(keyNodeOrEntry, value, count = 1) {
12576
13083
  const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value, count);
12577
13084
  if (newNode === void 0) return false;
12578
13085
  const orgNodeCount = newNode?.count || 0;
12579
- const inserted = super.add(newNode, newValue);
13086
+ const inserted = super.set(newNode, newValue);
12580
13087
  if (inserted) {
12581
13088
  this._count += orgNodeCount;
12582
13089
  }
@@ -12684,9 +13191,9 @@ var AVLTreeCounter = class extends AVLTree {
12684
13191
  clone() {
12685
13192
  const out = this._createInstance();
12686
13193
  if (this._isMapMode) {
12687
- this.bfs((node) => out.add(node.key, void 0, node.count));
13194
+ this.bfs((node) => out.set(node.key, void 0, node.count));
12688
13195
  } else {
12689
- this.bfs((node) => out.add(node.key, node.value, node.count));
13196
+ this.bfs((node) => out.set(node.key, node.value, node.count));
12690
13197
  }
12691
13198
  if (this._isMapMode) out._store = this._store;
12692
13199
  return out;
@@ -12706,7 +13213,7 @@ var AVLTreeCounter = class extends AVLTree {
12706
13213
  const out = this._createLike([], options);
12707
13214
  let index = 0;
12708
13215
  for (const [key, value] of this) {
12709
- out.add(callback.call(thisArg, value, key, index++, this));
13216
+ out.set(callback.call(thisArg, value, key, index++, this));
12710
13217
  }
12711
13218
  return out;
12712
13219
  }