data-structure-typed 2.2.8 → 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.
- package/.github/workflows/ci.yml +9 -0
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/README_CN.md +1 -1
- package/dist/cjs/index.cjs +584 -76
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +588 -79
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +584 -76
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +588 -79
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/linear-base.d.ts +6 -6
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +3 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +2 -1
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +150 -20
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +3 -3
- package/dist/types/interfaces/binary-tree.d.ts +1 -1
- package/dist/umd/data-structure-typed.js +588 -79
- package/dist/umd/data-structure-typed.js.map +1 -1
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +4 -3
- package/src/data-structures/base/linear-base.ts +2 -12
- package/src/data-structures/binary-tree/binary-tree.ts +5 -6
- package/src/data-structures/binary-tree/bst.ts +79 -4
- package/src/data-structures/binary-tree/red-black-tree.ts +583 -73
- package/src/data-structures/binary-tree/tree-counter.ts +21 -9
- package/src/data-structures/queue/deque.ts +10 -0
- package/src/interfaces/binary-tree.ts +1 -1
- package/test/unit/data-structures/base/iterable-element-base.coverage.test.ts +106 -0
- package/test/unit/data-structures/base/iterable-element-base.more-branches.coverage.test.ts +61 -0
- package/test/unit/data-structures/base/linear-base.array.coverage.test.ts +168 -0
- package/test/unit/data-structures/base/linear-base.concat-else.coverage.test.ts +82 -0
- package/test/unit/data-structures/base/linear-base.coverage.test.ts +72 -0
- package/test/unit/data-structures/base/linear-base.more-branches.coverage.test.ts +417 -0
- package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches-3.coverage.test.ts +146 -0
- package/test/unit/data-structures/binary-tree/avl-tree-counter.more-branches.coverage.test.ts +93 -0
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.coverage.test.ts +108 -0
- package/test/unit/data-structures/binary-tree/avl-tree-multi-map.more-branches-2.coverage.test.ts +85 -0
- package/test/unit/data-structures/binary-tree/avl-tree-node.familyPosition-root-left.coverage.test.ts +17 -0
- package/test/unit/data-structures/binary-tree/avl-tree.more-branches-2.coverage.test.ts +99 -0
- package/test/unit/data-structures/binary-tree/binary-indexed-tree.more-branches.coverage.test.ts +18 -0
- package/test/unit/data-structures/binary-tree/binary-tree.more-branches.coverage.test.ts +56 -0
- package/test/unit/data-structures/binary-tree/binary-tree.remaining-branches.coverage.test.ts +229 -0
- package/test/unit/data-structures/binary-tree/bst.bound-by-predicate.coverage.test.ts +33 -0
- package/test/unit/data-structures/binary-tree/bst.coverage.test.ts +94 -0
- package/test/unit/data-structures/binary-tree/bst.deletebykey.coverage.test.ts +70 -0
- package/test/unit/data-structures/binary-tree/bst.deletewhere.coverage.test.ts +37 -0
- package/test/unit/data-structures/binary-tree/bst.floor-lower-predicate.coverage.test.ts +29 -0
- package/test/unit/data-structures/binary-tree/bst.floor-setmany.coverage.test.ts +72 -0
- package/test/unit/data-structures/binary-tree/bst.getnode.range-ensure.coverage.test.ts +22 -0
- package/test/unit/data-structures/binary-tree/bst.misc-branches.coverage.test.ts +100 -0
- package/test/unit/data-structures/binary-tree/bst.more-branches-2.coverage.test.ts +133 -0
- package/test/unit/data-structures/binary-tree/bst.more-branches-3.coverage.test.ts +45 -0
- package/test/unit/data-structures/binary-tree/bst.more-branches-4.coverage.test.ts +36 -0
- package/test/unit/data-structures/binary-tree/bst.more-branches-5.coverage.test.ts +40 -0
- package/test/unit/data-structures/binary-tree/bst.more.coverage.test.ts +39 -0
- package/test/unit/data-structures/binary-tree/bst.node-family.coverage.test.ts +29 -0
- package/test/unit/data-structures/binary-tree/bst.range-pruning.coverage.test.ts +43 -0
- package/test/unit/data-structures/binary-tree/bst.search-fastpath.coverage.test.ts +30 -0
- package/test/unit/data-structures/binary-tree/bst.test.ts +25 -55
- package/test/unit/data-structures/binary-tree/red-black-tree.boundary-corruption-repair.coverage.test.ts +66 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.boundary-max-update.coverage.test.ts +18 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.boundary-null.coverage.test.ts +53 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.boundary-stale-cache.coverage.test.ts +25 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.boundary-update.coverage.test.ts +23 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.cache-delete.coverage.test.ts +49 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.cache-edge.coverage.test.ts +37 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.cache-stale-insert.coverage.test.ts +39 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.coverage.test.ts +334 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.delete-fixup.coverage.test.ts +68 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.delete-successor.coverage.test.ts +75 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.factories.coverage.test.ts +26 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-compare-update.coverage.test.ts +74 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-no-update.coverage.test.ts +44 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint-cache-nullish.coverage.test.ts +61 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-defined.coverage.test.ts +35 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint-mapmode-undefined.coverage.test.ts +43 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint-more.coverage.test.ts +99 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.hint.coverage.test.ts +60 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.insert-cache-nullish.coverage.test.ts +29 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.insert-header-parent-nullish.coverage.test.ts +17 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.internal-walk.coverage.test.ts +57 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.minmax-cache.test.ts +65 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.misc-inputs.coverage.test.ts +17 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-2.coverage.test.ts +121 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-3.coverage.test.ts +55 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.more-branches-4.coverage.test.ts +44 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.predsucc.coverage.test.ts +40 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.remaining-branches.coverage.test.ts +123 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.set-inputs.coverage.test.ts +64 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-parent-cache.coverage.test.ts +79 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-remaining.coverage.test.ts +44 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.setkvnode-uncovered.coverage.test.ts +74 -0
- package/test/unit/data-structures/binary-tree/red-black-tree.update-branches.coverage.test.ts +30 -0
- package/test/unit/data-structures/binary-tree/segment-tree.more-branches.coverage.test.ts +31 -0
- package/test/unit/data-structures/binary-tree/tree-counter.coverage.test.ts +115 -0
- package/test/unit/data-structures/binary-tree/tree-counter.more-branches.coverage.test.ts +244 -0
- package/test/unit/data-structures/binary-tree/tree-counter.test.ts +4 -2
- package/test/unit/data-structures/binary-tree/tree-multi-map.coverage.test.ts +104 -0
- package/test/unit/data-structures/binary-tree/tree-multi-map.more-branches-2.coverage.test.ts +59 -0
- package/test/unit/data-structures/graph/abstract-graph.more-branches-2.coverage.test.ts +40 -0
- package/test/unit/data-structures/graph/abstract-graph.more-branches-3.coverage.test.ts +65 -0
- package/test/unit/data-structures/graph/abstract-graph.more-branches-4.coverage.test.ts +98 -0
- package/test/unit/data-structures/graph/abstract-graph.more-branches-5.coverage.test.ts +51 -0
- package/test/unit/data-structures/graph/abstract-graph.more-branches.coverage.test.ts +62 -0
- package/test/unit/data-structures/graph/directed-graph.more-branches-2.coverage.test.ts +38 -0
- package/test/unit/data-structures/graph/directed-graph.more-branches-3.coverage.test.ts +25 -0
- package/test/unit/data-structures/graph/directed-graph.more-branches.coverage.test.ts +82 -0
- package/test/unit/data-structures/graph/map-graph.more-branches.coverage.test.ts +22 -0
- package/test/unit/data-structures/graph/undirected-graph.more-branches-2.coverage.test.ts +35 -0
- package/test/unit/data-structures/graph/undirected-graph.more-branches.coverage.test.ts +87 -0
- package/test/unit/data-structures/hash/hash-map.more-branches.coverage.test.ts +64 -0
- package/test/unit/data-structures/hash/hash-map.toEntryFn-branch.coverage.test.ts +9 -0
- package/test/unit/data-structures/heap/heap.misc-branches.coverage.test.ts +110 -0
- package/test/unit/data-structures/heap/heap.remaining-branches.coverage.test.ts +22 -0
- package/test/unit/data-structures/heap/max-heap.coverage.test.ts +29 -0
- package/test/unit/data-structures/linked-list/doubly-linked-list.more-branches.coverage.test.ts +72 -0
- package/test/unit/data-structures/linked-list/linked-list.unshiftMany-else.coverage.test.ts +15 -0
- package/test/unit/data-structures/linked-list/singly-linked-list.coverage.test.ts +221 -0
- package/test/unit/data-structures/linked-list/singly-linked-list.more-branches.coverage.test.ts +86 -0
- package/test/unit/data-structures/linked-list/skip-linked-list.more-branches.coverage.test.ts +31 -0
- package/test/unit/data-structures/matrix/matrix.more-branches.coverage.test.ts +81 -0
- package/test/unit/data-structures/matrix/matrix.pivotElement-nullish.coverage.test.ts +28 -0
- package/test/unit/data-structures/priority-queue/max-priority-queue.more-branches.coverage.test.ts +10 -0
- package/test/unit/data-structures/priority-queue/priority-queue.coverage.test.ts +21 -0
- package/test/unit/data-structures/queue/deque.coverage.test.ts +173 -0
- package/test/unit/data-structures/queue/deque.more-branches-2.coverage.test.ts +39 -0
- package/test/unit/data-structures/queue/deque.more-branches-3.coverage.test.ts +9 -0
- package/test/unit/data-structures/queue/deque.more-branches.coverage.test.ts +95 -0
- package/test/unit/data-structures/queue/queue.coverage.test.ts +138 -0
- package/test/unit/data-structures/queue/queue.more-branches-2.coverage.test.ts +27 -0
- package/test/unit/data-structures/stack/stack.coverage.test.ts +112 -0
- package/test/unit/data-structures/tree/tree.more-branches.coverage.test.ts +9 -0
- package/test/unit/data-structures/trie/trie.more-branches-2.coverage.test.ts +51 -0
- package/test/utils/patch.ts +33 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Standard data structure",
|
|
5
5
|
"browser": "dist/umd/data-structure-typed.min.js",
|
|
6
6
|
"umd:main": "dist/umd/data-structure-typed.min.js",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"test": "npm run test:in-band",
|
|
52
52
|
"test:integration": "npm run update:subs && jest --config jest.integration.config.js && tsc test/integration/compile.test.ts && node test/integration/compile.mjs",
|
|
53
53
|
"test:perf": "npm run build:ecut && ts-node test/performance/benchmark-runner.ts --isolate --gc --cooldown-ms=80",
|
|
54
|
+
"test:coverage": "jest --runInBand --coverage",
|
|
54
55
|
"check": "npm run check:src && npm run check:test",
|
|
55
56
|
"check:src": "tsc --noEmit",
|
|
56
57
|
"check:test": "tsc -p tsconfig.test.json --noEmit",
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"format:test": "prettier --write 'test/**/*.{js,ts}'",
|
|
64
65
|
"format": "npm run format:src && npm run format:test",
|
|
65
66
|
"check:exist-latest": "sh scripts/check_exist_remotely.sh",
|
|
66
|
-
"ci": "env && git fetch --tags && npm run update:subs && npm run inspect && npm run lint && npm run test && npm run changelog",
|
|
67
|
+
"ci": "env && git fetch --tags && npm run update:subs && npm run inspect && npm run lint && npm run test:coverage && npm run changelog",
|
|
67
68
|
"update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed data-structure-typed --save-dev",
|
|
68
69
|
"install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multimap-typed trie-typed undirected-graph-typed queue-typed --save-dev",
|
|
69
70
|
"changelog": "auto-changelog",
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
"benchmark": "^2.1.4",
|
|
103
104
|
"binary-tree-typed": "^1.54.3",
|
|
104
105
|
"bst-typed": "^1.54.3",
|
|
105
|
-
"data-structure-typed": "^2.2.
|
|
106
|
+
"data-structure-typed": "^2.2.8",
|
|
106
107
|
"dependency-cruiser": "^16.5.0",
|
|
107
108
|
"doctoc": "^2.2.1",
|
|
108
109
|
"eslint": "^9.13.0",
|
|
@@ -75,7 +75,7 @@ export abstract class LinearBase<
|
|
|
75
75
|
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
76
76
|
* @remarks Time O(1), Space O(1)
|
|
77
77
|
*/
|
|
78
|
-
|
|
78
|
+
constructor(options?: LinearBaseOptions<E, R>) {
|
|
79
79
|
super(options);
|
|
80
80
|
if (options) {
|
|
81
81
|
const { maxLen } = options;
|
|
@@ -156,14 +156,6 @@ export abstract class LinearBase<
|
|
|
156
156
|
return -1;
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
/**
|
|
160
|
-
* Concatenate multiple containers of the same species.
|
|
161
|
-
* @param items - Other lists to append.
|
|
162
|
-
* @returns New container with combined elements (`this` type).
|
|
163
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
164
|
-
*/
|
|
165
|
-
concat(...items: this[]): this;
|
|
166
|
-
|
|
167
159
|
/**
|
|
168
160
|
* Concatenate elements and/or containers.
|
|
169
161
|
* @param items - Elements or other containers.
|
|
@@ -412,7 +404,7 @@ export abstract class LinearLinkedBase<
|
|
|
412
404
|
R = any,
|
|
413
405
|
NODE extends LinkedListNode<E> = LinkedListNode<E>
|
|
414
406
|
> extends LinearBase<E, R, NODE> {
|
|
415
|
-
|
|
407
|
+
constructor(options?: LinearBaseOptions<E, R>) {
|
|
416
408
|
super(options);
|
|
417
409
|
if (options) {
|
|
418
410
|
const { maxLen } = options;
|
|
@@ -478,8 +470,6 @@ export abstract class LinearLinkedBase<
|
|
|
478
470
|
* @returns New list with combined elements (`this` type).
|
|
479
471
|
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
480
472
|
*/
|
|
481
|
-
override concat(...items: LinearBase<E, R>[]): this;
|
|
482
|
-
|
|
483
473
|
override concat(...items: (E | LinearBase<E, R>)[]): this {
|
|
484
474
|
const newList = this.clone();
|
|
485
475
|
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
BinaryTreeDeleteResult,
|
|
11
11
|
BinaryTreeOptions,
|
|
12
12
|
BinaryTreePrintOptions,
|
|
13
|
-
BTNEntry,
|
|
13
|
+
BTNEntry, BTNRep,
|
|
14
14
|
DFSOrderPattern,
|
|
15
15
|
DFSStackItem,
|
|
16
16
|
EntryCallback,
|
|
@@ -717,7 +717,6 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
717
717
|
* @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).
|
|
718
718
|
*
|
|
719
719
|
* @param keysNodesEntriesOrRaws - An iterable of items to set.
|
|
720
|
-
* @param [values] - An optional parallel iterable of values.
|
|
721
720
|
* @returns An array of booleans indicating the success of each individual `set` operation.
|
|
722
721
|
*/
|
|
723
722
|
addMany(
|
|
@@ -796,16 +795,16 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
796
795
|
* Deletes a node from the tree.
|
|
797
796
|
* @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).
|
|
798
797
|
*
|
|
799
|
-
* @param
|
|
798
|
+
* @param keyNodeEntryRawOrPredicate - The node to delete.
|
|
800
799
|
* @returns An array containing deletion results (for compatibility with self-balancing trees).
|
|
801
800
|
*/
|
|
802
801
|
delete(
|
|
803
|
-
|
|
802
|
+
keyNodeEntryRawOrPredicate: BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>
|
|
804
803
|
): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] {
|
|
805
804
|
const deletedResult: BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[] = [];
|
|
806
805
|
if (!this._root) return deletedResult;
|
|
807
806
|
|
|
808
|
-
const curr = this.getNode(
|
|
807
|
+
const curr = this.getNode(keyNodeEntryRawOrPredicate);
|
|
809
808
|
if (!curr) return deletedResult;
|
|
810
809
|
|
|
811
810
|
const parent: BinaryTreeNode<K, V> | undefined = curr?.parent;
|
|
@@ -1140,7 +1139,7 @@ export class BinaryTree<K = any, V = any, R = any>
|
|
|
1140
1139
|
}
|
|
1141
1140
|
return true;
|
|
1142
1141
|
};
|
|
1143
|
-
const isStandardBST = checkBST(
|
|
1142
|
+
const isStandardBST = checkBST();
|
|
1144
1143
|
const isInverseBST = checkBST(true);
|
|
1145
1144
|
return isStandardBST || isInverseBST;
|
|
1146
1145
|
}
|
|
@@ -204,7 +204,8 @@ export class BSTNode<K = any, V = any> {
|
|
|
204
204
|
* // Create a simple BST with numeric keys
|
|
205
205
|
* const bst = new BST<number>([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
|
206
206
|
*
|
|
207
|
-
*
|
|
207
|
+
* // Keep the example output in source comments but avoid noisy test logs.
|
|
208
|
+
* await withMutedConsole(() => bst.print());
|
|
208
209
|
* // _______8__________
|
|
209
210
|
* // / \
|
|
210
211
|
* // ___4___ ____12_____
|
|
@@ -556,9 +557,55 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
556
557
|
startNode: BSTNOptKeyOrNode<K, BSTNode<K, V>> = this._root,
|
|
557
558
|
iterationType: IterationType = this.iterationType
|
|
558
559
|
): OptNode<BSTNode<K, V>> {
|
|
559
|
-
|
|
560
|
+
// Fast-path: key lookup should not allocate arrays or build predicate closures.
|
|
561
|
+
// (This is a hot path for get/has in Node Mode.)
|
|
562
|
+
if (keyNodeEntryOrPredicate === null || keyNodeEntryOrPredicate === undefined) return undefined;
|
|
563
|
+
|
|
564
|
+
// If a predicate is provided, defer to the full search logic.
|
|
565
|
+
if (this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
566
|
+
return this.getNodes(keyNodeEntryOrPredicate, true, startNode, iterationType)[0] ?? undefined;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// NOTE: Range<K> is not part of this overload, but callers may still pass it at runtime.
|
|
570
|
+
// Let search handle it.
|
|
571
|
+
if (keyNodeEntryOrPredicate instanceof Range) {
|
|
572
|
+
return (
|
|
573
|
+
this.getNodes(
|
|
574
|
+
keyNodeEntryOrPredicate,
|
|
575
|
+
true,
|
|
576
|
+
startNode as K | BSTNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
577
|
+
iterationType
|
|
578
|
+
)[0] ?? undefined
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
let targetKey: K | undefined;
|
|
583
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
584
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
585
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
586
|
+
const k = keyNodeEntryOrPredicate[0];
|
|
587
|
+
if (k === null || k === undefined) return undefined;
|
|
588
|
+
targetKey = k;
|
|
589
|
+
} else {
|
|
590
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const start = this.ensureNode(startNode);
|
|
594
|
+
if (!start) return undefined;
|
|
595
|
+
|
|
596
|
+
const NIL = this._NIL as unknown as BSTNode<K, V> | null | undefined;
|
|
597
|
+
let cur: BSTNode<K, V> | null | undefined = start;
|
|
598
|
+
const cmpFn = this._comparator;
|
|
599
|
+
while (cur && cur !== NIL) {
|
|
600
|
+
const c = cmpFn(targetKey, cur.key);
|
|
601
|
+
if (c === 0) return cur;
|
|
602
|
+
cur = c < 0 ? cur._left : cur._right;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
return undefined;
|
|
560
606
|
}
|
|
561
607
|
|
|
608
|
+
|
|
562
609
|
override search(
|
|
563
610
|
keyNodeEntryOrPredicate:
|
|
564
611
|
| K
|
|
@@ -619,9 +666,37 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
619
666
|
startNode = this.ensureNode(startNode);
|
|
620
667
|
if (!startNode) return [];
|
|
621
668
|
|
|
622
|
-
|
|
669
|
+
// Fast-path: key lookup (unique keys) using a tight BST walk (no allocations).
|
|
670
|
+
// This is the hot path for get/has/search by key.
|
|
623
671
|
const isRange = this.isRange(keyNodeEntryOrPredicate);
|
|
672
|
+
const isPred = !isRange && this._isPredicate(keyNodeEntryOrPredicate);
|
|
673
|
+
|
|
674
|
+
if (!isRange && !isPred) {
|
|
675
|
+
let targetKey: K | undefined;
|
|
676
|
+
if (this.isNode(keyNodeEntryOrPredicate)) {
|
|
677
|
+
targetKey = keyNodeEntryOrPredicate.key;
|
|
678
|
+
} else if (this.isEntry(keyNodeEntryOrPredicate)) {
|
|
679
|
+
const k = keyNodeEntryOrPredicate[0];
|
|
680
|
+
if (k !== null && k !== undefined) targetKey = k;
|
|
681
|
+
} else {
|
|
682
|
+
targetKey = keyNodeEntryOrPredicate;
|
|
683
|
+
}
|
|
684
|
+
if (targetKey === undefined) return [];
|
|
685
|
+
|
|
686
|
+
const NIL = this._NIL as unknown as BSTNode<K, V> | null | undefined;
|
|
687
|
+
const cmpFn = this._comparator;
|
|
688
|
+
let cur: BSTNode<K, V> | null | undefined = startNode;
|
|
689
|
+
|
|
690
|
+
// Loop intentionally avoids getters and extra type checks.
|
|
691
|
+
while (cur && cur !== NIL) {
|
|
692
|
+
const c = cmpFn(targetKey, cur.key);
|
|
693
|
+
if (c === 0) return [callback(cur)];
|
|
694
|
+
cur = c < 0 ? cur._left : cur._right;
|
|
695
|
+
}
|
|
696
|
+
return [];
|
|
697
|
+
}
|
|
624
698
|
|
|
699
|
+
let predicate: NodePredicate<BSTNode<K, V>>;
|
|
625
700
|
if (isRange) {
|
|
626
701
|
predicate = node => {
|
|
627
702
|
if (!node) return false;
|
|
@@ -2018,7 +2093,7 @@ export class BST<K = any, V = any, R = any> extends BinaryTree<K, V, R> implemen
|
|
|
2018
2093
|
if (succ.left) (succ.left as BSTNode<K, V>).parent = succ;
|
|
2019
2094
|
}
|
|
2020
2095
|
|
|
2021
|
-
this._size = Math.max(0,
|
|
2096
|
+
this._size = Math.max(0, this._size - 1);
|
|
2022
2097
|
return true;
|
|
2023
2098
|
}
|
|
2024
2099
|
}
|