sorted-collections 1.0.2 → 1.1.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/README.md +25 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +23 -5
package/README.md
CHANGED
|
@@ -128,6 +128,15 @@ byPrice.set(99.75, 'order-2');
|
|
|
128
128
|
[...byPrice.keys()]; // [99.75, 101.5]
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
+
Constructing from an existing iterable builds in bulk (sort once, cut into buckets) rather
|
|
132
|
+
than inserting one element at a time — see [Performance](#performance) for what that's
|
|
133
|
+
worth at scale. `SortedList.from`/`SortedSet.from`/`SortedMap.from` are equivalent sugar,
|
|
134
|
+
paralleling `Array.from`:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const scores2 = SortedList.from([42, 7, 99]); // same as new SortedList([42, 7, 99])
|
|
138
|
+
```
|
|
139
|
+
|
|
131
140
|
Range queries work the same way across all three structures:
|
|
132
141
|
|
|
133
142
|
```ts
|
|
@@ -165,6 +174,22 @@ machine). Ops/sec, higher is better.
|
|
|
165
174
|
| `set()`, one at a time, n=5,000 | 1,397/s | 7,056/s |
|
|
166
175
|
| `get()`, n=100,000 | 12,453/s | 834,080/s |
|
|
167
176
|
|
|
177
|
+
**Bulk construction** — `new SortedX(iterable)` sorts once and cuts directly into buckets,
|
|
178
|
+
instead of inserting one element at a time. Compared against the old per-element path
|
|
179
|
+
(construct empty, then `add()`/`set()` in a loop):
|
|
180
|
+
|
|
181
|
+
| Structure | n=1,000 | n=100,000 | n=1,000,000 |
|
|
182
|
+
|---|---:|---:|---:|
|
|
183
|
+
| `SortedList` (bulk vs. per-element) | 17,316/s vs 32,250/s | 85/s vs 93/s | 7/s vs 5/s |
|
|
184
|
+
| `SortedSet` (bulk vs. per-element) | 16,065/s vs 20,200/s | 79/s vs 55/s | 7/s vs 3/s |
|
|
185
|
+
| `SortedMap` (bulk vs. per-element) | 14,121/s vs 12,476/s | 56/s vs 33/s | 3/s vs 1/s |
|
|
186
|
+
|
|
187
|
+
At n=1,000, `SortedList` and `SortedSet` are marginally *slower* to bulk-construct than the
|
|
188
|
+
old per-element path — the fixed cost of one `Array.prototype.sort()` call doesn't have much
|
|
189
|
+
to amortize over yet, since the bucket size floor (32) already keeps per-element insertion
|
|
190
|
+
cheap at that scale. The absolute difference is microseconds either way. From ~100,000
|
|
191
|
+
elements on, bulk construction wins decisively, up to 3x faster at n=1,000,000.
|
|
192
|
+
|
|
168
193
|
**Honest notes — when this library is (and isn't) the right call:**
|
|
169
194
|
|
|
170
195
|
* Native `Set`/`Map` numbers are a raw-speed reference only, not an apples-to-apples
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';function
|
|
1
|
+
'use strict';function b(s,e,t,r){let n=0,o=s;for(;n<o;){let a=n+o>>>1,i=t(e(a));(r==="left"?i>=0:i>0)?o=a:n=a+1;}return n}var c=class c{constructor(e){this.buckets=[];this.count=0;this.comparator=e;}static targetBucketSizeFor(e){return Math.max(c.MIN_BUCKET_SIZE,Math.ceil(Math.sqrt(e)))}targetBucketSize(){return c.targetBucketSizeFor(this.count)}static fromSorted(e,t){let r=new c(t),n=e.length;if(n===0)return r;if(c.isDevelopment){for(let i=1;i<n;i++)if(t(e[i-1],e[i])>0)throw new Error("BucketEngine.fromSorted: input array is not sorted per comparator")}let o=c.targetBucketSizeFor(n),a=[];for(let i=0;i<n;i+=o)a.push(e.slice(i,i+o));return r.buckets=a,r.count=n,r}maybeSplit(e){let t=this.buckets[e],r=this.targetBucketSize();if(t.length>r*2){let n=t.length>>>1,o=t.splice(n);this.buckets.splice(e+1,0,o);}}maybeMerge(e){let t=this.buckets[e];if(t.length===0){this.buckets.splice(e,1);return}if(this.buckets.length<=1)return;let r=this.targetBucketSize();if(t.length<r/2){let n=e>0?e-1:e+1,[o,a]=e<n?[e,n]:[n,e],i=this.buckets[o].concat(this.buckets[a]);this.buckets.splice(o,2,i),this.maybeSplit(o);}}locateBy(e,t){let r=b(this.buckets.length,i=>{let l=this.buckets[i];return l[l.length-1]},e,t),n=Math.min(r,this.buckets.length-1),o=this.buckets[n],a=b(o.length,i=>o[i],e,t);return {bucketIndex:n,localIndex:a}}locate(e,t){return this.locateBy(r=>this.comparator(r,e),t)}locatePosition(e){if(e<0||e>=this.count)return;let t=e;for(let r=0;r<this.buckets.length;r++){let n=this.buckets[r];if(t<n.length)return {bucketIndex:r,localIndex:t};t-=n.length;}throw new Error("BucketEngine: internal invariant violated (count out of sync with buckets)")}globalIndex(e,t){let r=t;for(let n=0;n<e;n++)r+=this.buckets[n].length;return r}resolveIndex(e){return e<0?this.count+e:e}*iterateRange(e,t){for(let r=e.bucketIndex;r<this.buckets.length;r++){if(t&&r>t.bucketIndex)return;let n=this.buckets[r],o=r===e.bucketIndex?e.localIndex:0,a=t&&r===t.bucketIndex?t.localIndex:n.length;for(let i=o;i<a;i++)yield n[i];}}add(e){if(this.buckets.length===0){this.buckets.push([e]),this.count+=1;return}let{bucketIndex:t,localIndex:r}=this.locate(e,"right");this.buckets[t].splice(r,0,e),this.count+=1,this.maybeSplit(t);}set(e){if(this.buckets.length===0){this.buckets.push([e]),this.count+=1;return}let{bucketIndex:t,localIndex:r}=this.locate(e,"left"),n=this.buckets[t];if(r<n.length&&this.comparator(n[r],e)===0){n[r]=e;return}n.splice(r,0,e),this.count+=1,this.maybeSplit(t);}remove(e){return this.removeBy(t=>this.comparator(t,e))}removeBy(e){if(this.buckets.length===0)return false;let{bucketIndex:t,localIndex:r}=this.locateBy(e,"left"),n=this.buckets[t];return r>=n.length||e(n[r])!==0?false:(n.splice(r,1),this.count-=1,this.maybeMerge(t),true)}discard(e){this.remove(e);}pop(e){if(this.count===0)throw new RangeError("SortedList#pop: list is empty");let t=e===void 0?this.count-1:this.resolveIndex(e),r=this.locatePosition(t);if(!r)throw new RangeError(`SortedList#pop: index ${e} is out of range`);let n=this.buckets[r.bucketIndex],[o]=n.splice(r.localIndex,1);return this.count-=1,this.maybeMerge(r.bucketIndex),o}at(e){let t=this.locatePosition(this.resolveIndex(e));if(t)return this.buckets[t.bucketIndex][t.localIndex]}indexOf(e){if(this.buckets.length===0)return -1;let{bucketIndex:t,localIndex:r}=this.locate(e,"left"),n=this.buckets[t];return r>=n.length||this.comparator(n[r],e)!==0?-1:this.globalIndex(t,r)}has(e){return this.hasBy(t=>this.comparator(t,e))}hasBy(e){return this.findBy(e)!==void 0}findBy(e){if(this.buckets.length===0)return;let{bucketIndex:t,localIndex:r}=this.locateBy(e,"left"),n=this.buckets[t];return r<n.length&&e(n[r])===0?n[r]:void 0}bisectLeft(e){if(this.buckets.length===0)return 0;let{bucketIndex:t,localIndex:r}=this.locate(e,"left");return this.globalIndex(t,r)}bisectRight(e){if(this.buckets.length===0)return 0;let{bucketIndex:t,localIndex:r}=this.locate(e,"right");return this.globalIndex(t,r)}irange(e,t,r){if(this.buckets.length===0)return this.iterateRange({bucketIndex:0,localIndex:0});let[n,o]=r?.inclusive??[true,true],a=e===void 0?{bucketIndex:0,localIndex:0}:this.locate(e,n?"left":"right"),i=t===void 0?void 0:this.locate(t,o?"right":"left");return this.iterateRange(a,i)}islice(e,t){let r=Math.max(0,e===void 0?0:this.resolveIndex(e)),n=Math.min(this.count,t===void 0?this.count:this.resolveIndex(t));if(r>=n||this.count===0)return this.iterateRange({bucketIndex:0,localIndex:0},{bucketIndex:0,localIndex:0});let o=this.locatePosition(r),a=this.locatePosition(n-1);return this.iterateRange(o,{bucketIndex:a.bucketIndex,localIndex:a.localIndex+1})}get length(){return this.count}clear(){this.buckets=[],this.count=0;}[Symbol.iterator](){return this.iterateRange({bucketIndex:0,localIndex:0})}};c.MIN_BUCKET_SIZE=32,c.isDevelopment=typeof process<"u"&&process.env?.NODE_ENV!=="production";var u=c;function m(s,e){if(typeof s=="number"&&typeof e=="number")return s-e;let t=String(s),r=String(e);return t<r?-1:t>r?1:0}var d=class s{constructor(e,...t){let n=t[0]?.comparator??m,o=e?this.prepareSorted(e,n):[];this.engine=u.fromSorted(o,n);}prepareSorted(e,t){return Array.from(e).sort(t)}static from(e,...t){return new s(e,...t)}comparatorArg(){return [{comparator:this.engine.comparator}]}add(e){this.engine.add(e);}update(e){for(let t of e)this.add(t);}remove(e){return this.engine.remove(e)}discard(e){this.engine.discard(e);}pop(e){return this.engine.pop(e)}at(e){return this.engine.at(e)}indexOf(e){return this.engine.indexOf(e)}has(e){return this.engine.has(e)}bisectLeft(e){return this.engine.bisectLeft(e)}bisectRight(e){return this.engine.bisectRight(e)}irange(e,t,r){return this.engine.irange(e,t,r)}islice(e,t){return this.engine.islice(e,t)}get length(){return this.engine.length}clear(){this.engine.clear();}clone(){return new s(this,...this.comparatorArg())}[Symbol.iterator](){return this.engine[Symbol.iterator]()}};var h=class s extends d{prepareSorted(e,t){let r=super.prepareSorted(e,t),n=[];for(let o of r)(n.length===0||t(n[n.length-1],o)!==0)&&n.push(o);return n}static from(e,...t){return new s(e,...t)}add(e){this.has(e)||super.add(e);}clone(){return new s(this,...this.comparatorArg())}union(e){let t=this.clone();for(let r of e)t.add(r);return t}intersection(e){let t=new s([],...this.comparatorArg());for(let r of this)e.has(r)&&t.add(r);return t}difference(e){let t=new s([],...this.comparatorArg());for(let r of this)e.has(r)||t.add(r);return t}isSubsetOf(e){for(let t of this)if(!e.has(t))return false;return true}};function f(s,e){if(typeof s=="number"&&typeof e=="number")return s-e;let t=String(s),r=String(e);return t<r?-1:t>r?1:0}function g(s){return [{comparator:s}]}function T(s,e){let t=[];for(let r of s)t.length>0&&e(t[t.length-1],r)===0?t[t.length-1]=r:t.push(r);return t}var p=class s{constructor(e,...t){let r=t[0];this.keyComparator=r?.comparator??f;let n=(i,l)=>this.keyComparator(i[0],l[0]),o=e?Array.from(e).sort(n):[],a=T(o,n);this.engine=u.fromSorted(a,n);}static from(e,...t){return new s(e,...t)}set(e,t){this.engine.set([e,t]);}get(e){return this.engine.findBy(t=>this.keyComparator(t[0],e))?.[1]}delete(e){return this.engine.removeBy(t=>this.keyComparator(t[0],e))}has(e){return this.engine.hasBy(t=>this.keyComparator(t[0],e))}keys(){return new h(this.keysGenerator(),...g(this.keyComparator))}*keysGenerator(){for(let[e]of this.engine)yield e;}*values(){for(let[,e]of this.engine)yield e;}entries(){return this.engine[Symbol.iterator]()}irange(e,t){let r=e===void 0?void 0:[e,void 0],n=t===void 0?void 0:[t,void 0];return this.engine.irange(r,n)}at(e){return this.engine.at(e)}get size(){return this.engine.length}clear(){this.engine.clear();}[Symbol.iterator](){return this.engine[Symbol.iterator]()}};exports.SortedList=d;exports.SortedMap=p;exports.SortedSet=h;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/bucket-engine.ts","../src/sorted-list.ts","../src/sorted-set.ts","../src/sorted-map.ts"],"names":["bisectByCompare","length","getCandidate","compare","bias","lo","hi","mid","cmp","_BucketEngine","comparator","bucketIndex","bucket","target","right","neighborIndex","a","b","merged","i","clampedBucketIndex","localIndex","value","candidate","index","remaining","total","start","end","from","to","resolved","location","min","max","options","minInclusive","maxInclusive","resolvedStart","resolvedEnd","startLoc","endLoc","BucketEngine","defaultComparator","left","SortedList","_SortedList","iterable","SortedSet","_SortedSet","other","result","defaultKeyComparator","comparatorArgs","SortedMap","entries","opts","entryComparator","key","entry","minKey","maxKey"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Comparator } from '../types.js';\n\ntype Bias = 'left' | 'right';\n\n/**\n * Generic binary search over `length` candidates. `compare(candidate)` must\n * return the same sign a comparator would for `comparator(candidate, target)`\n * — i.e. negative if the candidate sorts before the (implicit) target.\n * Taking a closure instead of `(target, comparator)` lets callers search by\n * a bare key without constructing a throwaway full element to compare against.\n */\nfunction bisectByCompare<T>(\n length: number,\n getCandidate: (index: number) => T,\n compare: (candidate: T) => number,\n bias: Bias,\n): number {\n let lo = 0;\n let hi = length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const cmp = compare(getCandidate(mid));\n const goLeft = bias === 'left' ? cmp >= 0 : cmp > 0;\n if (goLeft) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return lo;\n}\n\ninterface BucketLocation {\n bucketIndex: number;\n localIndex: number;\n}\n\n/**\n * Internal \"list of lists\" (sqrt-decomposition) engine shared by `SortedList`\n * and `SortedMap` — not part of the public API.\n *\n * Buckets of roughly √n sorted elements each, the same technique used by\n * Python's `sortedcontainers`. Locating a bucket by value is a binary search\n * over bucket boundaries (O(log buckets)); locating by position walks bucket\n * lengths (O(buckets)). With bucket count kept close to √n, that's O(log n)\n * and O(√n) respectively.\n *\n * `SortedMap` uses the `*By` methods directly (with a closure that compares\n * a stored `[K, V]` entry against a bare key) instead of `SortedList`'s\n * public wrapper: going through `bisectLeft` + `at` would pay for a\n * positional index (O(√n)) it doesn't need, and comparing via a search value\n * would need a throwaway `[key, undefined]` tuple and double key-unwrapping\n * per comparison instead of one.\n */\nexport class BucketEngine<T> implements Iterable<T> {\n private static readonly MIN_BUCKET_SIZE = 32;\n\n private buckets: T[][] = [];\n private count = 0;\n readonly comparator: Comparator<T>;\n\n constructor(comparator: Comparator<T>) {\n this.comparator = comparator;\n }\n\n private targetBucketSize(): number {\n return Math.max(BucketEngine.MIN_BUCKET_SIZE, Math.ceil(Math.sqrt(this.count)));\n }\n\n private maybeSplit(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n const target = this.targetBucketSize();\n if (bucket.length > target * 2) {\n const mid = bucket.length >>> 1;\n const right = bucket.splice(mid);\n this.buckets.splice(bucketIndex + 1, 0, right);\n }\n }\n\n private maybeMerge(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n if (bucket.length === 0) {\n this.buckets.splice(bucketIndex, 1);\n return;\n }\n if (this.buckets.length <= 1) {\n return;\n }\n const target = this.targetBucketSize();\n if (bucket.length < target / 2) {\n const neighborIndex = bucketIndex > 0 ? bucketIndex - 1 : bucketIndex + 1;\n const [a, b] =\n bucketIndex < neighborIndex ? [bucketIndex, neighborIndex] : [neighborIndex, bucketIndex];\n const merged = this.buckets[a]!.concat(this.buckets[b]!);\n this.buckets.splice(a, 2, merged);\n this.maybeSplit(a);\n }\n }\n\n /** Lookup by an arbitrary comparison closure: which (bucket, local index) does it point to? O(log n). Callers must ensure buckets is non-empty. */\n private locateBy(compare: (candidate: T) => number, bias: Bias): BucketLocation {\n const bucketIndex = bisectByCompare(\n this.buckets.length,\n (i) => {\n const bucket = this.buckets[i]!;\n return bucket[bucket.length - 1]!;\n },\n compare,\n bias,\n );\n const clampedBucketIndex = Math.min(bucketIndex, this.buckets.length - 1);\n const bucket = this.buckets[clampedBucketIndex]!;\n const localIndex = bisectByCompare(bucket.length, (i) => bucket[i]!, compare, bias);\n return { bucketIndex: clampedBucketIndex, localIndex };\n }\n\n /** Value-based lookup: which (bucket, local index) does `value` belong at? O(log n). Callers must ensure buckets is non-empty. */\n private locate(value: T, bias: Bias): BucketLocation {\n return this.locateBy((candidate) => this.comparator(candidate, value), bias);\n }\n\n /** Position-based lookup: which (bucket, local index) is global index `index` at? O(√n). */\n private locatePosition(index: number): BucketLocation | undefined {\n if (index < 0 || index >= this.count) {\n return undefined;\n }\n let remaining = index;\n for (let i = 0; i < this.buckets.length; i++) {\n const bucket = this.buckets[i]!;\n if (remaining < bucket.length) {\n return { bucketIndex: i, localIndex: remaining };\n }\n remaining -= bucket.length;\n }\n /* v8 ignore next -- unreachable unless `count` desyncs from `buckets`, which would be an internal bug */\n throw new Error('BucketEngine: internal invariant violated (count out of sync with buckets)');\n }\n\n /** Inverse of {@link locatePosition}: sums preceding bucket lengths. O(√n). */\n private globalIndex(bucketIndex: number, localIndex: number): number {\n let total = localIndex;\n for (let i = 0; i < bucketIndex; i++) {\n total += this.buckets[i]!.length;\n }\n return total;\n }\n\n private resolveIndex(index: number): number {\n return index < 0 ? this.count + index : index;\n }\n\n private *iterateRange(start: BucketLocation, end?: BucketLocation): Generator<T> {\n for (let bucketIndex = start.bucketIndex; bucketIndex < this.buckets.length; bucketIndex++) {\n if (end && bucketIndex > end.bucketIndex) {\n return;\n }\n const bucket = this.buckets[bucketIndex]!;\n const from = bucketIndex === start.bucketIndex ? start.localIndex : 0;\n const to = end && bucketIndex === end.bucketIndex ? end.localIndex : bucket.length;\n for (let i = from; i < to; i++) {\n yield bucket[i]!;\n }\n }\n }\n\n /** O(√n) amortized: locates the target bucket and splices the value in, splitting oversized buckets. */\n add(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n this.buckets[bucketIndex]!.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n /**\n * Replaces the stored element equal to `value` (by comparator) in place, or\n * inserts it if absent. O(log n) to locate; O(1) to replace in place, or\n * O(√n) amortized to insert. This is what backs `SortedMap#set` — cheaper\n * than a separate find-then-remove-then-add round trip.\n */\n set(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex < bucket.length && this.comparator(bucket[localIndex]!, value) === 0) {\n bucket[localIndex] = value;\n return;\n }\n bucket.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n remove(value: T): boolean {\n return this.removeBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link remove}, via an arbitrary comparison closure instead of a full value. */\n removeBy(compare: (candidate: T) => number): boolean {\n if (this.buckets.length === 0) {\n return false;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || compare(bucket[localIndex]!) !== 0) {\n return false;\n }\n bucket.splice(localIndex, 1);\n this.count -= 1;\n this.maybeMerge(bucketIndex);\n return true;\n }\n\n discard(value: T): void {\n this.remove(value);\n }\n\n pop(index?: number): T {\n if (this.count === 0) {\n throw new RangeError('SortedList#pop: list is empty');\n }\n const resolved = index === undefined ? this.count - 1 : this.resolveIndex(index);\n const location = this.locatePosition(resolved);\n if (!location) {\n throw new RangeError(`SortedList#pop: index ${index} is out of range`);\n }\n const bucket = this.buckets[location.bucketIndex]!;\n const [value] = bucket.splice(location.localIndex, 1);\n this.count -= 1;\n this.maybeMerge(location.bucketIndex);\n return value as T;\n }\n\n /** O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end). */\n at(index: number): T | undefined {\n const location = this.locatePosition(this.resolveIndex(index));\n if (!location) {\n return undefined;\n }\n return this.buckets[location.bucketIndex]![location.localIndex];\n }\n\n indexOf(value: T): number {\n if (this.buckets.length === 0) {\n return -1;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || this.comparator(bucket[localIndex]!, value) !== 0) {\n return -1;\n }\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n): binary search for the bucket, then binary search within it. */\n has(value: T): boolean {\n return this.hasBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link has}, via an arbitrary comparison closure instead of a full value. */\n hasBy(compare: (candidate: T) => number): boolean {\n return this.findBy(compare) !== undefined;\n }\n\n /** Same O(log n) path as {@link has}, but returns the actual stored element instead of a boolean. */\n findBy(compare: (candidate: T) => number): T | undefined {\n if (this.buckets.length === 0) {\n return undefined;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n return localIndex < bucket.length && compare(bucket[localIndex]!) === 0\n ? bucket[localIndex]\n : undefined;\n }\n\n bisectLeft(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n bisectRight(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n) to locate both bounds by value + O(k) to iterate the k results. */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n if (this.buckets.length === 0) {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n const [minInclusive, maxInclusive] = options?.inclusive ?? [true, true];\n const start =\n min === undefined\n ? { bucketIndex: 0, localIndex: 0 }\n : this.locate(min, minInclusive ? 'left' : 'right');\n const end = max === undefined ? undefined : this.locate(max, maxInclusive ? 'right' : 'left');\n return this.iterateRange(start, end);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n * (Slightly worse than the O(log n) originally targeted for this method —\n * positional lookup fundamentally needs a bucket-length walk without a\n * Fenwick index. Confirmed empirically via `npm run bench`.)\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n const resolvedStart = Math.max(0, start === undefined ? 0 : this.resolveIndex(start));\n const resolvedEnd = Math.min(\n this.count,\n end === undefined ? this.count : this.resolveIndex(end),\n );\n if (resolvedStart >= resolvedEnd || this.count === 0) {\n return this.iterateRange(\n { bucketIndex: 0, localIndex: 0 },\n { bucketIndex: 0, localIndex: 0 },\n );\n }\n const startLoc = this.locatePosition(resolvedStart)!;\n const endLoc = this.locatePosition(resolvedEnd - 1)!;\n return this.iterateRange(startLoc, {\n bucketIndex: endLoc.bucketIndex,\n localIndex: endLoc.localIndex + 1,\n });\n }\n\n get length(): number {\n return this.count;\n }\n\n clear(): void {\n this.buckets = [];\n this.count = 0;\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultComparator<T>(a: T, b: T): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\n/**\n * A list that keeps its elements in sorted order as they're inserted.\n *\n * A thin public wrapper around the internal {@link BucketEngine} — see there\n * for the actual \"list of lists\" (sqrt-decomposition) implementation and its\n * complexity notes.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([42, 7, 99]);\n * scores.add(15);\n * [...scores]; // [7, 15, 42, 99]\n * ```\n */\nexport class SortedList<T> implements Iterable<T> {\n private readonly engine: BucketEngine<T>;\n\n /**\n * @example\n * ```ts\n * new SortedList<number>(); // empty\n * new SortedList<number>([3, 1, 2]); // [1, 2, 3]\n * new SortedList<Person>([...], { comparator: (a, b) => a.age - b.age });\n * ```\n */\n constructor(iterable?: Iterable<T>, ...options: ComparatorArg<T>) {\n const opts = options[0] as SortedOptions<T> | undefined;\n const comparator = opts?.comparator ?? (defaultComparator as Comparator<T>);\n this.engine = new BucketEngine<T>(comparator);\n // Goes through `this.update` -> `this.add` (not the engine's) so that a\n // SortedSet's overridden, deduping `add` applies during construction too.\n if (iterable) {\n this.update(iterable);\n }\n }\n\n /** Safe to call from subclasses/clone: both `ComparatorArg<T>` branches accept `{ comparator }`. */\n protected comparatorArg(): ComparatorArg<T> {\n return [{ comparator: this.engine.comparator }] as unknown as ComparatorArg<T>;\n }\n\n /**\n * O(√n) amortized.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>();\n * scores.add(42);\n * scores.add(7);\n * [...scores]; // [7, 42]\n * ```\n */\n add(value: T): void {\n this.engine.add(value);\n }\n\n /**\n * Bulk-inserts every value from `iterable`, one {@link add} at a time.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1]);\n * scores.update([2, 5, 4]);\n * [...scores]; // [1, 2, 3, 4, 5]\n * ```\n */\n update(iterable: Iterable<T>): void {\n for (const value of iterable) {\n this.add(value);\n }\n }\n\n /**\n * Removes the first occurrence of `value`. Returns `false` if it wasn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 2, 3]);\n * scores.remove(2); // true — removes one occurrence\n * scores.remove(99); // false — not present\n * ```\n */\n remove(value: T): boolean {\n return this.engine.remove(value);\n }\n\n /**\n * Like {@link remove}, but never throws (or returns anything) if `value` isn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.discard(99); // no-op, no error\n * ```\n */\n discard(value: T): void {\n this.engine.discard(value);\n }\n\n /**\n * Removes and returns the element at `index` (default: the last element).\n * Negative indices count from the end, same as {@link at}.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.pop(); // 30 — last element\n * scores.pop(0); // 10 — first element\n * ```\n */\n pop(index?: number): T {\n return this.engine.pop(index);\n }\n\n /**\n * O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end).\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.at(0); // 10\n * scores.at(-1); // 30 — same as Array.prototype.at\n * scores.at(99); // undefined — out of range\n * ```\n */\n at(index: number): T | undefined {\n return this.engine.at(index);\n }\n\n /**\n * The index of the first occurrence of `value`, or `-1` if absent.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 3]).indexOf(2); // 1\n * new SortedList<number>([1, 2, 3]).indexOf(99); // -1\n * ```\n */\n indexOf(value: T): number {\n return this.engine.indexOf(value);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.has(2); // true\n * scores.has(99); // false\n * ```\n */\n has(value: T): boolean {\n return this.engine.has(value);\n }\n\n /**\n * The leftmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectLeft(2); // 1\n * ```\n */\n bisectLeft(value: T): number {\n return this.engine.bisectLeft(value);\n }\n\n /**\n * The rightmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectRight(2); // 4\n * ```\n */\n bisectRight(value: T): number {\n return this.engine.bisectRight(value);\n }\n\n /**\n * O(log n) to locate both bounds by value + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3, 4, 5]);\n * [...scores.irange(2, 4)]; // [2, 3, 4] — inclusive by default\n * [...scores.irange(2, 4, { inclusive: [false, true] })]; // [3, 4]\n * ```\n */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n return this.engine.irange(min, max, options);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30, 40, 50]);\n * [...scores.islice(1, 4)]; // [20, 30, 40] — like Array.prototype.slice\n * ```\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n return this.engine.islice(start, end);\n }\n\n /**\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 3]).length; // 3\n * ```\n */\n get length(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.clear();\n * scores.length; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * An independent copy — mutating the clone never affects the original.\n *\n * @example\n * ```ts\n * const original = new SortedList<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * copy.length; // 4\n * ```\n */\n clone(): SortedList<T> {\n return new SortedList<T>(this, ...this.comparatorArg());\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1, 2]);\n * for (const value of scores) console.log(value); // 1, 2, 3\n * ```\n */\n [Symbol.iterator](): IterableIterator<T> {\n return this.engine[Symbol.iterator]();\n }\n}\n","import { SortedList } from './sorted-list.js';\n\n/**\n * Like {@link SortedList}, but rejects duplicates (compared via the\n * comparator, not reference identity). Adds set-theory operations.\n *\n * Reuses `SortedList`'s bucket structure entirely: the only behavioral\n * difference is that `add` is a no-op for values already present.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['b', 'a', 'c', 'a']);\n * [...tags]; // ['a', 'b', 'c'] — the duplicate 'a' was dropped\n * ```\n */\nexport class SortedSet<T> extends SortedList<T> {\n /**\n * O(log n) `has` check + O(√n) amortized insert if the value is new.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['a']);\n * tags.add('a'); // no-op, already present\n * tags.length; // 1\n * ```\n */\n override add(value: T): void {\n if (!this.has(value)) {\n super.add(value);\n }\n }\n\n /**\n * @example\n * ```ts\n * const original = new SortedSet<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * ```\n */\n override clone(): SortedSet<T> {\n return new SortedSet<T>(this, ...this.comparatorArg());\n }\n\n /**\n * O(m log n + m) for a set of size m being merged in.\n *\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([3, 4]);\n * [...a.union(b)]; // [1, 2, 3, 4]\n * ```\n */\n union(other: SortedSet<T>): SortedSet<T> {\n const result = this.clone();\n for (const value of other) {\n result.add(value);\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3, 4]);\n * [...a.intersection(b)]; // [2, 3]\n * ```\n */\n intersection(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3]);\n * [...a.difference(b)]; // [1] — in a, not in b\n * ```\n */\n difference(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (!other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * new SortedSet<number>([2, 3]).isSubsetOf(new SortedSet<number>([1, 2, 3, 4])); // true\n * new SortedSet<number>([1, 5]).isSubsetOf(new SortedSet<number>([1, 2, 3])); // false\n * ```\n */\n isSubsetOf(other: SortedSet<T>): boolean {\n for (const value of this) {\n if (!other.has(value)) {\n return false;\n }\n }\n return true;\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport { SortedSet } from './sorted-set.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultKeyComparator<K>(a: K, b: K): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction comparatorArgs<T>(comparator: Comparator<T>): ComparatorArg<T> {\n return [{ comparator }] as unknown as ComparatorArg<T>;\n}\n\n/**\n * A dictionary ordered by key.\n *\n * Uses the internal {@link BucketEngine} directly (on `[K, V]` tuples, with a\n * comparator that only looks at the key) rather than composing over\n * `SortedList`'s public API. Two reasons: `set` needs the engine's O(log n)\n * in-place replace-or-insert (`SortedList#bisectLeft` + `#at` would pay for a\n * positional index it doesn't need), and `get`/`has`/`delete` use the `*By`\n * lookup methods with a closure over the bare key — that compares the key\n * only once per candidate (not twice, since the search side needs no\n * `entry[0]` unwrapping) and avoids allocating a throwaway `[key, undefined]`\n * search tuple per call.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1'], [99.75, 'order-2']]);\n * [...byPrice.keys()]; // [99.75, 101.5]\n * ```\n */\nexport class SortedMap<K, V> implements Iterable<[K, V]> {\n private readonly engine: BucketEngine<[K, V]>;\n private readonly keyComparator: Comparator<K>;\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>(); // empty\n * new SortedMap<number, string>([[2, 'b'], [1, 'a']]); // ordered by key: 1, 2\n * ```\n */\n constructor(entries?: Iterable<[K, V]>, ...options: ComparatorArg<K>) {\n const opts = options[0] as SortedOptions<K> | undefined;\n this.keyComparator = opts?.comparator ?? (defaultKeyComparator as Comparator<K>);\n const entryComparator: Comparator<[K, V]> = (a, b) => this.keyComparator(a[0], b[0]);\n this.engine = new BucketEngine<[K, V]>(entryComparator);\n if (entries) {\n for (const [key, value] of entries) {\n this.set(key, value);\n }\n }\n }\n\n /**\n * O(log n) to locate + O(1) to replace in place, or O(√n) amortized to insert.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>();\n * byPrice.set(101.5, 'order-1');\n * byPrice.set(101.5, 'order-1-updated'); // overwrites, doesn't grow size\n * ```\n */\n set(key: K, value: V): void {\n this.engine.set([key, value]);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.get(101.5); // 'order-1'\n * byPrice.get(1); // undefined\n * ```\n */\n get(key: K): V | undefined {\n return this.engine.findBy((entry) => this.keyComparator(entry[0], key))?.[1];\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.delete(101.5); // true\n * byPrice.delete(101.5); // false — already gone\n * ```\n */\n delete(key: K): boolean {\n return this.engine.removeBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a']]).has(1); // true\n * ```\n */\n has(key: K): boolean {\n return this.engine.hasBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * A snapshot `SortedSet` of the current keys — not a live view.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * [...byPrice.keys()]; // [1, 2]\n * ```\n */\n keys(): SortedSet<K> {\n return new SortedSet<K>(this.keysGenerator(), ...comparatorArgs(this.keyComparator));\n }\n\n private *keysGenerator(): Generator<K> {\n for (const [key] of this.engine) {\n yield key;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).values()]; // ['a', 'b']\n * ```\n */\n *values(): IterableIterator<V> {\n for (const [, value] of this.engine) {\n yield value;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).entries()]; // [[1, 'a'], [2, 'b']]\n * ```\n */\n entries(): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n\n /**\n * Iterates `[key, value]` pairs with keys in `[minKey, maxKey]`.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[95, 'a'], [100, 'b'], [105, 'c']]);\n * [...byPrice.irange(95, 100)]; // [[95, 'a'], [100, 'b']]\n * ```\n */\n irange(minKey?: K, maxKey?: K): IterableIterator<[K, V]> {\n const min = minKey === undefined ? undefined : ([minKey, undefined as unknown as V] as [K, V]);\n const max = maxKey === undefined ? undefined : ([maxKey, undefined as unknown as V] as [K, V]);\n return this.engine.irange(min, max);\n }\n\n /**\n * O(√n). Entry at ordinal position `index` in key order.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * byPrice.at(0); // [1, 'a']\n * ```\n */\n at(index: number): [K, V] | undefined {\n return this.engine.at(index);\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a'], [2, 'b']]).size; // 2\n * ```\n */\n get size(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[1, 'a']]);\n * byPrice.clear();\n * byPrice.size; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * @example\n * ```ts\n * for (const [key, value] of new SortedMap([[2, 'b'], [1, 'a']])) {\n * console.log(key, value); // 1 'a', then 2 'b'\n * }\n * ```\n */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/bucket-engine.ts","../src/sorted-list.ts","../src/sorted-set.ts","../src/sorted-map.ts"],"names":["bisectByCompare","length","getCandidate","compare","bias","lo","hi","mid","cmp","_BucketEngine","comparator","count","sortedArray","engine","target","buckets","bucketIndex","bucket","right","neighborIndex","a","b","merged","clampedBucketIndex","localIndex","value","candidate","index","remaining","i","total","start","end","from","to","resolved","location","min","max","options","minInclusive","maxInclusive","resolvedStart","resolvedEnd","startLoc","endLoc","BucketEngine","defaultComparator","left","SortedList","_SortedList","iterable","sorted","SortedSet","_SortedSet","deduped","other","result","defaultKeyComparator","comparatorArgs","dedupeKeepingLast","SortedMap","_SortedMap","entries","opts","entryComparator","key","entry","minKey","maxKey"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Comparator } from '../types.js';\n\ntype Bias = 'left' | 'right';\n\n/**\n * Generic binary search over `length` candidates. `compare(candidate)` must\n * return the same sign a comparator would for `comparator(candidate, target)`\n * — i.e. negative if the candidate sorts before the (implicit) target.\n * Taking a closure instead of `(target, comparator)` lets callers search by\n * a bare key without constructing a throwaway full element to compare against.\n */\nfunction bisectByCompare<T>(\n length: number,\n getCandidate: (index: number) => T,\n compare: (candidate: T) => number,\n bias: Bias,\n): number {\n let lo = 0;\n let hi = length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const cmp = compare(getCandidate(mid));\n const goLeft = bias === 'left' ? cmp >= 0 : cmp > 0;\n if (goLeft) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return lo;\n}\n\ninterface BucketLocation {\n bucketIndex: number;\n localIndex: number;\n}\n\n/**\n * Internal \"list of lists\" (sqrt-decomposition) engine shared by `SortedList`\n * and `SortedMap` — not part of the public API.\n *\n * Buckets of roughly √n sorted elements each, the same technique used by\n * Python's `sortedcontainers`. Locating a bucket by value is a binary search\n * over bucket boundaries (O(log buckets)); locating by position walks bucket\n * lengths (O(buckets)). With bucket count kept close to √n, that's O(log n)\n * and O(√n) respectively.\n *\n * `SortedMap` uses the `*By` methods directly (with a closure that compares\n * a stored `[K, V]` entry against a bare key) instead of `SortedList`'s\n * public wrapper: going through `bisectLeft` + `at` would pay for a\n * positional index (O(√n)) it doesn't need, and comparing via a search value\n * would need a throwaway `[key, undefined]` tuple and double key-unwrapping\n * per comparison instead of one.\n */\nexport class BucketEngine<T> implements Iterable<T> {\n private static readonly MIN_BUCKET_SIZE = 32;\n\n /**\n * Guards the O(n) sortedness check in {@link fromSorted}. `typeof process`\n * keeps this safe to evaluate in a plain browser (no bundler define step)\n * where `process` doesn't exist at runtime.\n */\n private static readonly isDevelopment =\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n private buckets: T[][] = [];\n private count = 0;\n readonly comparator: Comparator<T>;\n\n constructor(comparator: Comparator<T>) {\n this.comparator = comparator;\n }\n\n private static targetBucketSizeFor(count: number): number {\n return Math.max(BucketEngine.MIN_BUCKET_SIZE, Math.ceil(Math.sqrt(count)));\n }\n\n private targetBucketSize(): number {\n return BucketEngine.targetBucketSizeFor(this.count);\n }\n\n /**\n * Builds an engine directly from an array the caller guarantees is already\n * sorted per `comparator` — skips the O(√n)-amortized-per-element `add()`\n * path used by incremental construction in favor of one O(n) pass that\n * slices straight into buckets sized for the final count.\n *\n * Internal-only: the precondition (sortedness) is the caller's\n * responsibility. In non-production builds it's cheaply verified in O(n);\n * that check is skipped in production since it doubles comparator calls\n * for no benefit once the caller is trusted.\n */\n static fromSorted<T>(sortedArray: readonly T[], comparator: Comparator<T>): BucketEngine<T> {\n const engine = new BucketEngine<T>(comparator);\n const n = sortedArray.length;\n if (n === 0) {\n return engine;\n }\n if (BucketEngine.isDevelopment) {\n for (let i = 1; i < n; i++) {\n if (comparator(sortedArray[i - 1] as T, sortedArray[i] as T) > 0) {\n throw new Error('BucketEngine.fromSorted: input array is not sorted per comparator');\n }\n }\n }\n const target = BucketEngine.targetBucketSizeFor(n);\n const buckets: T[][] = [];\n for (let i = 0; i < n; i += target) {\n buckets.push(sortedArray.slice(i, i + target));\n }\n engine.buckets = buckets;\n engine.count = n;\n return engine;\n }\n\n private maybeSplit(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n const target = this.targetBucketSize();\n if (bucket.length > target * 2) {\n const mid = bucket.length >>> 1;\n const right = bucket.splice(mid);\n this.buckets.splice(bucketIndex + 1, 0, right);\n }\n }\n\n private maybeMerge(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n if (bucket.length === 0) {\n this.buckets.splice(bucketIndex, 1);\n return;\n }\n if (this.buckets.length <= 1) {\n return;\n }\n const target = this.targetBucketSize();\n if (bucket.length < target / 2) {\n const neighborIndex = bucketIndex > 0 ? bucketIndex - 1 : bucketIndex + 1;\n const [a, b] =\n bucketIndex < neighborIndex ? [bucketIndex, neighborIndex] : [neighborIndex, bucketIndex];\n const merged = this.buckets[a]!.concat(this.buckets[b]!);\n this.buckets.splice(a, 2, merged);\n this.maybeSplit(a);\n }\n }\n\n /** Lookup by an arbitrary comparison closure: which (bucket, local index) does it point to? O(log n). Callers must ensure buckets is non-empty. */\n private locateBy(compare: (candidate: T) => number, bias: Bias): BucketLocation {\n const bucketIndex = bisectByCompare(\n this.buckets.length,\n (i) => {\n const bucket = this.buckets[i]!;\n return bucket[bucket.length - 1]!;\n },\n compare,\n bias,\n );\n const clampedBucketIndex = Math.min(bucketIndex, this.buckets.length - 1);\n const bucket = this.buckets[clampedBucketIndex]!;\n const localIndex = bisectByCompare(bucket.length, (i) => bucket[i]!, compare, bias);\n return { bucketIndex: clampedBucketIndex, localIndex };\n }\n\n /** Value-based lookup: which (bucket, local index) does `value` belong at? O(log n). Callers must ensure buckets is non-empty. */\n private locate(value: T, bias: Bias): BucketLocation {\n return this.locateBy((candidate) => this.comparator(candidate, value), bias);\n }\n\n /** Position-based lookup: which (bucket, local index) is global index `index` at? O(√n). */\n private locatePosition(index: number): BucketLocation | undefined {\n if (index < 0 || index >= this.count) {\n return undefined;\n }\n let remaining = index;\n for (let i = 0; i < this.buckets.length; i++) {\n const bucket = this.buckets[i]!;\n if (remaining < bucket.length) {\n return { bucketIndex: i, localIndex: remaining };\n }\n remaining -= bucket.length;\n }\n /* v8 ignore next -- unreachable unless `count` desyncs from `buckets`, which would be an internal bug */\n throw new Error('BucketEngine: internal invariant violated (count out of sync with buckets)');\n }\n\n /** Inverse of {@link locatePosition}: sums preceding bucket lengths. O(√n). */\n private globalIndex(bucketIndex: number, localIndex: number): number {\n let total = localIndex;\n for (let i = 0; i < bucketIndex; i++) {\n total += this.buckets[i]!.length;\n }\n return total;\n }\n\n private resolveIndex(index: number): number {\n return index < 0 ? this.count + index : index;\n }\n\n private *iterateRange(start: BucketLocation, end?: BucketLocation): Generator<T> {\n for (let bucketIndex = start.bucketIndex; bucketIndex < this.buckets.length; bucketIndex++) {\n if (end && bucketIndex > end.bucketIndex) {\n return;\n }\n const bucket = this.buckets[bucketIndex]!;\n const from = bucketIndex === start.bucketIndex ? start.localIndex : 0;\n const to = end && bucketIndex === end.bucketIndex ? end.localIndex : bucket.length;\n for (let i = from; i < to; i++) {\n yield bucket[i]!;\n }\n }\n }\n\n /** O(√n) amortized: locates the target bucket and splices the value in, splitting oversized buckets. */\n add(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n this.buckets[bucketIndex]!.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n /**\n * Replaces the stored element equal to `value` (by comparator) in place, or\n * inserts it if absent. O(log n) to locate; O(1) to replace in place, or\n * O(√n) amortized to insert. This is what backs `SortedMap#set` — cheaper\n * than a separate find-then-remove-then-add round trip.\n */\n set(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex < bucket.length && this.comparator(bucket[localIndex]!, value) === 0) {\n bucket[localIndex] = value;\n return;\n }\n bucket.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n remove(value: T): boolean {\n return this.removeBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link remove}, via an arbitrary comparison closure instead of a full value. */\n removeBy(compare: (candidate: T) => number): boolean {\n if (this.buckets.length === 0) {\n return false;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || compare(bucket[localIndex]!) !== 0) {\n return false;\n }\n bucket.splice(localIndex, 1);\n this.count -= 1;\n this.maybeMerge(bucketIndex);\n return true;\n }\n\n discard(value: T): void {\n this.remove(value);\n }\n\n pop(index?: number): T {\n if (this.count === 0) {\n throw new RangeError('SortedList#pop: list is empty');\n }\n const resolved = index === undefined ? this.count - 1 : this.resolveIndex(index);\n const location = this.locatePosition(resolved);\n if (!location) {\n throw new RangeError(`SortedList#pop: index ${index} is out of range`);\n }\n const bucket = this.buckets[location.bucketIndex]!;\n const [value] = bucket.splice(location.localIndex, 1);\n this.count -= 1;\n this.maybeMerge(location.bucketIndex);\n return value as T;\n }\n\n /** O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end). */\n at(index: number): T | undefined {\n const location = this.locatePosition(this.resolveIndex(index));\n if (!location) {\n return undefined;\n }\n return this.buckets[location.bucketIndex]![location.localIndex];\n }\n\n indexOf(value: T): number {\n if (this.buckets.length === 0) {\n return -1;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || this.comparator(bucket[localIndex]!, value) !== 0) {\n return -1;\n }\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n): binary search for the bucket, then binary search within it. */\n has(value: T): boolean {\n return this.hasBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link has}, via an arbitrary comparison closure instead of a full value. */\n hasBy(compare: (candidate: T) => number): boolean {\n return this.findBy(compare) !== undefined;\n }\n\n /** Same O(log n) path as {@link has}, but returns the actual stored element instead of a boolean. */\n findBy(compare: (candidate: T) => number): T | undefined {\n if (this.buckets.length === 0) {\n return undefined;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n return localIndex < bucket.length && compare(bucket[localIndex]!) === 0\n ? bucket[localIndex]\n : undefined;\n }\n\n bisectLeft(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n bisectRight(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n) to locate both bounds by value + O(k) to iterate the k results. */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n if (this.buckets.length === 0) {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n const [minInclusive, maxInclusive] = options?.inclusive ?? [true, true];\n const start =\n min === undefined\n ? { bucketIndex: 0, localIndex: 0 }\n : this.locate(min, minInclusive ? 'left' : 'right');\n const end = max === undefined ? undefined : this.locate(max, maxInclusive ? 'right' : 'left');\n return this.iterateRange(start, end);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n * (Slightly worse than the O(log n) originally targeted for this method —\n * positional lookup fundamentally needs a bucket-length walk without a\n * Fenwick index. Confirmed empirically via `npm run bench`.)\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n const resolvedStart = Math.max(0, start === undefined ? 0 : this.resolveIndex(start));\n const resolvedEnd = Math.min(\n this.count,\n end === undefined ? this.count : this.resolveIndex(end),\n );\n if (resolvedStart >= resolvedEnd || this.count === 0) {\n return this.iterateRange(\n { bucketIndex: 0, localIndex: 0 },\n { bucketIndex: 0, localIndex: 0 },\n );\n }\n const startLoc = this.locatePosition(resolvedStart)!;\n const endLoc = this.locatePosition(resolvedEnd - 1)!;\n return this.iterateRange(startLoc, {\n bucketIndex: endLoc.bucketIndex,\n localIndex: endLoc.localIndex + 1,\n });\n }\n\n get length(): number {\n return this.count;\n }\n\n clear(): void {\n this.buckets = [];\n this.count = 0;\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultComparator<T>(a: T, b: T): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\n/**\n * A list that keeps its elements in sorted order as they're inserted.\n *\n * A thin public wrapper around the internal {@link BucketEngine} — see there\n * for the actual \"list of lists\" (sqrt-decomposition) implementation and its\n * complexity notes.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([42, 7, 99]);\n * scores.add(15);\n * [...scores]; // [7, 15, 42, 99]\n * ```\n */\nexport class SortedList<T> implements Iterable<T> {\n private readonly engine: BucketEngine<T>;\n\n /**\n * @example\n * ```ts\n * new SortedList<number>(); // empty\n * new SortedList<number>([3, 1, 2]); // [1, 2, 3]\n * new SortedList<Person>([...], { comparator: (a, b) => a.age - b.age });\n * ```\n */\n constructor(iterable?: Iterable<T>, ...options: ComparatorArg<T>) {\n const opts = options[0] as SortedOptions<T> | undefined;\n const comparator = opts?.comparator ?? (defaultComparator as Comparator<T>);\n const sorted = iterable ? this.prepareSorted(iterable, comparator) : [];\n this.engine = BucketEngine.fromSorted(sorted, comparator);\n }\n\n /**\n * Materializes and sorts `iterable` for the constructor to cut into\n * buckets in one O(n) pass. A hook (not a field/engine access — `engine`\n * isn't assigned yet when this runs) so `SortedSet` can additionally\n * dedupe adjacent equal elements while still reusing this sort step.\n */\n protected prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[] {\n return Array.from(iterable).sort(comparator);\n }\n\n /**\n * A read-only iterable/array factory, paralleling `Array.from`.\n *\n * @example\n * ```ts\n * SortedList.from([3, 1, 2]); // same as new SortedList([3, 1, 2])\n * ```\n */\n static from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedList<T> {\n return new SortedList<T>(iterable, ...options);\n }\n\n /** Safe to call from subclasses/clone: both `ComparatorArg<T>` branches accept `{ comparator }`. */\n protected comparatorArg(): ComparatorArg<T> {\n return [{ comparator: this.engine.comparator }] as unknown as ComparatorArg<T>;\n }\n\n /**\n * O(√n) amortized.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>();\n * scores.add(42);\n * scores.add(7);\n * [...scores]; // [7, 42]\n * ```\n */\n add(value: T): void {\n this.engine.add(value);\n }\n\n /**\n * Bulk-inserts every value from `iterable`, one {@link add} at a time.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1]);\n * scores.update([2, 5, 4]);\n * [...scores]; // [1, 2, 3, 4, 5]\n * ```\n */\n update(iterable: Iterable<T>): void {\n for (const value of iterable) {\n this.add(value);\n }\n }\n\n /**\n * Removes the first occurrence of `value`. Returns `false` if it wasn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 2, 3]);\n * scores.remove(2); // true — removes one occurrence\n * scores.remove(99); // false — not present\n * ```\n */\n remove(value: T): boolean {\n return this.engine.remove(value);\n }\n\n /**\n * Like {@link remove}, but never throws (or returns anything) if `value` isn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.discard(99); // no-op, no error\n * ```\n */\n discard(value: T): void {\n this.engine.discard(value);\n }\n\n /**\n * Removes and returns the element at `index` (default: the last element).\n * Negative indices count from the end, same as {@link at}.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.pop(); // 30 — last element\n * scores.pop(0); // 10 — first element\n * ```\n */\n pop(index?: number): T {\n return this.engine.pop(index);\n }\n\n /**\n * O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end).\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.at(0); // 10\n * scores.at(-1); // 30 — same as Array.prototype.at\n * scores.at(99); // undefined — out of range\n * ```\n */\n at(index: number): T | undefined {\n return this.engine.at(index);\n }\n\n /**\n * The index of the first occurrence of `value`, or `-1` if absent.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 3]).indexOf(2); // 1\n * new SortedList<number>([1, 2, 3]).indexOf(99); // -1\n * ```\n */\n indexOf(value: T): number {\n return this.engine.indexOf(value);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.has(2); // true\n * scores.has(99); // false\n * ```\n */\n has(value: T): boolean {\n return this.engine.has(value);\n }\n\n /**\n * The leftmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectLeft(2); // 1\n * ```\n */\n bisectLeft(value: T): number {\n return this.engine.bisectLeft(value);\n }\n\n /**\n * The rightmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectRight(2); // 4\n * ```\n */\n bisectRight(value: T): number {\n return this.engine.bisectRight(value);\n }\n\n /**\n * O(log n) to locate both bounds by value + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3, 4, 5]);\n * [...scores.irange(2, 4)]; // [2, 3, 4] — inclusive by default\n * [...scores.irange(2, 4, { inclusive: [false, true] })]; // [3, 4]\n * ```\n */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n return this.engine.irange(min, max, options);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30, 40, 50]);\n * [...scores.islice(1, 4)]; // [20, 30, 40] — like Array.prototype.slice\n * ```\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n return this.engine.islice(start, end);\n }\n\n /**\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 3]).length; // 3\n * ```\n */\n get length(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.clear();\n * scores.length; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * An independent copy — mutating the clone never affects the original.\n *\n * @example\n * ```ts\n * const original = new SortedList<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * copy.length; // 4\n * ```\n */\n clone(): SortedList<T> {\n return new SortedList<T>(this, ...this.comparatorArg());\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1, 2]);\n * for (const value of scores) console.log(value); // 1, 2, 3\n * ```\n */\n [Symbol.iterator](): IterableIterator<T> {\n return this.engine[Symbol.iterator]();\n }\n}\n","import { SortedList } from './sorted-list.js';\nimport type { Comparator, ComparatorArg } from './types.js';\n\n/**\n * Like {@link SortedList}, but rejects duplicates (compared via the\n * comparator, not reference identity). Adds set-theory operations.\n *\n * Reuses `SortedList`'s bucket structure entirely: the only behavioral\n * difference is that `add` is a no-op for values already present.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['b', 'a', 'c', 'a']);\n * [...tags]; // ['a', 'b', 'c'] — the duplicate 'a' was dropped\n * ```\n */\nexport class SortedSet<T> extends SortedList<T> {\n /**\n * Dedupes adjacent equal elements (by comparator) after the base class's\n * sort, keeping the first occurrence — matching {@link add}'s no-op-if-\n * present semantics, which is what incremental construction produced\n * before bulk construction existed.\n */\n protected override prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[] {\n const sorted = super.prepareSorted(iterable, comparator);\n const deduped: T[] = [];\n for (const value of sorted) {\n if (deduped.length === 0 || comparator(deduped[deduped.length - 1] as T, value) !== 0) {\n deduped.push(value);\n }\n }\n return deduped;\n }\n\n /**\n * @example\n * ```ts\n * SortedSet.from([3, 1, 2, 1]); // same as new SortedSet([3, 1, 2, 1])\n * ```\n */\n static override from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedSet<T> {\n return new SortedSet<T>(iterable, ...options);\n }\n\n /**\n * O(log n) `has` check + O(√n) amortized insert if the value is new.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['a']);\n * tags.add('a'); // no-op, already present\n * tags.length; // 1\n * ```\n */\n override add(value: T): void {\n if (!this.has(value)) {\n super.add(value);\n }\n }\n\n /**\n * @example\n * ```ts\n * const original = new SortedSet<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * ```\n */\n override clone(): SortedSet<T> {\n return new SortedSet<T>(this, ...this.comparatorArg());\n }\n\n /**\n * O(m log n + m) for a set of size m being merged in.\n *\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([3, 4]);\n * [...a.union(b)]; // [1, 2, 3, 4]\n * ```\n */\n union(other: SortedSet<T>): SortedSet<T> {\n const result = this.clone();\n for (const value of other) {\n result.add(value);\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3, 4]);\n * [...a.intersection(b)]; // [2, 3]\n * ```\n */\n intersection(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3]);\n * [...a.difference(b)]; // [1] — in a, not in b\n * ```\n */\n difference(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (!other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * new SortedSet<number>([2, 3]).isSubsetOf(new SortedSet<number>([1, 2, 3, 4])); // true\n * new SortedSet<number>([1, 5]).isSubsetOf(new SortedSet<number>([1, 2, 3])); // false\n * ```\n */\n isSubsetOf(other: SortedSet<T>): boolean {\n for (const value of this) {\n if (!other.has(value)) {\n return false;\n }\n }\n return true;\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport { SortedSet } from './sorted-set.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultKeyComparator<K>(a: K, b: K): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction comparatorArgs<T>(comparator: Comparator<T>): ComparatorArg<T> {\n return [{ comparator }] as unknown as ComparatorArg<T>;\n}\n\n/** Collapses adjacent equal-key runs (by `comparator`) to their last element — same \"later wins\" semantics as `new Map()`. */\nfunction dedupeKeepingLast<T>(sorted: T[], comparator: Comparator<T>): T[] {\n const result: T[] = [];\n for (const value of sorted) {\n if (result.length > 0 && comparator(result[result.length - 1] as T, value) === 0) {\n result[result.length - 1] = value;\n } else {\n result.push(value);\n }\n }\n return result;\n}\n\n/**\n * A dictionary ordered by key.\n *\n * Uses the internal {@link BucketEngine} directly (on `[K, V]` tuples, with a\n * comparator that only looks at the key) rather than composing over\n * `SortedList`'s public API. Two reasons: `set` needs the engine's O(log n)\n * in-place replace-or-insert (`SortedList#bisectLeft` + `#at` would pay for a\n * positional index it doesn't need), and `get`/`has`/`delete` use the `*By`\n * lookup methods with a closure over the bare key — that compares the key\n * only once per candidate (not twice, since the search side needs no\n * `entry[0]` unwrapping) and avoids allocating a throwaway `[key, undefined]`\n * search tuple per call.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1'], [99.75, 'order-2']]);\n * [...byPrice.keys()]; // [99.75, 101.5]\n * ```\n */\nexport class SortedMap<K, V> implements Iterable<[K, V]> {\n private readonly engine: BucketEngine<[K, V]>;\n private readonly keyComparator: Comparator<K>;\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>(); // empty\n * new SortedMap<number, string>([[2, 'b'], [1, 'a']]); // ordered by key: 1, 2\n * ```\n */\n constructor(entries?: Iterable<[K, V]>, ...options: ComparatorArg<K>) {\n const opts = options[0] as SortedOptions<K> | undefined;\n this.keyComparator = opts?.comparator ?? (defaultKeyComparator as Comparator<K>);\n const entryComparator: Comparator<[K, V]> = (a, b) => this.keyComparator(a[0], b[0]);\n const sorted = entries ? Array.from(entries).sort(entryComparator) : [];\n const deduped = dedupeKeepingLast(sorted, entryComparator);\n this.engine = BucketEngine.fromSorted(deduped, entryComparator);\n }\n\n /**\n * @example\n * ```ts\n * SortedMap.from([[2, 'b'], [1, 'a']]); // same as new SortedMap([[2, 'b'], [1, 'a']])\n * ```\n */\n static from<K, V>(entries: Iterable<[K, V]>, ...options: ComparatorArg<K>): SortedMap<K, V> {\n return new SortedMap<K, V>(entries, ...options);\n }\n\n /**\n * O(log n) to locate + O(1) to replace in place, or O(√n) amortized to insert.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>();\n * byPrice.set(101.5, 'order-1');\n * byPrice.set(101.5, 'order-1-updated'); // overwrites, doesn't grow size\n * ```\n */\n set(key: K, value: V): void {\n this.engine.set([key, value]);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.get(101.5); // 'order-1'\n * byPrice.get(1); // undefined\n * ```\n */\n get(key: K): V | undefined {\n return this.engine.findBy((entry) => this.keyComparator(entry[0], key))?.[1];\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.delete(101.5); // true\n * byPrice.delete(101.5); // false — already gone\n * ```\n */\n delete(key: K): boolean {\n return this.engine.removeBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a']]).has(1); // true\n * ```\n */\n has(key: K): boolean {\n return this.engine.hasBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * A snapshot `SortedSet` of the current keys — not a live view.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * [...byPrice.keys()]; // [1, 2]\n * ```\n */\n keys(): SortedSet<K> {\n return new SortedSet<K>(this.keysGenerator(), ...comparatorArgs(this.keyComparator));\n }\n\n private *keysGenerator(): Generator<K> {\n for (const [key] of this.engine) {\n yield key;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).values()]; // ['a', 'b']\n * ```\n */\n *values(): IterableIterator<V> {\n for (const [, value] of this.engine) {\n yield value;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).entries()]; // [[1, 'a'], [2, 'b']]\n * ```\n */\n entries(): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n\n /**\n * Iterates `[key, value]` pairs with keys in `[minKey, maxKey]`.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[95, 'a'], [100, 'b'], [105, 'c']]);\n * [...byPrice.irange(95, 100)]; // [[95, 'a'], [100, 'b']]\n * ```\n */\n irange(minKey?: K, maxKey?: K): IterableIterator<[K, V]> {\n const min = minKey === undefined ? undefined : ([minKey, undefined as unknown as V] as [K, V]);\n const max = maxKey === undefined ? undefined : ([maxKey, undefined as unknown as V] as [K, V]);\n return this.engine.irange(min, max);\n }\n\n /**\n * O(√n). Entry at ordinal position `index` in key order.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * byPrice.at(0); // [1, 'a']\n * ```\n */\n at(index: number): [K, V] | undefined {\n return this.engine.at(index);\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a'], [2, 'b']]).size; // 2\n * ```\n */\n get size(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[1, 'a']]);\n * byPrice.clear();\n * byPrice.size; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * @example\n * ```ts\n * for (const [key, value] of new SortedMap([[2, 'b'], [1, 'a']])) {\n * console.log(key, value); // 1 'a', then 2 'b'\n * }\n * ```\n */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -43,6 +43,22 @@ declare class SortedList<T> implements Iterable<T> {
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
constructor(iterable?: Iterable<T>, ...options: ComparatorArg<T>);
|
|
46
|
+
/**
|
|
47
|
+
* Materializes and sorts `iterable` for the constructor to cut into
|
|
48
|
+
* buckets in one O(n) pass. A hook (not a field/engine access — `engine`
|
|
49
|
+
* isn't assigned yet when this runs) so `SortedSet` can additionally
|
|
50
|
+
* dedupe adjacent equal elements while still reusing this sort step.
|
|
51
|
+
*/
|
|
52
|
+
protected prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[];
|
|
53
|
+
/**
|
|
54
|
+
* A read-only iterable/array factory, paralleling `Array.from`.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* SortedList.from([3, 1, 2]); // same as new SortedList([3, 1, 2])
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
static from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedList<T>;
|
|
46
62
|
/** Safe to call from subclasses/clone: both `ComparatorArg<T>` branches accept `{ comparator }`. */
|
|
47
63
|
protected comparatorArg(): ComparatorArg<T>;
|
|
48
64
|
/**
|
|
@@ -228,6 +244,20 @@ declare class SortedList<T> implements Iterable<T> {
|
|
|
228
244
|
* ```
|
|
229
245
|
*/
|
|
230
246
|
declare class SortedSet<T> extends SortedList<T> {
|
|
247
|
+
/**
|
|
248
|
+
* Dedupes adjacent equal elements (by comparator) after the base class's
|
|
249
|
+
* sort, keeping the first occurrence — matching {@link add}'s no-op-if-
|
|
250
|
+
* present semantics, which is what incremental construction produced
|
|
251
|
+
* before bulk construction existed.
|
|
252
|
+
*/
|
|
253
|
+
protected prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[];
|
|
254
|
+
/**
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* SortedSet.from([3, 1, 2, 1]); // same as new SortedSet([3, 1, 2, 1])
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
static from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedSet<T>;
|
|
231
261
|
/**
|
|
232
262
|
* O(log n) `has` check + O(√n) amortized insert if the value is new.
|
|
233
263
|
*
|
|
@@ -318,6 +348,13 @@ declare class SortedMap<K, V> implements Iterable<[K, V]> {
|
|
|
318
348
|
* ```
|
|
319
349
|
*/
|
|
320
350
|
constructor(entries?: Iterable<[K, V]>, ...options: ComparatorArg<K>);
|
|
351
|
+
/**
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* SortedMap.from([[2, 'b'], [1, 'a']]); // same as new SortedMap([[2, 'b'], [1, 'a']])
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
static from<K, V>(entries: Iterable<[K, V]>, ...options: ComparatorArg<K>): SortedMap<K, V>;
|
|
321
358
|
/**
|
|
322
359
|
* O(log n) to locate + O(1) to replace in place, or O(√n) amortized to insert.
|
|
323
360
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -43,6 +43,22 @@ declare class SortedList<T> implements Iterable<T> {
|
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
45
|
constructor(iterable?: Iterable<T>, ...options: ComparatorArg<T>);
|
|
46
|
+
/**
|
|
47
|
+
* Materializes and sorts `iterable` for the constructor to cut into
|
|
48
|
+
* buckets in one O(n) pass. A hook (not a field/engine access — `engine`
|
|
49
|
+
* isn't assigned yet when this runs) so `SortedSet` can additionally
|
|
50
|
+
* dedupe adjacent equal elements while still reusing this sort step.
|
|
51
|
+
*/
|
|
52
|
+
protected prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[];
|
|
53
|
+
/**
|
|
54
|
+
* A read-only iterable/array factory, paralleling `Array.from`.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* SortedList.from([3, 1, 2]); // same as new SortedList([3, 1, 2])
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
static from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedList<T>;
|
|
46
62
|
/** Safe to call from subclasses/clone: both `ComparatorArg<T>` branches accept `{ comparator }`. */
|
|
47
63
|
protected comparatorArg(): ComparatorArg<T>;
|
|
48
64
|
/**
|
|
@@ -228,6 +244,20 @@ declare class SortedList<T> implements Iterable<T> {
|
|
|
228
244
|
* ```
|
|
229
245
|
*/
|
|
230
246
|
declare class SortedSet<T> extends SortedList<T> {
|
|
247
|
+
/**
|
|
248
|
+
* Dedupes adjacent equal elements (by comparator) after the base class's
|
|
249
|
+
* sort, keeping the first occurrence — matching {@link add}'s no-op-if-
|
|
250
|
+
* present semantics, which is what incremental construction produced
|
|
251
|
+
* before bulk construction existed.
|
|
252
|
+
*/
|
|
253
|
+
protected prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[];
|
|
254
|
+
/**
|
|
255
|
+
* @example
|
|
256
|
+
* ```ts
|
|
257
|
+
* SortedSet.from([3, 1, 2, 1]); // same as new SortedSet([3, 1, 2, 1])
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
static from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedSet<T>;
|
|
231
261
|
/**
|
|
232
262
|
* O(log n) `has` check + O(√n) amortized insert if the value is new.
|
|
233
263
|
*
|
|
@@ -318,6 +348,13 @@ declare class SortedMap<K, V> implements Iterable<[K, V]> {
|
|
|
318
348
|
* ```
|
|
319
349
|
*/
|
|
320
350
|
constructor(entries?: Iterable<[K, V]>, ...options: ComparatorArg<K>);
|
|
351
|
+
/**
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* SortedMap.from([[2, 'b'], [1, 'a']]); // same as new SortedMap([[2, 'b'], [1, 'a']])
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
static from<K, V>(entries: Iterable<[K, V]>, ...options: ComparatorArg<K>): SortedMap<K, V>;
|
|
321
358
|
/**
|
|
322
359
|
* O(log n) to locate + O(1) to replace in place, or O(√n) amortized to insert.
|
|
323
360
|
*
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function
|
|
1
|
+
function b(s,e,t,r){let n=0,o=s;for(;n<o;){let a=n+o>>>1,i=t(e(a));(r==="left"?i>=0:i>0)?o=a:n=a+1;}return n}var c=class c{constructor(e){this.buckets=[];this.count=0;this.comparator=e;}static targetBucketSizeFor(e){return Math.max(c.MIN_BUCKET_SIZE,Math.ceil(Math.sqrt(e)))}targetBucketSize(){return c.targetBucketSizeFor(this.count)}static fromSorted(e,t){let r=new c(t),n=e.length;if(n===0)return r;if(c.isDevelopment){for(let i=1;i<n;i++)if(t(e[i-1],e[i])>0)throw new Error("BucketEngine.fromSorted: input array is not sorted per comparator")}let o=c.targetBucketSizeFor(n),a=[];for(let i=0;i<n;i+=o)a.push(e.slice(i,i+o));return r.buckets=a,r.count=n,r}maybeSplit(e){let t=this.buckets[e],r=this.targetBucketSize();if(t.length>r*2){let n=t.length>>>1,o=t.splice(n);this.buckets.splice(e+1,0,o);}}maybeMerge(e){let t=this.buckets[e];if(t.length===0){this.buckets.splice(e,1);return}if(this.buckets.length<=1)return;let r=this.targetBucketSize();if(t.length<r/2){let n=e>0?e-1:e+1,[o,a]=e<n?[e,n]:[n,e],i=this.buckets[o].concat(this.buckets[a]);this.buckets.splice(o,2,i),this.maybeSplit(o);}}locateBy(e,t){let r=b(this.buckets.length,i=>{let l=this.buckets[i];return l[l.length-1]},e,t),n=Math.min(r,this.buckets.length-1),o=this.buckets[n],a=b(o.length,i=>o[i],e,t);return {bucketIndex:n,localIndex:a}}locate(e,t){return this.locateBy(r=>this.comparator(r,e),t)}locatePosition(e){if(e<0||e>=this.count)return;let t=e;for(let r=0;r<this.buckets.length;r++){let n=this.buckets[r];if(t<n.length)return {bucketIndex:r,localIndex:t};t-=n.length;}throw new Error("BucketEngine: internal invariant violated (count out of sync with buckets)")}globalIndex(e,t){let r=t;for(let n=0;n<e;n++)r+=this.buckets[n].length;return r}resolveIndex(e){return e<0?this.count+e:e}*iterateRange(e,t){for(let r=e.bucketIndex;r<this.buckets.length;r++){if(t&&r>t.bucketIndex)return;let n=this.buckets[r],o=r===e.bucketIndex?e.localIndex:0,a=t&&r===t.bucketIndex?t.localIndex:n.length;for(let i=o;i<a;i++)yield n[i];}}add(e){if(this.buckets.length===0){this.buckets.push([e]),this.count+=1;return}let{bucketIndex:t,localIndex:r}=this.locate(e,"right");this.buckets[t].splice(r,0,e),this.count+=1,this.maybeSplit(t);}set(e){if(this.buckets.length===0){this.buckets.push([e]),this.count+=1;return}let{bucketIndex:t,localIndex:r}=this.locate(e,"left"),n=this.buckets[t];if(r<n.length&&this.comparator(n[r],e)===0){n[r]=e;return}n.splice(r,0,e),this.count+=1,this.maybeSplit(t);}remove(e){return this.removeBy(t=>this.comparator(t,e))}removeBy(e){if(this.buckets.length===0)return false;let{bucketIndex:t,localIndex:r}=this.locateBy(e,"left"),n=this.buckets[t];return r>=n.length||e(n[r])!==0?false:(n.splice(r,1),this.count-=1,this.maybeMerge(t),true)}discard(e){this.remove(e);}pop(e){if(this.count===0)throw new RangeError("SortedList#pop: list is empty");let t=e===void 0?this.count-1:this.resolveIndex(e),r=this.locatePosition(t);if(!r)throw new RangeError(`SortedList#pop: index ${e} is out of range`);let n=this.buckets[r.bucketIndex],[o]=n.splice(r.localIndex,1);return this.count-=1,this.maybeMerge(r.bucketIndex),o}at(e){let t=this.locatePosition(this.resolveIndex(e));if(t)return this.buckets[t.bucketIndex][t.localIndex]}indexOf(e){if(this.buckets.length===0)return -1;let{bucketIndex:t,localIndex:r}=this.locate(e,"left"),n=this.buckets[t];return r>=n.length||this.comparator(n[r],e)!==0?-1:this.globalIndex(t,r)}has(e){return this.hasBy(t=>this.comparator(t,e))}hasBy(e){return this.findBy(e)!==void 0}findBy(e){if(this.buckets.length===0)return;let{bucketIndex:t,localIndex:r}=this.locateBy(e,"left"),n=this.buckets[t];return r<n.length&&e(n[r])===0?n[r]:void 0}bisectLeft(e){if(this.buckets.length===0)return 0;let{bucketIndex:t,localIndex:r}=this.locate(e,"left");return this.globalIndex(t,r)}bisectRight(e){if(this.buckets.length===0)return 0;let{bucketIndex:t,localIndex:r}=this.locate(e,"right");return this.globalIndex(t,r)}irange(e,t,r){if(this.buckets.length===0)return this.iterateRange({bucketIndex:0,localIndex:0});let[n,o]=r?.inclusive??[true,true],a=e===void 0?{bucketIndex:0,localIndex:0}:this.locate(e,n?"left":"right"),i=t===void 0?void 0:this.locate(t,o?"right":"left");return this.iterateRange(a,i)}islice(e,t){let r=Math.max(0,e===void 0?0:this.resolveIndex(e)),n=Math.min(this.count,t===void 0?this.count:this.resolveIndex(t));if(r>=n||this.count===0)return this.iterateRange({bucketIndex:0,localIndex:0},{bucketIndex:0,localIndex:0});let o=this.locatePosition(r),a=this.locatePosition(n-1);return this.iterateRange(o,{bucketIndex:a.bucketIndex,localIndex:a.localIndex+1})}get length(){return this.count}clear(){this.buckets=[],this.count=0;}[Symbol.iterator](){return this.iterateRange({bucketIndex:0,localIndex:0})}};c.MIN_BUCKET_SIZE=32,c.isDevelopment=typeof process<"u"&&process.env?.NODE_ENV!=="production";var u=c;function m(s,e){if(typeof s=="number"&&typeof e=="number")return s-e;let t=String(s),r=String(e);return t<r?-1:t>r?1:0}var d=class s{constructor(e,...t){let n=t[0]?.comparator??m,o=e?this.prepareSorted(e,n):[];this.engine=u.fromSorted(o,n);}prepareSorted(e,t){return Array.from(e).sort(t)}static from(e,...t){return new s(e,...t)}comparatorArg(){return [{comparator:this.engine.comparator}]}add(e){this.engine.add(e);}update(e){for(let t of e)this.add(t);}remove(e){return this.engine.remove(e)}discard(e){this.engine.discard(e);}pop(e){return this.engine.pop(e)}at(e){return this.engine.at(e)}indexOf(e){return this.engine.indexOf(e)}has(e){return this.engine.has(e)}bisectLeft(e){return this.engine.bisectLeft(e)}bisectRight(e){return this.engine.bisectRight(e)}irange(e,t,r){return this.engine.irange(e,t,r)}islice(e,t){return this.engine.islice(e,t)}get length(){return this.engine.length}clear(){this.engine.clear();}clone(){return new s(this,...this.comparatorArg())}[Symbol.iterator](){return this.engine[Symbol.iterator]()}};var h=class s extends d{prepareSorted(e,t){let r=super.prepareSorted(e,t),n=[];for(let o of r)(n.length===0||t(n[n.length-1],o)!==0)&&n.push(o);return n}static from(e,...t){return new s(e,...t)}add(e){this.has(e)||super.add(e);}clone(){return new s(this,...this.comparatorArg())}union(e){let t=this.clone();for(let r of e)t.add(r);return t}intersection(e){let t=new s([],...this.comparatorArg());for(let r of this)e.has(r)&&t.add(r);return t}difference(e){let t=new s([],...this.comparatorArg());for(let r of this)e.has(r)||t.add(r);return t}isSubsetOf(e){for(let t of this)if(!e.has(t))return false;return true}};function f(s,e){if(typeof s=="number"&&typeof e=="number")return s-e;let t=String(s),r=String(e);return t<r?-1:t>r?1:0}function g(s){return [{comparator:s}]}function T(s,e){let t=[];for(let r of s)t.length>0&&e(t[t.length-1],r)===0?t[t.length-1]=r:t.push(r);return t}var p=class s{constructor(e,...t){let r=t[0];this.keyComparator=r?.comparator??f;let n=(i,l)=>this.keyComparator(i[0],l[0]),o=e?Array.from(e).sort(n):[],a=T(o,n);this.engine=u.fromSorted(a,n);}static from(e,...t){return new s(e,...t)}set(e,t){this.engine.set([e,t]);}get(e){return this.engine.findBy(t=>this.keyComparator(t[0],e))?.[1]}delete(e){return this.engine.removeBy(t=>this.keyComparator(t[0],e))}has(e){return this.engine.hasBy(t=>this.keyComparator(t[0],e))}keys(){return new h(this.keysGenerator(),...g(this.keyComparator))}*keysGenerator(){for(let[e]of this.engine)yield e;}*values(){for(let[,e]of this.engine)yield e;}entries(){return this.engine[Symbol.iterator]()}irange(e,t){let r=e===void 0?void 0:[e,void 0],n=t===void 0?void 0:[t,void 0];return this.engine.irange(r,n)}at(e){return this.engine.at(e)}get size(){return this.engine.length}clear(){this.engine.clear();}[Symbol.iterator](){return this.engine[Symbol.iterator]()}};export{d as SortedList,p as SortedMap,h as SortedSet};//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/bucket-engine.ts","../src/sorted-list.ts","../src/sorted-set.ts","../src/sorted-map.ts"],"names":["bisectByCompare","length","getCandidate","compare","bias","lo","hi","mid","cmp","_BucketEngine","comparator","bucketIndex","bucket","target","right","neighborIndex","a","b","merged","i","clampedBucketIndex","localIndex","value","candidate","index","remaining","total","start","end","from","to","resolved","location","min","max","options","minInclusive","maxInclusive","resolvedStart","resolvedEnd","startLoc","endLoc","BucketEngine","defaultComparator","left","SortedList","_SortedList","iterable","SortedSet","_SortedSet","other","result","defaultKeyComparator","comparatorArgs","SortedMap","entries","opts","entryComparator","key","entry","minKey","maxKey"],"mappings":"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","file":"index.js","sourcesContent":["import type { Comparator } from '../types.js';\n\ntype Bias = 'left' | 'right';\n\n/**\n * Generic binary search over `length` candidates. `compare(candidate)` must\n * return the same sign a comparator would for `comparator(candidate, target)`\n * — i.e. negative if the candidate sorts before the (implicit) target.\n * Taking a closure instead of `(target, comparator)` lets callers search by\n * a bare key without constructing a throwaway full element to compare against.\n */\nfunction bisectByCompare<T>(\n length: number,\n getCandidate: (index: number) => T,\n compare: (candidate: T) => number,\n bias: Bias,\n): number {\n let lo = 0;\n let hi = length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const cmp = compare(getCandidate(mid));\n const goLeft = bias === 'left' ? cmp >= 0 : cmp > 0;\n if (goLeft) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return lo;\n}\n\ninterface BucketLocation {\n bucketIndex: number;\n localIndex: number;\n}\n\n/**\n * Internal \"list of lists\" (sqrt-decomposition) engine shared by `SortedList`\n * and `SortedMap` — not part of the public API.\n *\n * Buckets of roughly √n sorted elements each, the same technique used by\n * Python's `sortedcontainers`. Locating a bucket by value is a binary search\n * over bucket boundaries (O(log buckets)); locating by position walks bucket\n * lengths (O(buckets)). With bucket count kept close to √n, that's O(log n)\n * and O(√n) respectively.\n *\n * `SortedMap` uses the `*By` methods directly (with a closure that compares\n * a stored `[K, V]` entry against a bare key) instead of `SortedList`'s\n * public wrapper: going through `bisectLeft` + `at` would pay for a\n * positional index (O(√n)) it doesn't need, and comparing via a search value\n * would need a throwaway `[key, undefined]` tuple and double key-unwrapping\n * per comparison instead of one.\n */\nexport class BucketEngine<T> implements Iterable<T> {\n private static readonly MIN_BUCKET_SIZE = 32;\n\n private buckets: T[][] = [];\n private count = 0;\n readonly comparator: Comparator<T>;\n\n constructor(comparator: Comparator<T>) {\n this.comparator = comparator;\n }\n\n private targetBucketSize(): number {\n return Math.max(BucketEngine.MIN_BUCKET_SIZE, Math.ceil(Math.sqrt(this.count)));\n }\n\n private maybeSplit(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n const target = this.targetBucketSize();\n if (bucket.length > target * 2) {\n const mid = bucket.length >>> 1;\n const right = bucket.splice(mid);\n this.buckets.splice(bucketIndex + 1, 0, right);\n }\n }\n\n private maybeMerge(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n if (bucket.length === 0) {\n this.buckets.splice(bucketIndex, 1);\n return;\n }\n if (this.buckets.length <= 1) {\n return;\n }\n const target = this.targetBucketSize();\n if (bucket.length < target / 2) {\n const neighborIndex = bucketIndex > 0 ? bucketIndex - 1 : bucketIndex + 1;\n const [a, b] =\n bucketIndex < neighborIndex ? [bucketIndex, neighborIndex] : [neighborIndex, bucketIndex];\n const merged = this.buckets[a]!.concat(this.buckets[b]!);\n this.buckets.splice(a, 2, merged);\n this.maybeSplit(a);\n }\n }\n\n /** Lookup by an arbitrary comparison closure: which (bucket, local index) does it point to? O(log n). Callers must ensure buckets is non-empty. */\n private locateBy(compare: (candidate: T) => number, bias: Bias): BucketLocation {\n const bucketIndex = bisectByCompare(\n this.buckets.length,\n (i) => {\n const bucket = this.buckets[i]!;\n return bucket[bucket.length - 1]!;\n },\n compare,\n bias,\n );\n const clampedBucketIndex = Math.min(bucketIndex, this.buckets.length - 1);\n const bucket = this.buckets[clampedBucketIndex]!;\n const localIndex = bisectByCompare(bucket.length, (i) => bucket[i]!, compare, bias);\n return { bucketIndex: clampedBucketIndex, localIndex };\n }\n\n /** Value-based lookup: which (bucket, local index) does `value` belong at? O(log n). Callers must ensure buckets is non-empty. */\n private locate(value: T, bias: Bias): BucketLocation {\n return this.locateBy((candidate) => this.comparator(candidate, value), bias);\n }\n\n /** Position-based lookup: which (bucket, local index) is global index `index` at? O(√n). */\n private locatePosition(index: number): BucketLocation | undefined {\n if (index < 0 || index >= this.count) {\n return undefined;\n }\n let remaining = index;\n for (let i = 0; i < this.buckets.length; i++) {\n const bucket = this.buckets[i]!;\n if (remaining < bucket.length) {\n return { bucketIndex: i, localIndex: remaining };\n }\n remaining -= bucket.length;\n }\n /* v8 ignore next -- unreachable unless `count` desyncs from `buckets`, which would be an internal bug */\n throw new Error('BucketEngine: internal invariant violated (count out of sync with buckets)');\n }\n\n /** Inverse of {@link locatePosition}: sums preceding bucket lengths. O(√n). */\n private globalIndex(bucketIndex: number, localIndex: number): number {\n let total = localIndex;\n for (let i = 0; i < bucketIndex; i++) {\n total += this.buckets[i]!.length;\n }\n return total;\n }\n\n private resolveIndex(index: number): number {\n return index < 0 ? this.count + index : index;\n }\n\n private *iterateRange(start: BucketLocation, end?: BucketLocation): Generator<T> {\n for (let bucketIndex = start.bucketIndex; bucketIndex < this.buckets.length; bucketIndex++) {\n if (end && bucketIndex > end.bucketIndex) {\n return;\n }\n const bucket = this.buckets[bucketIndex]!;\n const from = bucketIndex === start.bucketIndex ? start.localIndex : 0;\n const to = end && bucketIndex === end.bucketIndex ? end.localIndex : bucket.length;\n for (let i = from; i < to; i++) {\n yield bucket[i]!;\n }\n }\n }\n\n /** O(√n) amortized: locates the target bucket and splices the value in, splitting oversized buckets. */\n add(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n this.buckets[bucketIndex]!.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n /**\n * Replaces the stored element equal to `value` (by comparator) in place, or\n * inserts it if absent. O(log n) to locate; O(1) to replace in place, or\n * O(√n) amortized to insert. This is what backs `SortedMap#set` — cheaper\n * than a separate find-then-remove-then-add round trip.\n */\n set(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex < bucket.length && this.comparator(bucket[localIndex]!, value) === 0) {\n bucket[localIndex] = value;\n return;\n }\n bucket.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n remove(value: T): boolean {\n return this.removeBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link remove}, via an arbitrary comparison closure instead of a full value. */\n removeBy(compare: (candidate: T) => number): boolean {\n if (this.buckets.length === 0) {\n return false;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || compare(bucket[localIndex]!) !== 0) {\n return false;\n }\n bucket.splice(localIndex, 1);\n this.count -= 1;\n this.maybeMerge(bucketIndex);\n return true;\n }\n\n discard(value: T): void {\n this.remove(value);\n }\n\n pop(index?: number): T {\n if (this.count === 0) {\n throw new RangeError('SortedList#pop: list is empty');\n }\n const resolved = index === undefined ? this.count - 1 : this.resolveIndex(index);\n const location = this.locatePosition(resolved);\n if (!location) {\n throw new RangeError(`SortedList#pop: index ${index} is out of range`);\n }\n const bucket = this.buckets[location.bucketIndex]!;\n const [value] = bucket.splice(location.localIndex, 1);\n this.count -= 1;\n this.maybeMerge(location.bucketIndex);\n return value as T;\n }\n\n /** O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end). */\n at(index: number): T | undefined {\n const location = this.locatePosition(this.resolveIndex(index));\n if (!location) {\n return undefined;\n }\n return this.buckets[location.bucketIndex]![location.localIndex];\n }\n\n indexOf(value: T): number {\n if (this.buckets.length === 0) {\n return -1;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || this.comparator(bucket[localIndex]!, value) !== 0) {\n return -1;\n }\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n): binary search for the bucket, then binary search within it. */\n has(value: T): boolean {\n return this.hasBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link has}, via an arbitrary comparison closure instead of a full value. */\n hasBy(compare: (candidate: T) => number): boolean {\n return this.findBy(compare) !== undefined;\n }\n\n /** Same O(log n) path as {@link has}, but returns the actual stored element instead of a boolean. */\n findBy(compare: (candidate: T) => number): T | undefined {\n if (this.buckets.length === 0) {\n return undefined;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n return localIndex < bucket.length && compare(bucket[localIndex]!) === 0\n ? bucket[localIndex]\n : undefined;\n }\n\n bisectLeft(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n bisectRight(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n) to locate both bounds by value + O(k) to iterate the k results. */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n if (this.buckets.length === 0) {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n const [minInclusive, maxInclusive] = options?.inclusive ?? [true, true];\n const start =\n min === undefined\n ? { bucketIndex: 0, localIndex: 0 }\n : this.locate(min, minInclusive ? 'left' : 'right');\n const end = max === undefined ? undefined : this.locate(max, maxInclusive ? 'right' : 'left');\n return this.iterateRange(start, end);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n * (Slightly worse than the O(log n) originally targeted for this method —\n * positional lookup fundamentally needs a bucket-length walk without a\n * Fenwick index. Confirmed empirically via `npm run bench`.)\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n const resolvedStart = Math.max(0, start === undefined ? 0 : this.resolveIndex(start));\n const resolvedEnd = Math.min(\n this.count,\n end === undefined ? this.count : this.resolveIndex(end),\n );\n if (resolvedStart >= resolvedEnd || this.count === 0) {\n return this.iterateRange(\n { bucketIndex: 0, localIndex: 0 },\n { bucketIndex: 0, localIndex: 0 },\n );\n }\n const startLoc = this.locatePosition(resolvedStart)!;\n const endLoc = this.locatePosition(resolvedEnd - 1)!;\n return this.iterateRange(startLoc, {\n bucketIndex: endLoc.bucketIndex,\n localIndex: endLoc.localIndex + 1,\n });\n }\n\n get length(): number {\n return this.count;\n }\n\n clear(): void {\n this.buckets = [];\n this.count = 0;\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultComparator<T>(a: T, b: T): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\n/**\n * A list that keeps its elements in sorted order as they're inserted.\n *\n * A thin public wrapper around the internal {@link BucketEngine} — see there\n * for the actual \"list of lists\" (sqrt-decomposition) implementation and its\n * complexity notes.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([42, 7, 99]);\n * scores.add(15);\n * [...scores]; // [7, 15, 42, 99]\n * ```\n */\nexport class SortedList<T> implements Iterable<T> {\n private readonly engine: BucketEngine<T>;\n\n /**\n * @example\n * ```ts\n * new SortedList<number>(); // empty\n * new SortedList<number>([3, 1, 2]); // [1, 2, 3]\n * new SortedList<Person>([...], { comparator: (a, b) => a.age - b.age });\n * ```\n */\n constructor(iterable?: Iterable<T>, ...options: ComparatorArg<T>) {\n const opts = options[0] as SortedOptions<T> | undefined;\n const comparator = opts?.comparator ?? (defaultComparator as Comparator<T>);\n this.engine = new BucketEngine<T>(comparator);\n // Goes through `this.update` -> `this.add` (not the engine's) so that a\n // SortedSet's overridden, deduping `add` applies during construction too.\n if (iterable) {\n this.update(iterable);\n }\n }\n\n /** Safe to call from subclasses/clone: both `ComparatorArg<T>` branches accept `{ comparator }`. */\n protected comparatorArg(): ComparatorArg<T> {\n return [{ comparator: this.engine.comparator }] as unknown as ComparatorArg<T>;\n }\n\n /**\n * O(√n) amortized.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>();\n * scores.add(42);\n * scores.add(7);\n * [...scores]; // [7, 42]\n * ```\n */\n add(value: T): void {\n this.engine.add(value);\n }\n\n /**\n * Bulk-inserts every value from `iterable`, one {@link add} at a time.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1]);\n * scores.update([2, 5, 4]);\n * [...scores]; // [1, 2, 3, 4, 5]\n * ```\n */\n update(iterable: Iterable<T>): void {\n for (const value of iterable) {\n this.add(value);\n }\n }\n\n /**\n * Removes the first occurrence of `value`. Returns `false` if it wasn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 2, 3]);\n * scores.remove(2); // true — removes one occurrence\n * scores.remove(99); // false — not present\n * ```\n */\n remove(value: T): boolean {\n return this.engine.remove(value);\n }\n\n /**\n * Like {@link remove}, but never throws (or returns anything) if `value` isn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.discard(99); // no-op, no error\n * ```\n */\n discard(value: T): void {\n this.engine.discard(value);\n }\n\n /**\n * Removes and returns the element at `index` (default: the last element).\n * Negative indices count from the end, same as {@link at}.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.pop(); // 30 — last element\n * scores.pop(0); // 10 — first element\n * ```\n */\n pop(index?: number): T {\n return this.engine.pop(index);\n }\n\n /**\n * O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end).\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.at(0); // 10\n * scores.at(-1); // 30 — same as Array.prototype.at\n * scores.at(99); // undefined — out of range\n * ```\n */\n at(index: number): T | undefined {\n return this.engine.at(index);\n }\n\n /**\n * The index of the first occurrence of `value`, or `-1` if absent.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 3]).indexOf(2); // 1\n * new SortedList<number>([1, 2, 3]).indexOf(99); // -1\n * ```\n */\n indexOf(value: T): number {\n return this.engine.indexOf(value);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.has(2); // true\n * scores.has(99); // false\n * ```\n */\n has(value: T): boolean {\n return this.engine.has(value);\n }\n\n /**\n * The leftmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectLeft(2); // 1\n * ```\n */\n bisectLeft(value: T): number {\n return this.engine.bisectLeft(value);\n }\n\n /**\n * The rightmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectRight(2); // 4\n * ```\n */\n bisectRight(value: T): number {\n return this.engine.bisectRight(value);\n }\n\n /**\n * O(log n) to locate both bounds by value + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3, 4, 5]);\n * [...scores.irange(2, 4)]; // [2, 3, 4] — inclusive by default\n * [...scores.irange(2, 4, { inclusive: [false, true] })]; // [3, 4]\n * ```\n */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n return this.engine.irange(min, max, options);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30, 40, 50]);\n * [...scores.islice(1, 4)]; // [20, 30, 40] — like Array.prototype.slice\n * ```\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n return this.engine.islice(start, end);\n }\n\n /**\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 3]).length; // 3\n * ```\n */\n get length(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.clear();\n * scores.length; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * An independent copy — mutating the clone never affects the original.\n *\n * @example\n * ```ts\n * const original = new SortedList<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * copy.length; // 4\n * ```\n */\n clone(): SortedList<T> {\n return new SortedList<T>(this, ...this.comparatorArg());\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1, 2]);\n * for (const value of scores) console.log(value); // 1, 2, 3\n * ```\n */\n [Symbol.iterator](): IterableIterator<T> {\n return this.engine[Symbol.iterator]();\n }\n}\n","import { SortedList } from './sorted-list.js';\n\n/**\n * Like {@link SortedList}, but rejects duplicates (compared via the\n * comparator, not reference identity). Adds set-theory operations.\n *\n * Reuses `SortedList`'s bucket structure entirely: the only behavioral\n * difference is that `add` is a no-op for values already present.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['b', 'a', 'c', 'a']);\n * [...tags]; // ['a', 'b', 'c'] — the duplicate 'a' was dropped\n * ```\n */\nexport class SortedSet<T> extends SortedList<T> {\n /**\n * O(log n) `has` check + O(√n) amortized insert if the value is new.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['a']);\n * tags.add('a'); // no-op, already present\n * tags.length; // 1\n * ```\n */\n override add(value: T): void {\n if (!this.has(value)) {\n super.add(value);\n }\n }\n\n /**\n * @example\n * ```ts\n * const original = new SortedSet<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * ```\n */\n override clone(): SortedSet<T> {\n return new SortedSet<T>(this, ...this.comparatorArg());\n }\n\n /**\n * O(m log n + m) for a set of size m being merged in.\n *\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([3, 4]);\n * [...a.union(b)]; // [1, 2, 3, 4]\n * ```\n */\n union(other: SortedSet<T>): SortedSet<T> {\n const result = this.clone();\n for (const value of other) {\n result.add(value);\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3, 4]);\n * [...a.intersection(b)]; // [2, 3]\n * ```\n */\n intersection(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3]);\n * [...a.difference(b)]; // [1] — in a, not in b\n * ```\n */\n difference(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (!other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * new SortedSet<number>([2, 3]).isSubsetOf(new SortedSet<number>([1, 2, 3, 4])); // true\n * new SortedSet<number>([1, 5]).isSubsetOf(new SortedSet<number>([1, 2, 3])); // false\n * ```\n */\n isSubsetOf(other: SortedSet<T>): boolean {\n for (const value of this) {\n if (!other.has(value)) {\n return false;\n }\n }\n return true;\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport { SortedSet } from './sorted-set.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultKeyComparator<K>(a: K, b: K): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction comparatorArgs<T>(comparator: Comparator<T>): ComparatorArg<T> {\n return [{ comparator }] as unknown as ComparatorArg<T>;\n}\n\n/**\n * A dictionary ordered by key.\n *\n * Uses the internal {@link BucketEngine} directly (on `[K, V]` tuples, with a\n * comparator that only looks at the key) rather than composing over\n * `SortedList`'s public API. Two reasons: `set` needs the engine's O(log n)\n * in-place replace-or-insert (`SortedList#bisectLeft` + `#at` would pay for a\n * positional index it doesn't need), and `get`/`has`/`delete` use the `*By`\n * lookup methods with a closure over the bare key — that compares the key\n * only once per candidate (not twice, since the search side needs no\n * `entry[0]` unwrapping) and avoids allocating a throwaway `[key, undefined]`\n * search tuple per call.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1'], [99.75, 'order-2']]);\n * [...byPrice.keys()]; // [99.75, 101.5]\n * ```\n */\nexport class SortedMap<K, V> implements Iterable<[K, V]> {\n private readonly engine: BucketEngine<[K, V]>;\n private readonly keyComparator: Comparator<K>;\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>(); // empty\n * new SortedMap<number, string>([[2, 'b'], [1, 'a']]); // ordered by key: 1, 2\n * ```\n */\n constructor(entries?: Iterable<[K, V]>, ...options: ComparatorArg<K>) {\n const opts = options[0] as SortedOptions<K> | undefined;\n this.keyComparator = opts?.comparator ?? (defaultKeyComparator as Comparator<K>);\n const entryComparator: Comparator<[K, V]> = (a, b) => this.keyComparator(a[0], b[0]);\n this.engine = new BucketEngine<[K, V]>(entryComparator);\n if (entries) {\n for (const [key, value] of entries) {\n this.set(key, value);\n }\n }\n }\n\n /**\n * O(log n) to locate + O(1) to replace in place, or O(√n) amortized to insert.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>();\n * byPrice.set(101.5, 'order-1');\n * byPrice.set(101.5, 'order-1-updated'); // overwrites, doesn't grow size\n * ```\n */\n set(key: K, value: V): void {\n this.engine.set([key, value]);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.get(101.5); // 'order-1'\n * byPrice.get(1); // undefined\n * ```\n */\n get(key: K): V | undefined {\n return this.engine.findBy((entry) => this.keyComparator(entry[0], key))?.[1];\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.delete(101.5); // true\n * byPrice.delete(101.5); // false — already gone\n * ```\n */\n delete(key: K): boolean {\n return this.engine.removeBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a']]).has(1); // true\n * ```\n */\n has(key: K): boolean {\n return this.engine.hasBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * A snapshot `SortedSet` of the current keys — not a live view.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * [...byPrice.keys()]; // [1, 2]\n * ```\n */\n keys(): SortedSet<K> {\n return new SortedSet<K>(this.keysGenerator(), ...comparatorArgs(this.keyComparator));\n }\n\n private *keysGenerator(): Generator<K> {\n for (const [key] of this.engine) {\n yield key;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).values()]; // ['a', 'b']\n * ```\n */\n *values(): IterableIterator<V> {\n for (const [, value] of this.engine) {\n yield value;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).entries()]; // [[1, 'a'], [2, 'b']]\n * ```\n */\n entries(): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n\n /**\n * Iterates `[key, value]` pairs with keys in `[minKey, maxKey]`.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[95, 'a'], [100, 'b'], [105, 'c']]);\n * [...byPrice.irange(95, 100)]; // [[95, 'a'], [100, 'b']]\n * ```\n */\n irange(minKey?: K, maxKey?: K): IterableIterator<[K, V]> {\n const min = minKey === undefined ? undefined : ([minKey, undefined as unknown as V] as [K, V]);\n const max = maxKey === undefined ? undefined : ([maxKey, undefined as unknown as V] as [K, V]);\n return this.engine.irange(min, max);\n }\n\n /**\n * O(√n). Entry at ordinal position `index` in key order.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * byPrice.at(0); // [1, 'a']\n * ```\n */\n at(index: number): [K, V] | undefined {\n return this.engine.at(index);\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a'], [2, 'b']]).size; // 2\n * ```\n */\n get size(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[1, 'a']]);\n * byPrice.clear();\n * byPrice.size; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * @example\n * ```ts\n * for (const [key, value] of new SortedMap([[2, 'b'], [1, 'a']])) {\n * console.log(key, value); // 1 'a', then 2 'b'\n * }\n * ```\n */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/bucket-engine.ts","../src/sorted-list.ts","../src/sorted-set.ts","../src/sorted-map.ts"],"names":["bisectByCompare","length","getCandidate","compare","bias","lo","hi","mid","cmp","_BucketEngine","comparator","count","sortedArray","engine","target","buckets","bucketIndex","bucket","right","neighborIndex","a","b","merged","clampedBucketIndex","localIndex","value","candidate","index","remaining","i","total","start","end","from","to","resolved","location","min","max","options","minInclusive","maxInclusive","resolvedStart","resolvedEnd","startLoc","endLoc","BucketEngine","defaultComparator","left","SortedList","_SortedList","iterable","sorted","SortedSet","_SortedSet","deduped","other","result","defaultKeyComparator","comparatorArgs","dedupeKeepingLast","SortedMap","_SortedMap","entries","opts","entryComparator","key","entry","minKey","maxKey"],"mappings":"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","file":"index.js","sourcesContent":["import type { Comparator } from '../types.js';\n\ntype Bias = 'left' | 'right';\n\n/**\n * Generic binary search over `length` candidates. `compare(candidate)` must\n * return the same sign a comparator would for `comparator(candidate, target)`\n * — i.e. negative if the candidate sorts before the (implicit) target.\n * Taking a closure instead of `(target, comparator)` lets callers search by\n * a bare key without constructing a throwaway full element to compare against.\n */\nfunction bisectByCompare<T>(\n length: number,\n getCandidate: (index: number) => T,\n compare: (candidate: T) => number,\n bias: Bias,\n): number {\n let lo = 0;\n let hi = length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const cmp = compare(getCandidate(mid));\n const goLeft = bias === 'left' ? cmp >= 0 : cmp > 0;\n if (goLeft) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return lo;\n}\n\ninterface BucketLocation {\n bucketIndex: number;\n localIndex: number;\n}\n\n/**\n * Internal \"list of lists\" (sqrt-decomposition) engine shared by `SortedList`\n * and `SortedMap` — not part of the public API.\n *\n * Buckets of roughly √n sorted elements each, the same technique used by\n * Python's `sortedcontainers`. Locating a bucket by value is a binary search\n * over bucket boundaries (O(log buckets)); locating by position walks bucket\n * lengths (O(buckets)). With bucket count kept close to √n, that's O(log n)\n * and O(√n) respectively.\n *\n * `SortedMap` uses the `*By` methods directly (with a closure that compares\n * a stored `[K, V]` entry against a bare key) instead of `SortedList`'s\n * public wrapper: going through `bisectLeft` + `at` would pay for a\n * positional index (O(√n)) it doesn't need, and comparing via a search value\n * would need a throwaway `[key, undefined]` tuple and double key-unwrapping\n * per comparison instead of one.\n */\nexport class BucketEngine<T> implements Iterable<T> {\n private static readonly MIN_BUCKET_SIZE = 32;\n\n /**\n * Guards the O(n) sortedness check in {@link fromSorted}. `typeof process`\n * keeps this safe to evaluate in a plain browser (no bundler define step)\n * where `process` doesn't exist at runtime.\n */\n private static readonly isDevelopment =\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n private buckets: T[][] = [];\n private count = 0;\n readonly comparator: Comparator<T>;\n\n constructor(comparator: Comparator<T>) {\n this.comparator = comparator;\n }\n\n private static targetBucketSizeFor(count: number): number {\n return Math.max(BucketEngine.MIN_BUCKET_SIZE, Math.ceil(Math.sqrt(count)));\n }\n\n private targetBucketSize(): number {\n return BucketEngine.targetBucketSizeFor(this.count);\n }\n\n /**\n * Builds an engine directly from an array the caller guarantees is already\n * sorted per `comparator` — skips the O(√n)-amortized-per-element `add()`\n * path used by incremental construction in favor of one O(n) pass that\n * slices straight into buckets sized for the final count.\n *\n * Internal-only: the precondition (sortedness) is the caller's\n * responsibility. In non-production builds it's cheaply verified in O(n);\n * that check is skipped in production since it doubles comparator calls\n * for no benefit once the caller is trusted.\n */\n static fromSorted<T>(sortedArray: readonly T[], comparator: Comparator<T>): BucketEngine<T> {\n const engine = new BucketEngine<T>(comparator);\n const n = sortedArray.length;\n if (n === 0) {\n return engine;\n }\n if (BucketEngine.isDevelopment) {\n for (let i = 1; i < n; i++) {\n if (comparator(sortedArray[i - 1] as T, sortedArray[i] as T) > 0) {\n throw new Error('BucketEngine.fromSorted: input array is not sorted per comparator');\n }\n }\n }\n const target = BucketEngine.targetBucketSizeFor(n);\n const buckets: T[][] = [];\n for (let i = 0; i < n; i += target) {\n buckets.push(sortedArray.slice(i, i + target));\n }\n engine.buckets = buckets;\n engine.count = n;\n return engine;\n }\n\n private maybeSplit(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n const target = this.targetBucketSize();\n if (bucket.length > target * 2) {\n const mid = bucket.length >>> 1;\n const right = bucket.splice(mid);\n this.buckets.splice(bucketIndex + 1, 0, right);\n }\n }\n\n private maybeMerge(bucketIndex: number): void {\n const bucket = this.buckets[bucketIndex]!;\n if (bucket.length === 0) {\n this.buckets.splice(bucketIndex, 1);\n return;\n }\n if (this.buckets.length <= 1) {\n return;\n }\n const target = this.targetBucketSize();\n if (bucket.length < target / 2) {\n const neighborIndex = bucketIndex > 0 ? bucketIndex - 1 : bucketIndex + 1;\n const [a, b] =\n bucketIndex < neighborIndex ? [bucketIndex, neighborIndex] : [neighborIndex, bucketIndex];\n const merged = this.buckets[a]!.concat(this.buckets[b]!);\n this.buckets.splice(a, 2, merged);\n this.maybeSplit(a);\n }\n }\n\n /** Lookup by an arbitrary comparison closure: which (bucket, local index) does it point to? O(log n). Callers must ensure buckets is non-empty. */\n private locateBy(compare: (candidate: T) => number, bias: Bias): BucketLocation {\n const bucketIndex = bisectByCompare(\n this.buckets.length,\n (i) => {\n const bucket = this.buckets[i]!;\n return bucket[bucket.length - 1]!;\n },\n compare,\n bias,\n );\n const clampedBucketIndex = Math.min(bucketIndex, this.buckets.length - 1);\n const bucket = this.buckets[clampedBucketIndex]!;\n const localIndex = bisectByCompare(bucket.length, (i) => bucket[i]!, compare, bias);\n return { bucketIndex: clampedBucketIndex, localIndex };\n }\n\n /** Value-based lookup: which (bucket, local index) does `value` belong at? O(log n). Callers must ensure buckets is non-empty. */\n private locate(value: T, bias: Bias): BucketLocation {\n return this.locateBy((candidate) => this.comparator(candidate, value), bias);\n }\n\n /** Position-based lookup: which (bucket, local index) is global index `index` at? O(√n). */\n private locatePosition(index: number): BucketLocation | undefined {\n if (index < 0 || index >= this.count) {\n return undefined;\n }\n let remaining = index;\n for (let i = 0; i < this.buckets.length; i++) {\n const bucket = this.buckets[i]!;\n if (remaining < bucket.length) {\n return { bucketIndex: i, localIndex: remaining };\n }\n remaining -= bucket.length;\n }\n /* v8 ignore next -- unreachable unless `count` desyncs from `buckets`, which would be an internal bug */\n throw new Error('BucketEngine: internal invariant violated (count out of sync with buckets)');\n }\n\n /** Inverse of {@link locatePosition}: sums preceding bucket lengths. O(√n). */\n private globalIndex(bucketIndex: number, localIndex: number): number {\n let total = localIndex;\n for (let i = 0; i < bucketIndex; i++) {\n total += this.buckets[i]!.length;\n }\n return total;\n }\n\n private resolveIndex(index: number): number {\n return index < 0 ? this.count + index : index;\n }\n\n private *iterateRange(start: BucketLocation, end?: BucketLocation): Generator<T> {\n for (let bucketIndex = start.bucketIndex; bucketIndex < this.buckets.length; bucketIndex++) {\n if (end && bucketIndex > end.bucketIndex) {\n return;\n }\n const bucket = this.buckets[bucketIndex]!;\n const from = bucketIndex === start.bucketIndex ? start.localIndex : 0;\n const to = end && bucketIndex === end.bucketIndex ? end.localIndex : bucket.length;\n for (let i = from; i < to; i++) {\n yield bucket[i]!;\n }\n }\n }\n\n /** O(√n) amortized: locates the target bucket and splices the value in, splitting oversized buckets. */\n add(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n this.buckets[bucketIndex]!.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n /**\n * Replaces the stored element equal to `value` (by comparator) in place, or\n * inserts it if absent. O(log n) to locate; O(1) to replace in place, or\n * O(√n) amortized to insert. This is what backs `SortedMap#set` — cheaper\n * than a separate find-then-remove-then-add round trip.\n */\n set(value: T): void {\n if (this.buckets.length === 0) {\n this.buckets.push([value]);\n this.count += 1;\n return;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex < bucket.length && this.comparator(bucket[localIndex]!, value) === 0) {\n bucket[localIndex] = value;\n return;\n }\n bucket.splice(localIndex, 0, value);\n this.count += 1;\n this.maybeSplit(bucketIndex);\n }\n\n remove(value: T): boolean {\n return this.removeBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link remove}, via an arbitrary comparison closure instead of a full value. */\n removeBy(compare: (candidate: T) => number): boolean {\n if (this.buckets.length === 0) {\n return false;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || compare(bucket[localIndex]!) !== 0) {\n return false;\n }\n bucket.splice(localIndex, 1);\n this.count -= 1;\n this.maybeMerge(bucketIndex);\n return true;\n }\n\n discard(value: T): void {\n this.remove(value);\n }\n\n pop(index?: number): T {\n if (this.count === 0) {\n throw new RangeError('SortedList#pop: list is empty');\n }\n const resolved = index === undefined ? this.count - 1 : this.resolveIndex(index);\n const location = this.locatePosition(resolved);\n if (!location) {\n throw new RangeError(`SortedList#pop: index ${index} is out of range`);\n }\n const bucket = this.buckets[location.bucketIndex]!;\n const [value] = bucket.splice(location.localIndex, 1);\n this.count -= 1;\n this.maybeMerge(location.bucketIndex);\n return value as T;\n }\n\n /** O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end). */\n at(index: number): T | undefined {\n const location = this.locatePosition(this.resolveIndex(index));\n if (!location) {\n return undefined;\n }\n return this.buckets[location.bucketIndex]![location.localIndex];\n }\n\n indexOf(value: T): number {\n if (this.buckets.length === 0) {\n return -1;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n const bucket = this.buckets[bucketIndex]!;\n if (localIndex >= bucket.length || this.comparator(bucket[localIndex]!, value) !== 0) {\n return -1;\n }\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n): binary search for the bucket, then binary search within it. */\n has(value: T): boolean {\n return this.hasBy((candidate) => this.comparator(candidate, value));\n }\n\n /** Same O(log n) path as {@link has}, via an arbitrary comparison closure instead of a full value. */\n hasBy(compare: (candidate: T) => number): boolean {\n return this.findBy(compare) !== undefined;\n }\n\n /** Same O(log n) path as {@link has}, but returns the actual stored element instead of a boolean. */\n findBy(compare: (candidate: T) => number): T | undefined {\n if (this.buckets.length === 0) {\n return undefined;\n }\n const { bucketIndex, localIndex } = this.locateBy(compare, 'left');\n const bucket = this.buckets[bucketIndex]!;\n return localIndex < bucket.length && compare(bucket[localIndex]!) === 0\n ? bucket[localIndex]\n : undefined;\n }\n\n bisectLeft(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'left');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n bisectRight(value: T): number {\n if (this.buckets.length === 0) {\n return 0;\n }\n const { bucketIndex, localIndex } = this.locate(value, 'right');\n return this.globalIndex(bucketIndex, localIndex);\n }\n\n /** O(log n) to locate both bounds by value + O(k) to iterate the k results. */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n if (this.buckets.length === 0) {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n const [minInclusive, maxInclusive] = options?.inclusive ?? [true, true];\n const start =\n min === undefined\n ? { bucketIndex: 0, localIndex: 0 }\n : this.locate(min, minInclusive ? 'left' : 'right');\n const end = max === undefined ? undefined : this.locate(max, maxInclusive ? 'right' : 'left');\n return this.iterateRange(start, end);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n * (Slightly worse than the O(log n) originally targeted for this method —\n * positional lookup fundamentally needs a bucket-length walk without a\n * Fenwick index. Confirmed empirically via `npm run bench`.)\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n const resolvedStart = Math.max(0, start === undefined ? 0 : this.resolveIndex(start));\n const resolvedEnd = Math.min(\n this.count,\n end === undefined ? this.count : this.resolveIndex(end),\n );\n if (resolvedStart >= resolvedEnd || this.count === 0) {\n return this.iterateRange(\n { bucketIndex: 0, localIndex: 0 },\n { bucketIndex: 0, localIndex: 0 },\n );\n }\n const startLoc = this.locatePosition(resolvedStart)!;\n const endLoc = this.locatePosition(resolvedEnd - 1)!;\n return this.iterateRange(startLoc, {\n bucketIndex: endLoc.bucketIndex,\n localIndex: endLoc.localIndex + 1,\n });\n }\n\n get length(): number {\n return this.count;\n }\n\n clear(): void {\n this.buckets = [];\n this.count = 0;\n }\n\n [Symbol.iterator](): IterableIterator<T> {\n return this.iterateRange({ bucketIndex: 0, localIndex: 0 });\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultComparator<T>(a: T, b: T): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\n/**\n * A list that keeps its elements in sorted order as they're inserted.\n *\n * A thin public wrapper around the internal {@link BucketEngine} — see there\n * for the actual \"list of lists\" (sqrt-decomposition) implementation and its\n * complexity notes.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([42, 7, 99]);\n * scores.add(15);\n * [...scores]; // [7, 15, 42, 99]\n * ```\n */\nexport class SortedList<T> implements Iterable<T> {\n private readonly engine: BucketEngine<T>;\n\n /**\n * @example\n * ```ts\n * new SortedList<number>(); // empty\n * new SortedList<number>([3, 1, 2]); // [1, 2, 3]\n * new SortedList<Person>([...], { comparator: (a, b) => a.age - b.age });\n * ```\n */\n constructor(iterable?: Iterable<T>, ...options: ComparatorArg<T>) {\n const opts = options[0] as SortedOptions<T> | undefined;\n const comparator = opts?.comparator ?? (defaultComparator as Comparator<T>);\n const sorted = iterable ? this.prepareSorted(iterable, comparator) : [];\n this.engine = BucketEngine.fromSorted(sorted, comparator);\n }\n\n /**\n * Materializes and sorts `iterable` for the constructor to cut into\n * buckets in one O(n) pass. A hook (not a field/engine access — `engine`\n * isn't assigned yet when this runs) so `SortedSet` can additionally\n * dedupe adjacent equal elements while still reusing this sort step.\n */\n protected prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[] {\n return Array.from(iterable).sort(comparator);\n }\n\n /**\n * A read-only iterable/array factory, paralleling `Array.from`.\n *\n * @example\n * ```ts\n * SortedList.from([3, 1, 2]); // same as new SortedList([3, 1, 2])\n * ```\n */\n static from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedList<T> {\n return new SortedList<T>(iterable, ...options);\n }\n\n /** Safe to call from subclasses/clone: both `ComparatorArg<T>` branches accept `{ comparator }`. */\n protected comparatorArg(): ComparatorArg<T> {\n return [{ comparator: this.engine.comparator }] as unknown as ComparatorArg<T>;\n }\n\n /**\n * O(√n) amortized.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>();\n * scores.add(42);\n * scores.add(7);\n * [...scores]; // [7, 42]\n * ```\n */\n add(value: T): void {\n this.engine.add(value);\n }\n\n /**\n * Bulk-inserts every value from `iterable`, one {@link add} at a time.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1]);\n * scores.update([2, 5, 4]);\n * [...scores]; // [1, 2, 3, 4, 5]\n * ```\n */\n update(iterable: Iterable<T>): void {\n for (const value of iterable) {\n this.add(value);\n }\n }\n\n /**\n * Removes the first occurrence of `value`. Returns `false` if it wasn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 2, 3]);\n * scores.remove(2); // true — removes one occurrence\n * scores.remove(99); // false — not present\n * ```\n */\n remove(value: T): boolean {\n return this.engine.remove(value);\n }\n\n /**\n * Like {@link remove}, but never throws (or returns anything) if `value` isn't present.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.discard(99); // no-op, no error\n * ```\n */\n discard(value: T): void {\n this.engine.discard(value);\n }\n\n /**\n * Removes and returns the element at `index` (default: the last element).\n * Negative indices count from the end, same as {@link at}.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.pop(); // 30 — last element\n * scores.pop(0); // 10 — first element\n * ```\n */\n pop(index?: number): T {\n return this.engine.pop(index);\n }\n\n /**\n * O(√n): walks bucket lengths to find the element at `index` (negative indices count from the end).\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30]);\n * scores.at(0); // 10\n * scores.at(-1); // 30 — same as Array.prototype.at\n * scores.at(99); // undefined — out of range\n * ```\n */\n at(index: number): T | undefined {\n return this.engine.at(index);\n }\n\n /**\n * The index of the first occurrence of `value`, or `-1` if absent.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 3]).indexOf(2); // 1\n * new SortedList<number>([1, 2, 3]).indexOf(99); // -1\n * ```\n */\n indexOf(value: T): number {\n return this.engine.indexOf(value);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.has(2); // true\n * scores.has(99); // false\n * ```\n */\n has(value: T): boolean {\n return this.engine.has(value);\n }\n\n /**\n * The leftmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectLeft(2); // 1\n * ```\n */\n bisectLeft(value: T): number {\n return this.engine.bisectLeft(value);\n }\n\n /**\n * The rightmost index where `value` could be inserted while keeping the list sorted.\n *\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 2, 2, 3]).bisectRight(2); // 4\n * ```\n */\n bisectRight(value: T): number {\n return this.engine.bisectRight(value);\n }\n\n /**\n * O(log n) to locate both bounds by value + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3, 4, 5]);\n * [...scores.irange(2, 4)]; // [2, 3, 4] — inclusive by default\n * [...scores.irange(2, 4, { inclusive: [false, true] })]; // [3, 4]\n * ```\n */\n irange(min?: T, max?: T, options?: { inclusive?: [boolean, boolean] }): IterableIterator<T> {\n return this.engine.irange(min, max, options);\n }\n\n /**\n * O(√n) to locate both positional bounds + O(k) to iterate the k results.\n *\n * @example\n * ```ts\n * const scores = new SortedList<number>([10, 20, 30, 40, 50]);\n * [...scores.islice(1, 4)]; // [20, 30, 40] — like Array.prototype.slice\n * ```\n */\n islice(start?: number, end?: number): IterableIterator<T> {\n return this.engine.islice(start, end);\n }\n\n /**\n * @example\n * ```ts\n * new SortedList<number>([1, 2, 3]).length; // 3\n * ```\n */\n get length(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([1, 2, 3]);\n * scores.clear();\n * scores.length; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * An independent copy — mutating the clone never affects the original.\n *\n * @example\n * ```ts\n * const original = new SortedList<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * copy.length; // 4\n * ```\n */\n clone(): SortedList<T> {\n return new SortedList<T>(this, ...this.comparatorArg());\n }\n\n /**\n * @example\n * ```ts\n * const scores = new SortedList<number>([3, 1, 2]);\n * for (const value of scores) console.log(value); // 1, 2, 3\n * ```\n */\n [Symbol.iterator](): IterableIterator<T> {\n return this.engine[Symbol.iterator]();\n }\n}\n","import { SortedList } from './sorted-list.js';\nimport type { Comparator, ComparatorArg } from './types.js';\n\n/**\n * Like {@link SortedList}, but rejects duplicates (compared via the\n * comparator, not reference identity). Adds set-theory operations.\n *\n * Reuses `SortedList`'s bucket structure entirely: the only behavioral\n * difference is that `add` is a no-op for values already present.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['b', 'a', 'c', 'a']);\n * [...tags]; // ['a', 'b', 'c'] — the duplicate 'a' was dropped\n * ```\n */\nexport class SortedSet<T> extends SortedList<T> {\n /**\n * Dedupes adjacent equal elements (by comparator) after the base class's\n * sort, keeping the first occurrence — matching {@link add}'s no-op-if-\n * present semantics, which is what incremental construction produced\n * before bulk construction existed.\n */\n protected override prepareSorted(iterable: Iterable<T>, comparator: Comparator<T>): T[] {\n const sorted = super.prepareSorted(iterable, comparator);\n const deduped: T[] = [];\n for (const value of sorted) {\n if (deduped.length === 0 || comparator(deduped[deduped.length - 1] as T, value) !== 0) {\n deduped.push(value);\n }\n }\n return deduped;\n }\n\n /**\n * @example\n * ```ts\n * SortedSet.from([3, 1, 2, 1]); // same as new SortedSet([3, 1, 2, 1])\n * ```\n */\n static override from<T>(iterable: Iterable<T>, ...options: ComparatorArg<T>): SortedSet<T> {\n return new SortedSet<T>(iterable, ...options);\n }\n\n /**\n * O(log n) `has` check + O(√n) amortized insert if the value is new.\n *\n * @example\n * ```ts\n * const tags = new SortedSet<string>(['a']);\n * tags.add('a'); // no-op, already present\n * tags.length; // 1\n * ```\n */\n override add(value: T): void {\n if (!this.has(value)) {\n super.add(value);\n }\n }\n\n /**\n * @example\n * ```ts\n * const original = new SortedSet<number>([1, 2, 3]);\n * const copy = original.clone();\n * copy.add(4);\n * original.length; // 3\n * ```\n */\n override clone(): SortedSet<T> {\n return new SortedSet<T>(this, ...this.comparatorArg());\n }\n\n /**\n * O(m log n + m) for a set of size m being merged in.\n *\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([3, 4]);\n * [...a.union(b)]; // [1, 2, 3, 4]\n * ```\n */\n union(other: SortedSet<T>): SortedSet<T> {\n const result = this.clone();\n for (const value of other) {\n result.add(value);\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3, 4]);\n * [...a.intersection(b)]; // [2, 3]\n * ```\n */\n intersection(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * const a = new SortedSet<number>([1, 2, 3]);\n * const b = new SortedSet<number>([2, 3]);\n * [...a.difference(b)]; // [1] — in a, not in b\n * ```\n */\n difference(other: SortedSet<T>): SortedSet<T> {\n const result = new SortedSet<T>([], ...this.comparatorArg());\n for (const value of this) {\n if (!other.has(value)) {\n result.add(value);\n }\n }\n return result;\n }\n\n /**\n * @example\n * ```ts\n * new SortedSet<number>([2, 3]).isSubsetOf(new SortedSet<number>([1, 2, 3, 4])); // true\n * new SortedSet<number>([1, 5]).isSubsetOf(new SortedSet<number>([1, 2, 3])); // false\n * ```\n */\n isSubsetOf(other: SortedSet<T>): boolean {\n for (const value of this) {\n if (!other.has(value)) {\n return false;\n }\n }\n return true;\n }\n}\n","import { BucketEngine } from './internal/bucket-engine.js';\nimport { SortedSet } from './sorted-set.js';\nimport type { Comparator, ComparatorArg, SortedOptions } from './types.js';\n\nfunction defaultKeyComparator<K>(a: K, b: K): number {\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n const left = String(a);\n const right = String(b);\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n\nfunction comparatorArgs<T>(comparator: Comparator<T>): ComparatorArg<T> {\n return [{ comparator }] as unknown as ComparatorArg<T>;\n}\n\n/** Collapses adjacent equal-key runs (by `comparator`) to their last element — same \"later wins\" semantics as `new Map()`. */\nfunction dedupeKeepingLast<T>(sorted: T[], comparator: Comparator<T>): T[] {\n const result: T[] = [];\n for (const value of sorted) {\n if (result.length > 0 && comparator(result[result.length - 1] as T, value) === 0) {\n result[result.length - 1] = value;\n } else {\n result.push(value);\n }\n }\n return result;\n}\n\n/**\n * A dictionary ordered by key.\n *\n * Uses the internal {@link BucketEngine} directly (on `[K, V]` tuples, with a\n * comparator that only looks at the key) rather than composing over\n * `SortedList`'s public API. Two reasons: `set` needs the engine's O(log n)\n * in-place replace-or-insert (`SortedList#bisectLeft` + `#at` would pay for a\n * positional index it doesn't need), and `get`/`has`/`delete` use the `*By`\n * lookup methods with a closure over the bare key — that compares the key\n * only once per candidate (not twice, since the search side needs no\n * `entry[0]` unwrapping) and avoids allocating a throwaway `[key, undefined]`\n * search tuple per call.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1'], [99.75, 'order-2']]);\n * [...byPrice.keys()]; // [99.75, 101.5]\n * ```\n */\nexport class SortedMap<K, V> implements Iterable<[K, V]> {\n private readonly engine: BucketEngine<[K, V]>;\n private readonly keyComparator: Comparator<K>;\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>(); // empty\n * new SortedMap<number, string>([[2, 'b'], [1, 'a']]); // ordered by key: 1, 2\n * ```\n */\n constructor(entries?: Iterable<[K, V]>, ...options: ComparatorArg<K>) {\n const opts = options[0] as SortedOptions<K> | undefined;\n this.keyComparator = opts?.comparator ?? (defaultKeyComparator as Comparator<K>);\n const entryComparator: Comparator<[K, V]> = (a, b) => this.keyComparator(a[0], b[0]);\n const sorted = entries ? Array.from(entries).sort(entryComparator) : [];\n const deduped = dedupeKeepingLast(sorted, entryComparator);\n this.engine = BucketEngine.fromSorted(deduped, entryComparator);\n }\n\n /**\n * @example\n * ```ts\n * SortedMap.from([[2, 'b'], [1, 'a']]); // same as new SortedMap([[2, 'b'], [1, 'a']])\n * ```\n */\n static from<K, V>(entries: Iterable<[K, V]>, ...options: ComparatorArg<K>): SortedMap<K, V> {\n return new SortedMap<K, V>(entries, ...options);\n }\n\n /**\n * O(log n) to locate + O(1) to replace in place, or O(√n) amortized to insert.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>();\n * byPrice.set(101.5, 'order-1');\n * byPrice.set(101.5, 'order-1-updated'); // overwrites, doesn't grow size\n * ```\n */\n set(key: K, value: V): void {\n this.engine.set([key, value]);\n }\n\n /**\n * O(log n): binary search for the bucket, then binary search within it.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.get(101.5); // 'order-1'\n * byPrice.get(1); // undefined\n * ```\n */\n get(key: K): V | undefined {\n return this.engine.findBy((entry) => this.keyComparator(entry[0], key))?.[1];\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[101.5, 'order-1']]);\n * byPrice.delete(101.5); // true\n * byPrice.delete(101.5); // false — already gone\n * ```\n */\n delete(key: K): boolean {\n return this.engine.removeBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a']]).has(1); // true\n * ```\n */\n has(key: K): boolean {\n return this.engine.hasBy((entry) => this.keyComparator(entry[0], key));\n }\n\n /**\n * A snapshot `SortedSet` of the current keys — not a live view.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * [...byPrice.keys()]; // [1, 2]\n * ```\n */\n keys(): SortedSet<K> {\n return new SortedSet<K>(this.keysGenerator(), ...comparatorArgs(this.keyComparator));\n }\n\n private *keysGenerator(): Generator<K> {\n for (const [key] of this.engine) {\n yield key;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).values()]; // ['a', 'b']\n * ```\n */\n *values(): IterableIterator<V> {\n for (const [, value] of this.engine) {\n yield value;\n }\n }\n\n /**\n * @example\n * ```ts\n * [...new SortedMap<number, string>([[2, 'b'], [1, 'a']]).entries()]; // [[1, 'a'], [2, 'b']]\n * ```\n */\n entries(): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n\n /**\n * Iterates `[key, value]` pairs with keys in `[minKey, maxKey]`.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[95, 'a'], [100, 'b'], [105, 'c']]);\n * [...byPrice.irange(95, 100)]; // [[95, 'a'], [100, 'b']]\n * ```\n */\n irange(minKey?: K, maxKey?: K): IterableIterator<[K, V]> {\n const min = minKey === undefined ? undefined : ([minKey, undefined as unknown as V] as [K, V]);\n const max = maxKey === undefined ? undefined : ([maxKey, undefined as unknown as V] as [K, V]);\n return this.engine.irange(min, max);\n }\n\n /**\n * O(√n). Entry at ordinal position `index` in key order.\n *\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[2, 'b'], [1, 'a']]);\n * byPrice.at(0); // [1, 'a']\n * ```\n */\n at(index: number): [K, V] | undefined {\n return this.engine.at(index);\n }\n\n /**\n * @example\n * ```ts\n * new SortedMap<number, string>([[1, 'a'], [2, 'b']]).size; // 2\n * ```\n */\n get size(): number {\n return this.engine.length;\n }\n\n /**\n * @example\n * ```ts\n * const byPrice = new SortedMap<number, string>([[1, 'a']]);\n * byPrice.clear();\n * byPrice.size; // 0\n * ```\n */\n clear(): void {\n this.engine.clear();\n }\n\n /**\n * @example\n * ```ts\n * for (const [key, value] of new SortedMap([[2, 'b'], [1, 'a']])) {\n * console.log(key, value); // 1 'a', then 2 'b'\n * }\n * ```\n */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.engine[Symbol.iterator]();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sorted-collections",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "SortedList, SortedSet and SortedMap for JavaScript/TypeScript — zero runtime dependencies, inspired by Python's sortedcontainers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sorted",
|
|
@@ -25,9 +25,14 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"exports": {
|
|
27
27
|
".": {
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
"import": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"require": {
|
|
33
|
+
"types": "./dist/index.d.cts",
|
|
34
|
+
"default": "./dist/index.cjs"
|
|
35
|
+
}
|
|
31
36
|
},
|
|
32
37
|
"./package.json": "./package.json"
|
|
33
38
|
},
|
|
@@ -57,14 +62,27 @@
|
|
|
57
62
|
"docs:dev": "npm run docs:api && vitepress dev docs-site",
|
|
58
63
|
"docs:build": "npm run docs:api && vitepress build docs-site",
|
|
59
64
|
"docs:preview": "vitepress preview docs-site",
|
|
60
|
-
"
|
|
65
|
+
"publint": "publint",
|
|
66
|
+
"attw": "attw --pack .",
|
|
67
|
+
"size": "size-limit",
|
|
68
|
+
"prepublishOnly": "npm run format:check && npm run lint && npm run typecheck && npm run test && npm run build && npm run publint && npm run attw && npm run size"
|
|
61
69
|
},
|
|
70
|
+
"size-limit": [
|
|
71
|
+
{
|
|
72
|
+
"path": "dist/index.js",
|
|
73
|
+
"limit": "3 KB"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
62
76
|
"devDependencies": {
|
|
77
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
63
78
|
"@biomejs/biome": "^2.5.3",
|
|
64
79
|
"@changesets/cli": "^2.31.0",
|
|
80
|
+
"@size-limit/preset-small-lib": "^12.1.0",
|
|
65
81
|
"@types/node": "^26.1.1",
|
|
66
82
|
"@vitest/coverage-v8": "^4.1.10",
|
|
67
83
|
"fast-check": "^4.9.0",
|
|
84
|
+
"publint": "^0.3.21",
|
|
85
|
+
"size-limit": "^12.1.0",
|
|
68
86
|
"sorted-containers": "^0.4.0",
|
|
69
87
|
"sortedkit": "^0.1.0",
|
|
70
88
|
"tinybench": "^6.0.2",
|