max-priority-queue-typed 2.5.0 → 2.5.1
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/dist/cjs/index.cjs +294 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +294 -0
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +294 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +294 -0
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +252 -0
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +294 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +527 -2
- package/dist/types/data-structures/binary-tree/bst.d.ts +505 -1
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +399 -0
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +126 -1
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +2881 -382
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2867 -347
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2328 -312
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +2671 -277
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +210 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +189 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +241 -10
- package/dist/types/data-structures/heap/heap.d.ts +294 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +360 -3
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +318 -3
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +380 -2
- package/dist/types/data-structures/matrix/matrix.d.ts +168 -0
- package/dist/types/data-structures/queue/deque.d.ts +319 -4
- package/dist/types/data-structures/queue/queue.d.ts +252 -0
- package/dist/types/data-structures/stack/stack.d.ts +210 -0
- package/dist/types/data-structures/trie/trie.d.ts +256 -4
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/max-priority-queue-typed.js +294 -0
- package/dist/umd/max-priority-queue-typed.js.map +1 -1
- package/dist/umd/max-priority-queue-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +252 -0
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +295 -1
- package/src/data-structures/binary-tree/binary-tree.ts +527 -2
- package/src/data-structures/binary-tree/bst.ts +505 -1
- package/src/data-structures/binary-tree/red-black-tree.ts +399 -0
- package/src/data-structures/binary-tree/segment-tree.ts +127 -2
- package/src/data-structures/binary-tree/tree-map.ts +2958 -459
- package/src/data-structures/binary-tree/tree-multi-map.ts +3069 -549
- package/src/data-structures/binary-tree/tree-multi-set.ts +2476 -460
- package/src/data-structures/binary-tree/tree-set.ts +2816 -422
- package/src/data-structures/graph/abstract-graph.ts +4 -4
- package/src/data-structures/graph/directed-graph.ts +210 -0
- package/src/data-structures/graph/undirected-graph.ts +189 -0
- package/src/data-structures/hash/hash-map.ts +246 -15
- package/src/data-structures/heap/heap.ts +294 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +360 -3
- package/src/data-structures/linked-list/singly-linked-list.ts +318 -3
- package/src/data-structures/linked-list/skip-linked-list.ts +380 -2
- package/src/data-structures/matrix/matrix.ts +169 -1
- package/src/data-structures/queue/deque.ts +320 -5
- package/src/data-structures/queue/queue.ts +252 -0
- package/src/data-structures/stack/stack.ts +210 -0
- package/src/data-structures/trie/trie.ts +257 -5
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
|
@@ -151,17 +151,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
151
151
|
|
|
152
152
|
|
|
153
153
|
|
|
154
|
-
* @example
|
|
155
|
-
* // Check if empty
|
|
156
|
-
* console.log(new TreeMultiMap().isEmpty()); // true;
|
|
157
|
-
*/
|
|
158
|
-
isEmpty(): boolean {
|
|
159
|
-
return this.size === 0;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Removes all entries from the map.
|
|
164
|
-
* @remarks Time O(1), Space O(1)
|
|
165
154
|
|
|
166
155
|
|
|
167
156
|
|
|
@@ -200,56 +189,21 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
200
189
|
|
|
201
190
|
|
|
202
191
|
|
|
203
|
-
* @example
|
|
204
|
-
* // Remove all entries
|
|
205
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
206
|
-
* mm.add(1, 'a');
|
|
207
|
-
* mm.clear();
|
|
208
|
-
* console.log(mm.isEmpty()); // true;
|
|
209
|
-
*/
|
|
210
|
-
clear(): void {
|
|
211
|
-
this.#core.clear();
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Bucket length for a key (missing => 0).
|
|
216
|
-
* @remarks Time O(log n), Space O(1)
|
|
217
192
|
|
|
218
193
|
|
|
219
|
-
* @example
|
|
220
|
-
* // Count values for key
|
|
221
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
222
|
-
* mm.add(1, 'a');
|
|
223
|
-
* mm.add(1, 'b');
|
|
224
|
-
* console.log(mm.count(1)); // 2;
|
|
225
|
-
*/
|
|
226
|
-
count(key: K): number {
|
|
227
|
-
const b = this.get(key);
|
|
228
|
-
return Array.isArray(b) ? b.length : 0;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Total number of values across all buckets (Σ bucket.length).
|
|
233
|
-
* @remarks Time O(n), Space O(1)
|
|
234
194
|
|
|
235
195
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
return sum;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Whether the map contains the given key.
|
|
252
|
-
* @remarks Time O(log n), Space O(1)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
253
207
|
|
|
254
208
|
|
|
255
209
|
|
|
@@ -303,20 +257,25 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
303
257
|
|
|
304
258
|
|
|
305
259
|
* @example
|
|
306
|
-
* // Check
|
|
307
|
-
*
|
|
308
|
-
* mm.add(1, 'a');
|
|
309
|
-
* console.log(mm.has(1)); // true;
|
|
310
|
-
* console.log(mm.has(2)); // false;
|
|
260
|
+
* // Check if empty
|
|
261
|
+
* console.log(new TreeMultiMap().isEmpty()); // true;
|
|
311
262
|
*/
|
|
312
|
-
|
|
313
|
-
this.
|
|
314
|
-
return this.#core.has(key);
|
|
263
|
+
isEmpty(): boolean {
|
|
264
|
+
return this.size === 0;
|
|
315
265
|
}
|
|
316
266
|
|
|
317
267
|
/**
|
|
318
|
-
*
|
|
319
|
-
* @remarks Time O(
|
|
268
|
+
* Removes all entries from the map.
|
|
269
|
+
* @remarks Time O(1), Space O(1)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
320
279
|
|
|
321
280
|
|
|
322
281
|
|
|
@@ -369,21 +328,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
369
328
|
|
|
370
329
|
|
|
371
330
|
|
|
372
|
-
* @example
|
|
373
|
-
* // Get values for key
|
|
374
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
375
|
-
* mm.add(1, 'a');
|
|
376
|
-
* mm.add(1, 'b');
|
|
377
|
-
* console.log(mm.get(1)); // ['a', 'b'];
|
|
378
|
-
*/
|
|
379
|
-
get(key: K): V[] | undefined {
|
|
380
|
-
this._validateKey(key);
|
|
381
|
-
return this.#core.get(key);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Append a single value.
|
|
386
|
-
* @remarks Time O(log n), Space O(1)
|
|
387
331
|
|
|
388
332
|
|
|
389
333
|
|
|
@@ -416,27 +360,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
416
360
|
|
|
417
361
|
|
|
418
362
|
|
|
419
|
-
* @example
|
|
420
|
-
* // Add key-value pair
|
|
421
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
422
|
-
* mm.add(1, 'a');
|
|
423
|
-
* mm.add(1, 'b');
|
|
424
|
-
* mm.add(2, 'c');
|
|
425
|
-
* console.log(mm.get(1)); // ['a', 'b'];
|
|
426
|
-
*/
|
|
427
|
-
add(key: K, value: V): boolean {
|
|
428
|
-
this._validateKey(key);
|
|
429
|
-
const bucket = this.#core.get(key);
|
|
430
|
-
if (bucket) {
|
|
431
|
-
bucket.push(value);
|
|
432
|
-
return true;
|
|
433
|
-
}
|
|
434
|
-
return this.#core.set(key, [value]);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Alias for compatibility with existing TreeMultiMap semantics.
|
|
439
|
-
* @remarks Time O(log n), Space O(1) for single value; O(log n + m) for bucket append
|
|
440
363
|
|
|
441
364
|
|
|
442
365
|
|
|
@@ -488,39 +411,18 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
488
411
|
|
|
489
412
|
|
|
490
413
|
* @example
|
|
491
|
-
* //
|
|
414
|
+
* // Remove all entries
|
|
492
415
|
* const mm = new TreeMultiMap<number, string>();
|
|
493
|
-
* mm.
|
|
494
|
-
* mm.
|
|
495
|
-
* console.log(mm.
|
|
416
|
+
* mm.add(1, 'a');
|
|
417
|
+
* mm.clear();
|
|
418
|
+
* console.log(mm.isEmpty()); // true;
|
|
496
419
|
*/
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
set(entry: [K | null | undefined, V[] | undefined] | K | null | undefined, value?: V): boolean {
|
|
500
|
-
if (entry === null || entry === undefined) return false;
|
|
501
|
-
if (Array.isArray(entry)) {
|
|
502
|
-
const [k, bucket] = entry;
|
|
503
|
-
if (k === null || k === undefined) return false;
|
|
504
|
-
if (value !== undefined) return this.add(k as K, value);
|
|
505
|
-
if (bucket === undefined) {
|
|
506
|
-
// ensure key exists
|
|
507
|
-
return this.#core.set(k as K, [] as V[]);
|
|
508
|
-
}
|
|
509
|
-
// append bucket
|
|
510
|
-
const existing = this.#core.get(k as K);
|
|
511
|
-
if (existing) {
|
|
512
|
-
existing.push(...bucket);
|
|
513
|
-
return true;
|
|
514
|
-
}
|
|
515
|
-
return this.#core.set(k as K, [...bucket] as V[]);
|
|
516
|
-
}
|
|
517
|
-
// key-only or key+value
|
|
518
|
-
if (value !== undefined) return this.add(entry as K, value);
|
|
519
|
-
return this.#core.set(entry as K, [] as V[]);
|
|
420
|
+
clear(): void {
|
|
421
|
+
this.#core.clear();
|
|
520
422
|
}
|
|
521
423
|
|
|
522
424
|
/**
|
|
523
|
-
*
|
|
425
|
+
* Bucket length for a key (missing => 0).
|
|
524
426
|
* @remarks Time O(log n), Space O(1)
|
|
525
427
|
|
|
526
428
|
|
|
@@ -545,12 +447,21 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
545
447
|
|
|
546
448
|
|
|
547
449
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
450
|
+
* @example
|
|
451
|
+
* // Count values for key
|
|
452
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
453
|
+
* mm.add(1, 'a');
|
|
454
|
+
* mm.add(1, 'b');
|
|
455
|
+
* console.log(mm.count(1)); // 2;
|
|
456
|
+
*/
|
|
457
|
+
count(key: K): number {
|
|
458
|
+
const b = this.get(key);
|
|
459
|
+
return Array.isArray(b) ? b.length : 0;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Total number of values across all buckets (Σ bucket.length).
|
|
464
|
+
* @remarks Time O(n), Space O(1)
|
|
554
465
|
|
|
555
466
|
|
|
556
467
|
|
|
@@ -575,103 +486,2920 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
575
486
|
|
|
576
487
|
|
|
577
488
|
* @example
|
|
578
|
-
* //
|
|
489
|
+
* // Total number of values
|
|
579
490
|
* const mm = new TreeMultiMap<number, string>();
|
|
580
491
|
* mm.add(1, 'a');
|
|
581
|
-
* mm.add(
|
|
582
|
-
* mm.
|
|
583
|
-
* console.log(mm.
|
|
492
|
+
* mm.add(1, 'b');
|
|
493
|
+
* mm.add(2, 'c');
|
|
494
|
+
* console.log(mm.totalSize); // 3;
|
|
584
495
|
*/
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
496
|
+
get totalSize(): number {
|
|
497
|
+
let sum = 0;
|
|
498
|
+
for (const [, bucket] of this) sum += bucket.length;
|
|
499
|
+
return sum;
|
|
588
500
|
}
|
|
589
501
|
|
|
590
502
|
/**
|
|
591
|
-
*
|
|
592
|
-
* @remarks Time O(log n
|
|
503
|
+
* Whether the map contains the given key.
|
|
504
|
+
* @remarks Time O(log n), Space O(1)
|
|
593
505
|
|
|
594
506
|
|
|
595
|
-
* @example
|
|
596
|
-
* // Check specific key-value
|
|
597
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
598
|
-
* mm.add(1, 'a');
|
|
599
|
-
* console.log(mm.hasEntry(1, 'a')); // true;
|
|
600
|
-
* console.log(mm.hasEntry(1, 'z')); // false;
|
|
601
|
-
*/
|
|
602
|
-
hasEntry(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
|
|
603
|
-
const bucket = this.get(key);
|
|
604
|
-
if (!Array.isArray(bucket)) return false;
|
|
605
|
-
return bucket.some(v => eq(v, value));
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/**
|
|
609
|
-
* Delete a single occurrence of a value from a key's bucket.
|
|
610
|
-
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
611
507
|
|
|
612
508
|
|
|
613
|
-
* @example
|
|
614
|
-
* // Delete specific value
|
|
615
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
616
|
-
* mm.add(1, 'a');
|
|
617
|
-
* mm.add(1, 'b');
|
|
618
|
-
* mm.deleteValue(1, 'a');
|
|
619
|
-
* console.log(mm.get(1)); // ['b'];
|
|
620
|
-
*/
|
|
621
|
-
deleteValue(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
|
|
622
|
-
const bucket = this.get(key);
|
|
623
|
-
if (!Array.isArray(bucket)) return false;
|
|
624
|
-
const idx = bucket.findIndex(v => eq(v, value));
|
|
625
|
-
if (idx === -1) return false;
|
|
626
|
-
bucket.splice(idx, 1);
|
|
627
|
-
if (bucket.length === 0) this.delete(key);
|
|
628
|
-
return true;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* Delete all occurrences of a value from a key's bucket.
|
|
633
|
-
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
634
509
|
|
|
635
510
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
* @example
|
|
684
|
+
* // Check key existence
|
|
685
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
686
|
+
* mm.add(1, 'a');
|
|
687
|
+
* console.log(mm.has(1)); // true;
|
|
688
|
+
* console.log(mm.has(2)); // false;
|
|
689
|
+
*/
|
|
690
|
+
has(key: K): boolean {
|
|
691
|
+
this._validateKey(key);
|
|
692
|
+
return this.#core.has(key);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Live bucket reference (do not auto-delete key if bucket becomes empty via mutation).
|
|
697
|
+
* @remarks Time O(log n), Space O(1)
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
* @example
|
|
877
|
+
* // Get values for key
|
|
878
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
879
|
+
* mm.add(1, 'a');
|
|
880
|
+
* mm.add(1, 'b');
|
|
881
|
+
* console.log(mm.get(1)); // ['a', 'b'];
|
|
882
|
+
*/
|
|
883
|
+
get(key: K): V[] | undefined {
|
|
884
|
+
this._validateKey(key);
|
|
885
|
+
return this.#core.get(key);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Append a single value.
|
|
890
|
+
* @remarks Time O(log n), Space O(1)
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
* @example
|
|
1029
|
+
* // Add key-value pair
|
|
1030
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1031
|
+
* mm.add(1, 'a');
|
|
1032
|
+
* mm.add(1, 'b');
|
|
1033
|
+
* mm.add(2, 'c');
|
|
1034
|
+
* console.log(mm.get(1)); // ['a', 'b'];
|
|
1035
|
+
*/
|
|
1036
|
+
add(key: K, value: V): boolean {
|
|
1037
|
+
this._validateKey(key);
|
|
1038
|
+
const bucket = this.#core.get(key);
|
|
1039
|
+
if (bucket) {
|
|
1040
|
+
bucket.push(value);
|
|
1041
|
+
return true;
|
|
1042
|
+
}
|
|
1043
|
+
return this.#core.set(key, [value]);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Alias for compatibility with existing TreeMultiMap semantics.
|
|
1048
|
+
* @remarks Time O(log n), Space O(1) for single value; O(log n + m) for bucket append
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
* @example
|
|
1226
|
+
* // Set values for key
|
|
1227
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1228
|
+
* mm.set(1, 'a');
|
|
1229
|
+
* mm.set(1, 'b');
|
|
1230
|
+
* console.log(mm.get(1)); // ['a', 'b'];
|
|
1231
|
+
*/
|
|
1232
|
+
set(entry: [K | null | undefined, V[] | undefined] | K | null | undefined, value?: V): boolean;
|
|
1233
|
+
set(key: K, value: V): boolean;
|
|
1234
|
+
set(entry: [K | null | undefined, V[] | undefined] | K | null | undefined, value?: V): boolean {
|
|
1235
|
+
if (entry === null || entry === undefined) return false;
|
|
1236
|
+
if (Array.isArray(entry)) {
|
|
1237
|
+
const [k, bucket] = entry;
|
|
1238
|
+
if (k === null || k === undefined) return false;
|
|
1239
|
+
if (value !== undefined) return this.add(k as K, value);
|
|
1240
|
+
if (bucket === undefined) {
|
|
1241
|
+
// ensure key exists
|
|
1242
|
+
return this.#core.set(k as K, [] as V[]);
|
|
1243
|
+
}
|
|
1244
|
+
// append bucket
|
|
1245
|
+
const existing = this.#core.get(k as K);
|
|
1246
|
+
if (existing) {
|
|
1247
|
+
existing.push(...bucket);
|
|
1248
|
+
return true;
|
|
1249
|
+
}
|
|
1250
|
+
return this.#core.set(k as K, [...bucket] as V[]);
|
|
1251
|
+
}
|
|
1252
|
+
// key-only or key+value
|
|
1253
|
+
if (value !== undefined) return this.add(entry as K, value);
|
|
1254
|
+
return this.#core.set(entry as K, [] as V[]);
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
/**
|
|
1258
|
+
* Deletes a key and its entire bucket.
|
|
1259
|
+
* @remarks Time O(log n), Space O(1)
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
* @example
|
|
1439
|
+
* // Remove key
|
|
1440
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1441
|
+
* mm.add(1, 'a');
|
|
1442
|
+
* mm.add(2, 'b');
|
|
1443
|
+
* mm.delete(1);
|
|
1444
|
+
* console.log(mm.has(1)); // false;
|
|
1445
|
+
*/
|
|
1446
|
+
delete(key: K): boolean {
|
|
1447
|
+
this._validateKey(key);
|
|
1448
|
+
return this.#core.delete(key).length > 0;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/**
|
|
1452
|
+
* Check if a specific value exists in a key's bucket.
|
|
1453
|
+
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
* @example
|
|
1478
|
+
* // Check specific key-value
|
|
1479
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1480
|
+
* mm.add(1, 'a');
|
|
1481
|
+
* console.log(mm.hasEntry(1, 'a')); // true;
|
|
1482
|
+
* console.log(mm.hasEntry(1, 'z')); // false;
|
|
1483
|
+
*/
|
|
1484
|
+
hasEntry(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
|
|
1485
|
+
const bucket = this.get(key);
|
|
1486
|
+
if (!Array.isArray(bucket)) return false;
|
|
1487
|
+
return bucket.some(v => eq(v, value));
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
/**
|
|
1491
|
+
* Delete a single occurrence of a value from a key's bucket.
|
|
1492
|
+
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
* @example
|
|
1517
|
+
* // Delete specific value
|
|
1518
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1519
|
+
* mm.add(1, 'a');
|
|
1520
|
+
* mm.add(1, 'b');
|
|
1521
|
+
* mm.deleteValue(1, 'a');
|
|
1522
|
+
* console.log(mm.get(1)); // ['b'];
|
|
1523
|
+
*/
|
|
1524
|
+
deleteValue(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
|
|
1525
|
+
const bucket = this.get(key);
|
|
1526
|
+
if (!Array.isArray(bucket)) return false;
|
|
1527
|
+
const idx = bucket.findIndex(v => eq(v, value));
|
|
1528
|
+
if (idx === -1) return false;
|
|
1529
|
+
bucket.splice(idx, 1);
|
|
1530
|
+
if (bucket.length === 0) this.delete(key);
|
|
1531
|
+
return true;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
/**
|
|
1535
|
+
* Delete all occurrences of a value from a key's bucket.
|
|
1536
|
+
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
* @example
|
|
1561
|
+
* // Delete all matching values
|
|
1562
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1563
|
+
* mm.add(1, 'a');
|
|
1564
|
+
* mm.add(1, 'a');
|
|
1565
|
+
* mm.add(1, 'b');
|
|
1566
|
+
* const count = mm.deleteValues(1, 'a');
|
|
1567
|
+
* console.log(count); // 2;
|
|
1568
|
+
*/
|
|
1569
|
+
deleteValues(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): number {
|
|
1570
|
+
const bucket = this.get(key);
|
|
1571
|
+
if (!Array.isArray(bucket) || bucket.length === 0) return 0;
|
|
1572
|
+
let removed = 0;
|
|
1573
|
+
for (let i = bucket.length - 1; i >= 0; i--) {
|
|
1574
|
+
if (eq(bucket[i] as V, value)) {
|
|
651
1575
|
bucket.splice(i, 1);
|
|
652
1576
|
removed++;
|
|
653
1577
|
}
|
|
654
1578
|
}
|
|
655
|
-
if (bucket.length === 0 && removed > 0) this.delete(key);
|
|
656
|
-
return removed;
|
|
1579
|
+
if (bucket.length === 0 && removed > 0) this.delete(key);
|
|
1580
|
+
return removed;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// ---- iteration (bucket view) ----
|
|
1584
|
+
|
|
1585
|
+
/**
|
|
1586
|
+
* Iterates over all entries as [key, bucket] pairs.
|
|
1587
|
+
* @remarks Time O(n), Space O(1)
|
|
1588
|
+
*/
|
|
1589
|
+
*[Symbol.iterator](): Iterator<[K, V[]]> {
|
|
1590
|
+
for (const [k, v] of this.#core) {
|
|
1591
|
+
// core always stores buckets, but guard anyway
|
|
1592
|
+
yield [k, v ?? /* istanbul ignore next */ ([] as V[])];
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
/**
|
|
1597
|
+
* Iterates over all keys.
|
|
1598
|
+
* @remarks Time O(n), Space O(1)
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
|
|
1604
|
+
|
|
1605
|
+
|
|
1606
|
+
|
|
1607
|
+
|
|
1608
|
+
|
|
1609
|
+
|
|
1610
|
+
|
|
1611
|
+
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
|
|
1615
|
+
|
|
1616
|
+
|
|
1617
|
+
|
|
1618
|
+
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
|
|
1625
|
+
|
|
1626
|
+
|
|
1627
|
+
|
|
1628
|
+
|
|
1629
|
+
|
|
1630
|
+
|
|
1631
|
+
|
|
1632
|
+
|
|
1633
|
+
|
|
1634
|
+
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
|
|
1639
|
+
|
|
1640
|
+
|
|
1641
|
+
|
|
1642
|
+
|
|
1643
|
+
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
|
|
1647
|
+
|
|
1648
|
+
|
|
1649
|
+
|
|
1650
|
+
|
|
1651
|
+
|
|
1652
|
+
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
|
|
1662
|
+
|
|
1663
|
+
|
|
1664
|
+
|
|
1665
|
+
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
|
|
1669
|
+
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
|
|
1681
|
+
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
|
|
1685
|
+
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
|
|
1692
|
+
|
|
1693
|
+
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
|
|
1697
|
+
|
|
1698
|
+
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
|
|
1705
|
+
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
|
|
1709
|
+
|
|
1710
|
+
|
|
1711
|
+
|
|
1712
|
+
|
|
1713
|
+
|
|
1714
|
+
|
|
1715
|
+
|
|
1716
|
+
|
|
1717
|
+
|
|
1718
|
+
|
|
1719
|
+
|
|
1720
|
+
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
|
|
1725
|
+
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
|
|
1738
|
+
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
* @example
|
|
1743
|
+
* // Iterate keys
|
|
1744
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1745
|
+
* mm.add(3, 'c');
|
|
1746
|
+
* mm.add(1, 'a');
|
|
1747
|
+
* console.log([...mm.keys()]); // [1, 3];
|
|
1748
|
+
*/
|
|
1749
|
+
*keys(): IterableIterator<K> {
|
|
1750
|
+
yield* this.#core.keys();
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
/**
|
|
1754
|
+
* Iterates over all buckets.
|
|
1755
|
+
* @remarks Time O(n), Space O(1)
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
|
|
1769
|
+
|
|
1770
|
+
|
|
1771
|
+
|
|
1772
|
+
|
|
1773
|
+
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
|
|
1777
|
+
|
|
1778
|
+
|
|
1779
|
+
|
|
1780
|
+
|
|
1781
|
+
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
|
|
1835
|
+
|
|
1836
|
+
|
|
1837
|
+
|
|
1838
|
+
|
|
1839
|
+
|
|
1840
|
+
|
|
1841
|
+
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
|
|
1854
|
+
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
|
|
1884
|
+
|
|
1885
|
+
|
|
1886
|
+
|
|
1887
|
+
|
|
1888
|
+
|
|
1889
|
+
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
|
|
1896
|
+
|
|
1897
|
+
|
|
1898
|
+
|
|
1899
|
+
* @example
|
|
1900
|
+
* // Iterate value arrays
|
|
1901
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1902
|
+
* mm.add(1, 'a');
|
|
1903
|
+
* mm.add(1, 'b');
|
|
1904
|
+
* console.log([...mm.values()]); // [['a', 'b']];
|
|
1905
|
+
*/
|
|
1906
|
+
*values(): IterableIterator<V[]> {
|
|
1907
|
+
for (const [, bucket] of this) yield bucket;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
// ---- entry-flat views ----
|
|
1911
|
+
|
|
1912
|
+
/**
|
|
1913
|
+
* Iterates over all entries for a specific key.
|
|
1914
|
+
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
1915
|
+
|
|
1916
|
+
|
|
1917
|
+
|
|
1918
|
+
|
|
1919
|
+
|
|
1920
|
+
|
|
1921
|
+
|
|
1922
|
+
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
|
|
1938
|
+
* @example
|
|
1939
|
+
* // Get entries for key
|
|
1940
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1941
|
+
* mm.add(1, 'a');
|
|
1942
|
+
* mm.add(1, 'b');
|
|
1943
|
+
* console.log([...mm.entriesOf(1)]); // [[1, 'a'], [1, 'b']];
|
|
1944
|
+
*/
|
|
1945
|
+
*entriesOf(key: K): IterableIterator<[K, V]> {
|
|
1946
|
+
const bucket = this.get(key);
|
|
1947
|
+
if (!Array.isArray(bucket)) return;
|
|
1948
|
+
for (const v of bucket) yield [key, v];
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* Iterates over all values for a specific key.
|
|
1953
|
+
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
1954
|
+
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
|
|
1958
|
+
|
|
1959
|
+
|
|
1960
|
+
|
|
1961
|
+
|
|
1962
|
+
|
|
1963
|
+
|
|
1964
|
+
|
|
1965
|
+
|
|
1966
|
+
|
|
1967
|
+
|
|
1968
|
+
|
|
1969
|
+
|
|
1970
|
+
|
|
1971
|
+
|
|
1972
|
+
|
|
1973
|
+
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
|
|
1977
|
+
* @example
|
|
1978
|
+
* // Get flat values for key
|
|
1979
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
1980
|
+
* mm.add(1, 'a');
|
|
1981
|
+
* mm.add(1, 'b');
|
|
1982
|
+
* console.log([...mm.valuesOf(1)]); // ['a', 'b'];
|
|
1983
|
+
*/
|
|
1984
|
+
*valuesOf(key: K): IterableIterator<V> {
|
|
1985
|
+
const bucket = this.get(key);
|
|
1986
|
+
if (!Array.isArray(bucket)) return;
|
|
1987
|
+
yield* bucket;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
/**
|
|
1991
|
+
* Iterates over all [key, value] pairs (flattened from buckets).
|
|
1992
|
+
* @remarks Time O(T), Space O(1) where T is totalSize
|
|
1993
|
+
|
|
1994
|
+
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
|
|
2001
|
+
|
|
2002
|
+
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+
|
|
2012
|
+
|
|
2013
|
+
|
|
2014
|
+
|
|
2015
|
+
|
|
2016
|
+
* @example
|
|
2017
|
+
* // All key-value pairs flattened
|
|
2018
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2019
|
+
* mm.add(1, 'a');
|
|
2020
|
+
* mm.add(1, 'b');
|
|
2021
|
+
* mm.add(2, 'c');
|
|
2022
|
+
* console.log([...mm.flatEntries()]); // [[1, 'a'], [1, 'b'], [2, 'c']];
|
|
2023
|
+
*/
|
|
2024
|
+
*flatEntries(): IterableIterator<[K, V]> {
|
|
2025
|
+
for (const [k, bucket] of this) {
|
|
2026
|
+
for (const v of bucket) yield [k, v];
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// ━━━ Navigable methods (return [K, V[]] | undefined) ━━━
|
|
2031
|
+
|
|
2032
|
+
/**
|
|
2033
|
+
* Returns the entry with the smallest key.
|
|
2034
|
+
* @remarks Time O(log n), Space O(1)
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
|
|
2039
|
+
|
|
2040
|
+
|
|
2041
|
+
|
|
2042
|
+
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
|
|
2055
|
+
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
|
|
2059
|
+
|
|
2060
|
+
|
|
2061
|
+
|
|
2062
|
+
|
|
2063
|
+
|
|
2064
|
+
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
|
|
2070
|
+
|
|
2071
|
+
|
|
2072
|
+
|
|
2073
|
+
|
|
2074
|
+
|
|
2075
|
+
|
|
2076
|
+
|
|
2077
|
+
|
|
2078
|
+
|
|
2079
|
+
|
|
2080
|
+
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
|
|
2088
|
+
|
|
2089
|
+
|
|
2090
|
+
|
|
2091
|
+
* @example
|
|
2092
|
+
* // First entry
|
|
2093
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2094
|
+
* mm.add(3, 'c');
|
|
2095
|
+
* mm.add(1, 'a');
|
|
2096
|
+
* console.log(mm.first()?.[0]); // 1;
|
|
2097
|
+
*/
|
|
2098
|
+
first(): [K, V[]] | undefined {
|
|
2099
|
+
const k = this.#core.getLeftMost();
|
|
2100
|
+
if (k === undefined) return undefined;
|
|
2101
|
+
const b = this.get(k);
|
|
2102
|
+
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
/**
|
|
2106
|
+
* Returns the entry with the largest key.
|
|
2107
|
+
* @remarks Time O(log n), Space O(1)
|
|
2108
|
+
|
|
2109
|
+
|
|
2110
|
+
|
|
2111
|
+
|
|
2112
|
+
|
|
2113
|
+
|
|
2114
|
+
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
|
|
2119
|
+
|
|
2120
|
+
|
|
2121
|
+
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
|
|
2125
|
+
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
|
|
2131
|
+
|
|
2132
|
+
|
|
2133
|
+
|
|
2134
|
+
|
|
2135
|
+
|
|
2136
|
+
|
|
2137
|
+
|
|
2138
|
+
|
|
2139
|
+
|
|
2140
|
+
|
|
2141
|
+
|
|
2142
|
+
|
|
2143
|
+
|
|
2144
|
+
|
|
2145
|
+
|
|
2146
|
+
|
|
2147
|
+
|
|
2148
|
+
|
|
2149
|
+
|
|
2150
|
+
|
|
2151
|
+
|
|
2152
|
+
|
|
2153
|
+
|
|
2154
|
+
|
|
2155
|
+
|
|
2156
|
+
|
|
2157
|
+
|
|
2158
|
+
|
|
2159
|
+
|
|
2160
|
+
|
|
2161
|
+
|
|
2162
|
+
|
|
2163
|
+
|
|
2164
|
+
* @example
|
|
2165
|
+
* // Last entry
|
|
2166
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2167
|
+
* mm.add(1, 'a');
|
|
2168
|
+
* mm.add(3, 'c');
|
|
2169
|
+
* console.log(mm.last()?.[0]); // 3;
|
|
2170
|
+
*/
|
|
2171
|
+
last(): [K, V[]] | undefined {
|
|
2172
|
+
const k = this.#core.getRightMost();
|
|
2173
|
+
if (k === undefined) return undefined;
|
|
2174
|
+
const b = this.get(k);
|
|
2175
|
+
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
2176
|
+
}
|
|
2177
|
+
|
|
2178
|
+
/**
|
|
2179
|
+
* Removes and returns the entry with the smallest key.
|
|
2180
|
+
* @remarks Time O(log n), Space O(1)
|
|
2181
|
+
|
|
2182
|
+
|
|
2183
|
+
|
|
2184
|
+
|
|
2185
|
+
|
|
2186
|
+
|
|
2187
|
+
|
|
2188
|
+
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
|
|
2196
|
+
|
|
2197
|
+
|
|
2198
|
+
|
|
2199
|
+
|
|
2200
|
+
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
|
|
2205
|
+
* @example
|
|
2206
|
+
* // Remove and return first
|
|
2207
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2208
|
+
* mm.add(2, 'b');
|
|
2209
|
+
* mm.add(1, 'a');
|
|
2210
|
+
* const first = mm.pollFirst();
|
|
2211
|
+
* console.log(first?.[0]); // 1;
|
|
2212
|
+
* console.log(mm.has(1)); // false;
|
|
2213
|
+
*/
|
|
2214
|
+
pollFirst(): [K, V[]] | undefined {
|
|
2215
|
+
const e = this.first();
|
|
2216
|
+
if (!e) return undefined;
|
|
2217
|
+
this.delete(e[0]);
|
|
2218
|
+
return e;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
/**
|
|
2222
|
+
* Removes and returns the entry with the largest key.
|
|
2223
|
+
* @remarks Time O(log n), Space O(1)
|
|
2224
|
+
|
|
2225
|
+
|
|
2226
|
+
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
|
|
2232
|
+
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
|
|
2247
|
+
|
|
2248
|
+
* @example
|
|
2249
|
+
* // Remove and return last
|
|
2250
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2251
|
+
* mm.add(1, 'a');
|
|
2252
|
+
* mm.add(3, 'c');
|
|
2253
|
+
* const last = mm.pollLast();
|
|
2254
|
+
* console.log(last?.[0]); // 3;
|
|
2255
|
+
*/
|
|
2256
|
+
pollLast(): [K, V[]] | undefined {
|
|
2257
|
+
const e = this.last();
|
|
2258
|
+
if (!e) return undefined;
|
|
2259
|
+
this.delete(e[0]);
|
|
2260
|
+
return e;
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
/**
|
|
2264
|
+
* Returns the entry with the smallest key >= given key.
|
|
2265
|
+
* @remarks Time O(log n), Space O(1)
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
|
|
2269
|
+
|
|
2270
|
+
|
|
2271
|
+
|
|
2272
|
+
|
|
2273
|
+
|
|
2274
|
+
|
|
2275
|
+
|
|
2276
|
+
|
|
2277
|
+
|
|
2278
|
+
|
|
2279
|
+
|
|
2280
|
+
|
|
2281
|
+
|
|
2282
|
+
|
|
2283
|
+
|
|
2284
|
+
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
|
|
2289
|
+
|
|
2290
|
+
|
|
2291
|
+
|
|
2292
|
+
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
|
|
2296
|
+
|
|
2297
|
+
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
|
|
2301
|
+
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
|
|
2309
|
+
|
|
2310
|
+
|
|
2311
|
+
|
|
2312
|
+
|
|
2313
|
+
|
|
2314
|
+
|
|
2315
|
+
|
|
2316
|
+
|
|
2317
|
+
|
|
2318
|
+
|
|
2319
|
+
|
|
2320
|
+
|
|
2321
|
+
|
|
2322
|
+
|
|
2323
|
+
|
|
2324
|
+
|
|
2325
|
+
|
|
2326
|
+
|
|
2327
|
+
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
|
|
2336
|
+
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
|
|
2341
|
+
|
|
2342
|
+
|
|
2343
|
+
|
|
2344
|
+
|
|
2345
|
+
|
|
2346
|
+
|
|
2347
|
+
|
|
2348
|
+
|
|
2349
|
+
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
|
|
2353
|
+
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
|
|
2357
|
+
|
|
2358
|
+
|
|
2359
|
+
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
|
|
2363
|
+
|
|
2364
|
+
|
|
2365
|
+
|
|
2366
|
+
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
|
|
2370
|
+
|
|
2371
|
+
|
|
2372
|
+
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
|
|
2379
|
+
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
|
|
2385
|
+
|
|
2386
|
+
|
|
2387
|
+
|
|
2388
|
+
|
|
2389
|
+
|
|
2390
|
+
|
|
2391
|
+
|
|
2392
|
+
|
|
2393
|
+
|
|
2394
|
+
|
|
2395
|
+
|
|
2396
|
+
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
|
|
2400
|
+
|
|
2401
|
+
|
|
2402
|
+
|
|
2403
|
+
|
|
2404
|
+
|
|
2405
|
+
|
|
2406
|
+
|
|
2407
|
+
|
|
2408
|
+
|
|
2409
|
+
|
|
2410
|
+
|
|
2411
|
+
|
|
2412
|
+
* @example
|
|
2413
|
+
* // Least key ≥ target
|
|
2414
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2415
|
+
* mm.add(10, 'a');
|
|
2416
|
+
* mm.add(20, 'b');
|
|
2417
|
+
* mm.add(30, 'c');
|
|
2418
|
+
* console.log(mm.ceiling(15)?.[0]); // 20;
|
|
2419
|
+
*/
|
|
2420
|
+
ceiling(key: K): [K, V[]] | undefined {
|
|
2421
|
+
this._validateKey(key);
|
|
2422
|
+
const k = this.#core.ceiling(key);
|
|
2423
|
+
if (k === undefined) return undefined;
|
|
2424
|
+
const b = this.get(k);
|
|
2425
|
+
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
/**
|
|
2429
|
+
* Returns the entry with the largest key <= given key.
|
|
2430
|
+
* @remarks Time O(log n), Space O(1)
|
|
2431
|
+
|
|
2432
|
+
|
|
2433
|
+
|
|
2434
|
+
|
|
2435
|
+
|
|
2436
|
+
|
|
2437
|
+
|
|
2438
|
+
|
|
2439
|
+
|
|
2440
|
+
|
|
2441
|
+
|
|
2442
|
+
|
|
2443
|
+
|
|
2444
|
+
|
|
2445
|
+
|
|
2446
|
+
|
|
2447
|
+
|
|
2448
|
+
|
|
2449
|
+
|
|
2450
|
+
|
|
2451
|
+
|
|
2452
|
+
|
|
2453
|
+
|
|
2454
|
+
|
|
2455
|
+
|
|
2456
|
+
|
|
2457
|
+
|
|
2458
|
+
|
|
2459
|
+
|
|
2460
|
+
|
|
2461
|
+
|
|
2462
|
+
|
|
2463
|
+
|
|
2464
|
+
|
|
2465
|
+
|
|
2466
|
+
|
|
2467
|
+
|
|
2468
|
+
|
|
2469
|
+
|
|
2470
|
+
|
|
2471
|
+
|
|
2472
|
+
|
|
2473
|
+
|
|
2474
|
+
|
|
2475
|
+
|
|
2476
|
+
|
|
2477
|
+
|
|
2478
|
+
|
|
2479
|
+
|
|
2480
|
+
|
|
2481
|
+
|
|
2482
|
+
|
|
2483
|
+
|
|
2484
|
+
|
|
2485
|
+
|
|
2486
|
+
|
|
2487
|
+
|
|
2488
|
+
|
|
2489
|
+
|
|
2490
|
+
|
|
2491
|
+
|
|
2492
|
+
|
|
2493
|
+
|
|
2494
|
+
|
|
2495
|
+
|
|
2496
|
+
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
|
|
2505
|
+
|
|
2506
|
+
|
|
2507
|
+
|
|
2508
|
+
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
|
|
2512
|
+
|
|
2513
|
+
|
|
2514
|
+
|
|
2515
|
+
|
|
2516
|
+
|
|
2517
|
+
|
|
2518
|
+
|
|
2519
|
+
|
|
2520
|
+
|
|
2521
|
+
|
|
2522
|
+
|
|
2523
|
+
|
|
2524
|
+
|
|
2525
|
+
|
|
2526
|
+
|
|
2527
|
+
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
|
|
2537
|
+
|
|
2538
|
+
|
|
2539
|
+
|
|
2540
|
+
|
|
2541
|
+
|
|
2542
|
+
|
|
2543
|
+
|
|
2544
|
+
|
|
2545
|
+
|
|
2546
|
+
|
|
2547
|
+
|
|
2548
|
+
|
|
2549
|
+
|
|
2550
|
+
|
|
2551
|
+
|
|
2552
|
+
|
|
2553
|
+
|
|
2554
|
+
|
|
2555
|
+
|
|
2556
|
+
|
|
2557
|
+
|
|
2558
|
+
|
|
2559
|
+
|
|
2560
|
+
|
|
2561
|
+
|
|
2562
|
+
|
|
2563
|
+
|
|
2564
|
+
|
|
2565
|
+
|
|
2566
|
+
|
|
2567
|
+
|
|
2568
|
+
|
|
2569
|
+
|
|
2570
|
+
|
|
2571
|
+
|
|
2572
|
+
|
|
2573
|
+
|
|
2574
|
+
|
|
2575
|
+
|
|
2576
|
+
|
|
2577
|
+
* @example
|
|
2578
|
+
* // Greatest key ≤ target
|
|
2579
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2580
|
+
* mm.add(10, 'a');
|
|
2581
|
+
* mm.add(20, 'b');
|
|
2582
|
+
* mm.add(30, 'c');
|
|
2583
|
+
* console.log(mm.floor(25)?.[0]); // 20;
|
|
2584
|
+
*/
|
|
2585
|
+
floor(key: K): [K, V[]] | undefined {
|
|
2586
|
+
this._validateKey(key);
|
|
2587
|
+
const k = this.#core.floor(key);
|
|
2588
|
+
if (k === undefined) return undefined;
|
|
2589
|
+
const b = this.get(k);
|
|
2590
|
+
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
/**
|
|
2594
|
+
* Returns the entry with the smallest key > given key.
|
|
2595
|
+
* @remarks Time O(log n), Space O(1)
|
|
2596
|
+
|
|
2597
|
+
|
|
2598
|
+
|
|
2599
|
+
|
|
2600
|
+
|
|
2601
|
+
|
|
2602
|
+
|
|
2603
|
+
|
|
2604
|
+
|
|
2605
|
+
|
|
2606
|
+
|
|
2607
|
+
|
|
2608
|
+
|
|
2609
|
+
|
|
2610
|
+
|
|
2611
|
+
|
|
2612
|
+
|
|
2613
|
+
|
|
2614
|
+
|
|
2615
|
+
|
|
2616
|
+
|
|
2617
|
+
|
|
2618
|
+
|
|
2619
|
+
|
|
2620
|
+
|
|
2621
|
+
|
|
2622
|
+
|
|
2623
|
+
|
|
2624
|
+
|
|
2625
|
+
|
|
2626
|
+
|
|
2627
|
+
|
|
2628
|
+
|
|
2629
|
+
|
|
2630
|
+
|
|
2631
|
+
|
|
2632
|
+
|
|
2633
|
+
|
|
2634
|
+
|
|
2635
|
+
|
|
2636
|
+
|
|
2637
|
+
|
|
2638
|
+
|
|
2639
|
+
|
|
2640
|
+
|
|
2641
|
+
|
|
2642
|
+
|
|
2643
|
+
|
|
2644
|
+
|
|
2645
|
+
|
|
2646
|
+
|
|
2647
|
+
|
|
2648
|
+
|
|
2649
|
+
|
|
2650
|
+
|
|
2651
|
+
|
|
2652
|
+
|
|
2653
|
+
|
|
2654
|
+
|
|
2655
|
+
|
|
2656
|
+
|
|
2657
|
+
|
|
2658
|
+
|
|
2659
|
+
|
|
2660
|
+
|
|
2661
|
+
|
|
2662
|
+
|
|
2663
|
+
|
|
2664
|
+
|
|
2665
|
+
|
|
2666
|
+
|
|
2667
|
+
|
|
2668
|
+
|
|
2669
|
+
|
|
2670
|
+
|
|
2671
|
+
|
|
2672
|
+
|
|
2673
|
+
|
|
2674
|
+
|
|
2675
|
+
|
|
2676
|
+
|
|
2677
|
+
|
|
2678
|
+
|
|
2679
|
+
|
|
2680
|
+
|
|
2681
|
+
|
|
2682
|
+
|
|
2683
|
+
|
|
2684
|
+
|
|
2685
|
+
|
|
2686
|
+
|
|
2687
|
+
|
|
2688
|
+
|
|
2689
|
+
|
|
2690
|
+
|
|
2691
|
+
|
|
2692
|
+
|
|
2693
|
+
|
|
2694
|
+
|
|
2695
|
+
|
|
2696
|
+
|
|
2697
|
+
|
|
2698
|
+
|
|
2699
|
+
|
|
2700
|
+
|
|
2701
|
+
|
|
2702
|
+
|
|
2703
|
+
|
|
2704
|
+
|
|
2705
|
+
|
|
2706
|
+
|
|
2707
|
+
|
|
2708
|
+
|
|
2709
|
+
|
|
2710
|
+
* @example
|
|
2711
|
+
* // Least key > target
|
|
2712
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2713
|
+
* mm.add(10, 'a');
|
|
2714
|
+
* mm.add(20, 'b');
|
|
2715
|
+
* console.log(mm.higher(10)?.[0]); // 20;
|
|
2716
|
+
*/
|
|
2717
|
+
higher(key: K): [K, V[]] | undefined {
|
|
2718
|
+
this._validateKey(key);
|
|
2719
|
+
const k = this.#core.higher(key);
|
|
2720
|
+
if (k === undefined) return undefined;
|
|
2721
|
+
const b = this.get(k);
|
|
2722
|
+
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
/**
|
|
2726
|
+
* Returns the entry with the largest key < given key.
|
|
2727
|
+
* @remarks Time O(log n), Space O(1)
|
|
2728
|
+
|
|
2729
|
+
|
|
2730
|
+
|
|
2731
|
+
|
|
2732
|
+
|
|
2733
|
+
|
|
2734
|
+
|
|
2735
|
+
|
|
2736
|
+
|
|
2737
|
+
|
|
2738
|
+
|
|
2739
|
+
|
|
2740
|
+
|
|
2741
|
+
|
|
2742
|
+
|
|
2743
|
+
|
|
2744
|
+
|
|
2745
|
+
|
|
2746
|
+
|
|
2747
|
+
|
|
2748
|
+
|
|
2749
|
+
|
|
2750
|
+
|
|
2751
|
+
|
|
2752
|
+
|
|
2753
|
+
|
|
2754
|
+
|
|
2755
|
+
|
|
2756
|
+
|
|
2757
|
+
|
|
2758
|
+
|
|
2759
|
+
|
|
2760
|
+
|
|
2761
|
+
|
|
2762
|
+
|
|
2763
|
+
|
|
2764
|
+
|
|
2765
|
+
|
|
2766
|
+
|
|
2767
|
+
|
|
2768
|
+
|
|
2769
|
+
|
|
2770
|
+
|
|
2771
|
+
|
|
2772
|
+
|
|
2773
|
+
|
|
2774
|
+
|
|
2775
|
+
|
|
2776
|
+
|
|
2777
|
+
|
|
2778
|
+
|
|
2779
|
+
|
|
2780
|
+
|
|
2781
|
+
|
|
2782
|
+
|
|
2783
|
+
|
|
2784
|
+
|
|
2785
|
+
|
|
2786
|
+
|
|
2787
|
+
|
|
2788
|
+
|
|
2789
|
+
|
|
2790
|
+
|
|
2791
|
+
|
|
2792
|
+
|
|
2793
|
+
|
|
2794
|
+
|
|
2795
|
+
|
|
2796
|
+
|
|
2797
|
+
|
|
2798
|
+
|
|
2799
|
+
|
|
2800
|
+
|
|
2801
|
+
|
|
2802
|
+
|
|
2803
|
+
|
|
2804
|
+
|
|
2805
|
+
|
|
2806
|
+
|
|
2807
|
+
|
|
2808
|
+
|
|
2809
|
+
|
|
2810
|
+
|
|
2811
|
+
|
|
2812
|
+
|
|
2813
|
+
|
|
2814
|
+
|
|
2815
|
+
|
|
2816
|
+
|
|
2817
|
+
|
|
2818
|
+
|
|
2819
|
+
|
|
2820
|
+
|
|
2821
|
+
|
|
2822
|
+
|
|
2823
|
+
|
|
2824
|
+
|
|
2825
|
+
|
|
2826
|
+
|
|
2827
|
+
|
|
2828
|
+
|
|
2829
|
+
|
|
2830
|
+
|
|
2831
|
+
|
|
2832
|
+
|
|
2833
|
+
|
|
2834
|
+
|
|
2835
|
+
|
|
2836
|
+
|
|
2837
|
+
|
|
2838
|
+
|
|
2839
|
+
|
|
2840
|
+
|
|
2841
|
+
|
|
2842
|
+
* @example
|
|
2843
|
+
* // Greatest key < target
|
|
2844
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
2845
|
+
* mm.add(10, 'a');
|
|
2846
|
+
* mm.add(20, 'b');
|
|
2847
|
+
* console.log(mm.lower(20)?.[0]); // 10;
|
|
2848
|
+
*/
|
|
2849
|
+
lower(key: K): [K, V[]] | undefined {
|
|
2850
|
+
this._validateKey(key);
|
|
2851
|
+
const k = this.#core.lower(key);
|
|
2852
|
+
if (k === undefined) return undefined;
|
|
2853
|
+
const b = this.get(k);
|
|
2854
|
+
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
// ━━━ Tree utilities ━━━
|
|
2858
|
+
|
|
2859
|
+
/**
|
|
2860
|
+
* Prints the internal tree structure (for debugging).
|
|
2861
|
+
* @remarks Time O(n), Space O(n)
|
|
2862
|
+
|
|
2863
|
+
|
|
2864
|
+
|
|
2865
|
+
|
|
2866
|
+
|
|
2867
|
+
|
|
2868
|
+
|
|
2869
|
+
|
|
2870
|
+
|
|
2871
|
+
|
|
2872
|
+
|
|
2873
|
+
|
|
2874
|
+
|
|
2875
|
+
|
|
2876
|
+
|
|
2877
|
+
|
|
2878
|
+
|
|
2879
|
+
|
|
2880
|
+
|
|
2881
|
+
|
|
2882
|
+
|
|
2883
|
+
|
|
2884
|
+
|
|
2885
|
+
|
|
2886
|
+
|
|
2887
|
+
|
|
2888
|
+
|
|
2889
|
+
|
|
2890
|
+
|
|
2891
|
+
|
|
2892
|
+
|
|
2893
|
+
|
|
2894
|
+
|
|
2895
|
+
|
|
2896
|
+
|
|
2897
|
+
|
|
2898
|
+
|
|
2899
|
+
|
|
2900
|
+
|
|
2901
|
+
|
|
2902
|
+
|
|
2903
|
+
|
|
2904
|
+
|
|
2905
|
+
|
|
2906
|
+
|
|
2907
|
+
|
|
2908
|
+
|
|
2909
|
+
|
|
2910
|
+
|
|
2911
|
+
|
|
2912
|
+
|
|
2913
|
+
|
|
2914
|
+
|
|
2915
|
+
|
|
2916
|
+
|
|
2917
|
+
|
|
2918
|
+
|
|
2919
|
+
|
|
2920
|
+
|
|
2921
|
+
|
|
2922
|
+
|
|
2923
|
+
|
|
2924
|
+
|
|
2925
|
+
|
|
2926
|
+
|
|
2927
|
+
|
|
2928
|
+
|
|
2929
|
+
|
|
2930
|
+
|
|
2931
|
+
|
|
2932
|
+
|
|
2933
|
+
|
|
2934
|
+
|
|
2935
|
+
|
|
2936
|
+
|
|
2937
|
+
|
|
2938
|
+
|
|
2939
|
+
|
|
2940
|
+
|
|
2941
|
+
|
|
2942
|
+
|
|
2943
|
+
|
|
2944
|
+
|
|
2945
|
+
|
|
2946
|
+
|
|
2947
|
+
|
|
2948
|
+
|
|
2949
|
+
|
|
2950
|
+
|
|
2951
|
+
|
|
2952
|
+
|
|
2953
|
+
|
|
2954
|
+
|
|
2955
|
+
|
|
2956
|
+
|
|
2957
|
+
|
|
2958
|
+
|
|
2959
|
+
|
|
2960
|
+
|
|
2961
|
+
|
|
2962
|
+
|
|
2963
|
+
|
|
2964
|
+
|
|
2965
|
+
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
|
|
2969
|
+
|
|
2970
|
+
|
|
2971
|
+
|
|
2972
|
+
|
|
2973
|
+
|
|
2974
|
+
|
|
2975
|
+
|
|
2976
|
+
|
|
2977
|
+
|
|
2978
|
+
|
|
2979
|
+
|
|
2980
|
+
|
|
2981
|
+
|
|
2982
|
+
|
|
2983
|
+
|
|
2984
|
+
|
|
2985
|
+
|
|
2986
|
+
|
|
2987
|
+
|
|
2988
|
+
|
|
2989
|
+
|
|
2990
|
+
|
|
2991
|
+
|
|
2992
|
+
|
|
2993
|
+
|
|
2994
|
+
|
|
2995
|
+
|
|
2996
|
+
|
|
2997
|
+
|
|
2998
|
+
|
|
2999
|
+
|
|
3000
|
+
|
|
3001
|
+
|
|
3002
|
+
|
|
3003
|
+
|
|
3004
|
+
|
|
3005
|
+
* @example
|
|
3006
|
+
* // Display tree
|
|
3007
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
3008
|
+
* mm.add(1, 'a');
|
|
3009
|
+
* expect(() => mm.print()).not.toThrow();
|
|
3010
|
+
*/
|
|
3011
|
+
print(): void {
|
|
3012
|
+
this.#core.print();
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
/**
|
|
3016
|
+
* Executes a callback for each entry.
|
|
3017
|
+
* @remarks Time O(n), Space O(1)
|
|
3018
|
+
|
|
3019
|
+
|
|
3020
|
+
|
|
3021
|
+
|
|
3022
|
+
|
|
3023
|
+
|
|
3024
|
+
|
|
3025
|
+
|
|
3026
|
+
|
|
3027
|
+
|
|
3028
|
+
|
|
3029
|
+
|
|
3030
|
+
|
|
3031
|
+
|
|
3032
|
+
|
|
3033
|
+
|
|
3034
|
+
|
|
3035
|
+
|
|
3036
|
+
|
|
3037
|
+
|
|
3038
|
+
|
|
3039
|
+
|
|
3040
|
+
|
|
3041
|
+
|
|
3042
|
+
|
|
3043
|
+
|
|
3044
|
+
|
|
3045
|
+
|
|
3046
|
+
|
|
3047
|
+
|
|
3048
|
+
|
|
3049
|
+
|
|
3050
|
+
|
|
3051
|
+
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
|
|
3055
|
+
|
|
3056
|
+
|
|
3057
|
+
|
|
3058
|
+
|
|
3059
|
+
|
|
3060
|
+
|
|
3061
|
+
|
|
3062
|
+
|
|
3063
|
+
|
|
3064
|
+
|
|
3065
|
+
|
|
3066
|
+
|
|
3067
|
+
|
|
3068
|
+
|
|
3069
|
+
|
|
3070
|
+
|
|
3071
|
+
|
|
3072
|
+
|
|
3073
|
+
|
|
3074
|
+
|
|
3075
|
+
|
|
3076
|
+
|
|
3077
|
+
|
|
3078
|
+
|
|
3079
|
+
|
|
3080
|
+
|
|
3081
|
+
|
|
3082
|
+
|
|
3083
|
+
|
|
3084
|
+
|
|
3085
|
+
|
|
3086
|
+
|
|
3087
|
+
|
|
3088
|
+
|
|
3089
|
+
|
|
3090
|
+
|
|
3091
|
+
|
|
3092
|
+
|
|
3093
|
+
|
|
3094
|
+
|
|
3095
|
+
|
|
3096
|
+
|
|
3097
|
+
|
|
3098
|
+
|
|
3099
|
+
|
|
3100
|
+
|
|
3101
|
+
|
|
3102
|
+
|
|
3103
|
+
|
|
3104
|
+
|
|
3105
|
+
|
|
3106
|
+
|
|
3107
|
+
|
|
3108
|
+
|
|
3109
|
+
|
|
3110
|
+
|
|
3111
|
+
|
|
3112
|
+
|
|
3113
|
+
|
|
3114
|
+
|
|
3115
|
+
|
|
3116
|
+
|
|
3117
|
+
|
|
3118
|
+
|
|
3119
|
+
|
|
3120
|
+
|
|
3121
|
+
|
|
3122
|
+
|
|
3123
|
+
|
|
3124
|
+
|
|
3125
|
+
|
|
3126
|
+
|
|
3127
|
+
|
|
3128
|
+
|
|
3129
|
+
|
|
3130
|
+
|
|
3131
|
+
|
|
3132
|
+
|
|
3133
|
+
|
|
3134
|
+
|
|
3135
|
+
|
|
3136
|
+
|
|
3137
|
+
|
|
3138
|
+
|
|
3139
|
+
|
|
3140
|
+
|
|
3141
|
+
|
|
3142
|
+
|
|
3143
|
+
|
|
3144
|
+
|
|
3145
|
+
|
|
3146
|
+
|
|
3147
|
+
|
|
3148
|
+
|
|
3149
|
+
|
|
3150
|
+
|
|
3151
|
+
|
|
3152
|
+
|
|
3153
|
+
|
|
3154
|
+
|
|
3155
|
+
|
|
3156
|
+
|
|
3157
|
+
|
|
3158
|
+
|
|
3159
|
+
|
|
3160
|
+
|
|
3161
|
+
* @example
|
|
3162
|
+
* // Iterate entries
|
|
3163
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
3164
|
+
* mm.add(1, 'a');
|
|
3165
|
+
* mm.add(2, 'b');
|
|
3166
|
+
* const keys: number[] = [];
|
|
3167
|
+
* mm.forEach((v, k) => keys.push(k));
|
|
3168
|
+
* console.log(keys); // [1, 2];
|
|
3169
|
+
*/
|
|
3170
|
+
forEach(callback: (value: V[], key: K, map: this) => void): void {
|
|
3171
|
+
for (const [k, v] of this) {
|
|
3172
|
+
callback(v, k, this);
|
|
3173
|
+
}
|
|
657
3174
|
}
|
|
658
3175
|
|
|
659
|
-
// ---- iteration (bucket view) ----
|
|
660
|
-
|
|
661
3176
|
/**
|
|
662
|
-
*
|
|
663
|
-
* @remarks Time O(n), Space O(
|
|
3177
|
+
* Creates a new map with entries that pass the predicate.
|
|
3178
|
+
* @remarks Time O(n), Space O(n)
|
|
3179
|
+
|
|
3180
|
+
|
|
3181
|
+
|
|
3182
|
+
|
|
3183
|
+
|
|
3184
|
+
|
|
3185
|
+
|
|
3186
|
+
|
|
3187
|
+
|
|
3188
|
+
|
|
3189
|
+
|
|
3190
|
+
|
|
3191
|
+
|
|
3192
|
+
|
|
3193
|
+
|
|
3194
|
+
|
|
3195
|
+
|
|
3196
|
+
|
|
3197
|
+
|
|
3198
|
+
|
|
3199
|
+
|
|
3200
|
+
|
|
3201
|
+
|
|
3202
|
+
|
|
3203
|
+
|
|
3204
|
+
|
|
3205
|
+
|
|
3206
|
+
|
|
3207
|
+
|
|
3208
|
+
|
|
3209
|
+
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
|
|
3213
|
+
|
|
3214
|
+
|
|
3215
|
+
|
|
3216
|
+
|
|
3217
|
+
|
|
3218
|
+
|
|
3219
|
+
|
|
3220
|
+
|
|
3221
|
+
|
|
3222
|
+
|
|
3223
|
+
|
|
3224
|
+
|
|
3225
|
+
|
|
3226
|
+
|
|
3227
|
+
|
|
3228
|
+
|
|
3229
|
+
|
|
3230
|
+
|
|
3231
|
+
|
|
3232
|
+
|
|
3233
|
+
|
|
3234
|
+
|
|
3235
|
+
|
|
3236
|
+
|
|
3237
|
+
|
|
3238
|
+
|
|
3239
|
+
|
|
3240
|
+
|
|
3241
|
+
|
|
3242
|
+
|
|
3243
|
+
|
|
3244
|
+
|
|
3245
|
+
|
|
3246
|
+
|
|
3247
|
+
|
|
3248
|
+
|
|
3249
|
+
|
|
3250
|
+
|
|
3251
|
+
|
|
3252
|
+
|
|
3253
|
+
|
|
3254
|
+
|
|
3255
|
+
|
|
3256
|
+
|
|
3257
|
+
|
|
3258
|
+
|
|
3259
|
+
|
|
3260
|
+
|
|
3261
|
+
|
|
3262
|
+
|
|
3263
|
+
|
|
3264
|
+
|
|
3265
|
+
|
|
3266
|
+
|
|
3267
|
+
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
|
|
3276
|
+
|
|
3277
|
+
|
|
3278
|
+
|
|
3279
|
+
|
|
3280
|
+
|
|
3281
|
+
|
|
3282
|
+
|
|
3283
|
+
|
|
3284
|
+
|
|
3285
|
+
|
|
3286
|
+
|
|
3287
|
+
|
|
3288
|
+
|
|
3289
|
+
|
|
3290
|
+
|
|
3291
|
+
|
|
3292
|
+
|
|
3293
|
+
|
|
3294
|
+
|
|
3295
|
+
|
|
3296
|
+
|
|
3297
|
+
|
|
3298
|
+
|
|
3299
|
+
|
|
3300
|
+
|
|
3301
|
+
|
|
3302
|
+
|
|
3303
|
+
|
|
3304
|
+
|
|
3305
|
+
|
|
3306
|
+
|
|
3307
|
+
|
|
3308
|
+
|
|
3309
|
+
|
|
3310
|
+
|
|
3311
|
+
|
|
3312
|
+
|
|
3313
|
+
|
|
3314
|
+
|
|
3315
|
+
|
|
3316
|
+
|
|
3317
|
+
|
|
3318
|
+
|
|
3319
|
+
|
|
3320
|
+
|
|
3321
|
+
|
|
3322
|
+
* @example
|
|
3323
|
+
* // Filter entries
|
|
3324
|
+
* const mm = new TreeMultiMap<number, string>();
|
|
3325
|
+
* mm.add(1, 'a');
|
|
3326
|
+
* mm.add(2, 'b');
|
|
3327
|
+
* mm.add(3, 'c');
|
|
3328
|
+
* const filtered = mm.filter((v, k) => k > 1);
|
|
3329
|
+
* console.log([...filtered.keys()]); // [2, 3];
|
|
664
3330
|
*/
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
3331
|
+
filter(predicate: (value: V[], key: K, map: this) => boolean): TreeMultiMap<K, V, R> {
|
|
3332
|
+
const filtered: [K, V[]][] = [];
|
|
3333
|
+
for (const [k, v] of this) {
|
|
3334
|
+
if (predicate(v, k, this)) filtered.push([k, v]);
|
|
669
3335
|
}
|
|
3336
|
+
return new TreeMultiMap<K, V, R>(filtered, { comparator: this.comparator });
|
|
670
3337
|
}
|
|
671
3338
|
|
|
672
3339
|
/**
|
|
673
|
-
*
|
|
674
|
-
* @remarks Time O(n), Space O(
|
|
3340
|
+
* Creates a new map by transforming each entry.
|
|
3341
|
+
* @remarks Time O(n log n), Space O(n)
|
|
3342
|
+
|
|
3343
|
+
|
|
3344
|
+
|
|
3345
|
+
|
|
3346
|
+
|
|
3347
|
+
|
|
3348
|
+
|
|
3349
|
+
|
|
3350
|
+
|
|
3351
|
+
|
|
3352
|
+
|
|
3353
|
+
|
|
3354
|
+
|
|
3355
|
+
|
|
3356
|
+
|
|
3357
|
+
|
|
3358
|
+
|
|
3359
|
+
|
|
3360
|
+
|
|
3361
|
+
|
|
3362
|
+
|
|
3363
|
+
|
|
3364
|
+
|
|
3365
|
+
|
|
3366
|
+
|
|
3367
|
+
|
|
3368
|
+
|
|
3369
|
+
|
|
3370
|
+
|
|
3371
|
+
|
|
3372
|
+
|
|
3373
|
+
|
|
3374
|
+
|
|
3375
|
+
|
|
3376
|
+
|
|
3377
|
+
|
|
3378
|
+
|
|
3379
|
+
|
|
3380
|
+
|
|
3381
|
+
|
|
3382
|
+
|
|
3383
|
+
|
|
3384
|
+
|
|
3385
|
+
|
|
3386
|
+
|
|
3387
|
+
|
|
3388
|
+
|
|
3389
|
+
|
|
3390
|
+
|
|
3391
|
+
|
|
3392
|
+
|
|
3393
|
+
|
|
3394
|
+
|
|
3395
|
+
|
|
3396
|
+
|
|
3397
|
+
|
|
3398
|
+
|
|
3399
|
+
|
|
3400
|
+
|
|
3401
|
+
|
|
3402
|
+
|
|
675
3403
|
|
|
676
3404
|
|
|
677
3405
|
|
|
@@ -710,20 +3438,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
710
3438
|
|
|
711
3439
|
|
|
712
3440
|
|
|
713
|
-
* @example
|
|
714
|
-
* // Iterate keys
|
|
715
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
716
|
-
* mm.add(3, 'c');
|
|
717
|
-
* mm.add(1, 'a');
|
|
718
|
-
* console.log([...mm.keys()]); // [1, 3];
|
|
719
|
-
*/
|
|
720
|
-
*keys(): IterableIterator<K> {
|
|
721
|
-
yield* this.#core.keys();
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
/**
|
|
725
|
-
* Iterates over all buckets.
|
|
726
|
-
* @remarks Time O(n), Space O(1)
|
|
727
3441
|
|
|
728
3442
|
|
|
729
3443
|
|
|
@@ -762,80 +3476,105 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
762
3476
|
|
|
763
3477
|
|
|
764
3478
|
|
|
765
|
-
* @example
|
|
766
|
-
* // Iterate value arrays
|
|
767
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
768
|
-
* mm.add(1, 'a');
|
|
769
|
-
* mm.add(1, 'b');
|
|
770
|
-
* console.log([...mm.values()]); // [['a', 'b']];
|
|
771
|
-
*/
|
|
772
|
-
*values(): IterableIterator<V[]> {
|
|
773
|
-
for (const [, bucket] of this) yield bucket;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
// ---- entry-flat views ----
|
|
777
|
-
|
|
778
|
-
/**
|
|
779
|
-
* Iterates over all entries for a specific key.
|
|
780
|
-
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
781
3479
|
|
|
782
3480
|
|
|
783
|
-
* @example
|
|
784
|
-
* // Get entries for key
|
|
785
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
786
|
-
* mm.add(1, 'a');
|
|
787
|
-
* mm.add(1, 'b');
|
|
788
|
-
* console.log([...mm.entriesOf(1)]); // [[1, 'a'], [1, 'b']];
|
|
789
|
-
*/
|
|
790
|
-
*entriesOf(key: K): IterableIterator<[K, V]> {
|
|
791
|
-
const bucket = this.get(key);
|
|
792
|
-
if (!Array.isArray(bucket)) return;
|
|
793
|
-
for (const v of bucket) yield [key, v];
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
/**
|
|
797
|
-
* Iterates over all values for a specific key.
|
|
798
|
-
* @remarks Time O(log n + m), Space O(1) where m is bucket size
|
|
799
3481
|
|
|
800
3482
|
|
|
801
|
-
* @example
|
|
802
|
-
* // Get flat values for key
|
|
803
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
804
|
-
* mm.add(1, 'a');
|
|
805
|
-
* mm.add(1, 'b');
|
|
806
|
-
* console.log([...mm.valuesOf(1)]); // ['a', 'b'];
|
|
807
|
-
*/
|
|
808
|
-
*valuesOf(key: K): IterableIterator<V> {
|
|
809
|
-
const bucket = this.get(key);
|
|
810
|
-
if (!Array.isArray(bucket)) return;
|
|
811
|
-
yield* bucket;
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/**
|
|
815
|
-
* Iterates over all [key, value] pairs (flattened from buckets).
|
|
816
|
-
* @remarks Time O(T), Space O(1) where T is totalSize
|
|
817
3483
|
|
|
818
3484
|
|
|
819
3485
|
* @example
|
|
820
|
-
* //
|
|
3486
|
+
* // Transform values
|
|
821
3487
|
* const mm = new TreeMultiMap<number, string>();
|
|
822
3488
|
* mm.add(1, 'a');
|
|
823
|
-
* mm.
|
|
824
|
-
*
|
|
825
|
-
* console.log([...mm.flatEntries()]); // [[1, 'a'], [1, 'b'], [2, 'c']];
|
|
3489
|
+
* const mapped = mm.map((v, k) => [k, v.map(s => s.toUpperCase())] as [number, string[]]);
|
|
3490
|
+
* console.log(mapped.get(1)); // ['A'];
|
|
826
3491
|
*/
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
3492
|
+
map<V2>(
|
|
3493
|
+
mapper: (value: V[], key: K, map: this) => [K, V2[]]
|
|
3494
|
+
): TreeMultiMap<K, V2, R> {
|
|
3495
|
+
const mapped: [K, V2[]][] = [];
|
|
3496
|
+
for (const [k, v] of this) {
|
|
3497
|
+
mapped.push(mapper(v, k, this));
|
|
830
3498
|
}
|
|
3499
|
+
return new TreeMultiMap<K, V2, R>(mapped, { comparator: this.comparator });
|
|
831
3500
|
}
|
|
832
3501
|
|
|
833
|
-
// ━━━ Navigable methods (return [K, V[]] | undefined) ━━━
|
|
834
|
-
|
|
835
3502
|
/**
|
|
836
|
-
*
|
|
837
|
-
* @remarks Time O(
|
|
838
|
-
|
|
3503
|
+
* Reduces all entries to a single value.
|
|
3504
|
+
* @remarks Time O(n), Space O(1)
|
|
3505
|
+
|
|
3506
|
+
|
|
3507
|
+
|
|
3508
|
+
|
|
3509
|
+
|
|
3510
|
+
|
|
3511
|
+
|
|
3512
|
+
|
|
3513
|
+
|
|
3514
|
+
|
|
3515
|
+
|
|
3516
|
+
|
|
3517
|
+
|
|
3518
|
+
|
|
3519
|
+
|
|
3520
|
+
|
|
3521
|
+
|
|
3522
|
+
|
|
3523
|
+
|
|
3524
|
+
|
|
3525
|
+
|
|
3526
|
+
|
|
3527
|
+
|
|
3528
|
+
|
|
3529
|
+
|
|
3530
|
+
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
|
|
3535
|
+
|
|
3536
|
+
|
|
3537
|
+
|
|
3538
|
+
|
|
3539
|
+
|
|
3540
|
+
|
|
3541
|
+
|
|
3542
|
+
|
|
3543
|
+
|
|
3544
|
+
|
|
3545
|
+
|
|
3546
|
+
|
|
3547
|
+
|
|
3548
|
+
|
|
3549
|
+
|
|
3550
|
+
|
|
3551
|
+
|
|
3552
|
+
|
|
3553
|
+
|
|
3554
|
+
|
|
3555
|
+
|
|
3556
|
+
|
|
3557
|
+
|
|
3558
|
+
|
|
3559
|
+
|
|
3560
|
+
|
|
3561
|
+
|
|
3562
|
+
|
|
3563
|
+
|
|
3564
|
+
|
|
3565
|
+
|
|
3566
|
+
|
|
3567
|
+
|
|
3568
|
+
|
|
3569
|
+
|
|
3570
|
+
|
|
3571
|
+
|
|
3572
|
+
|
|
3573
|
+
|
|
3574
|
+
|
|
3575
|
+
|
|
3576
|
+
|
|
3577
|
+
|
|
839
3578
|
|
|
840
3579
|
|
|
841
3580
|
|
|
@@ -849,24 +3588,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
849
3588
|
|
|
850
3589
|
|
|
851
3590
|
|
|
852
|
-
* @example
|
|
853
|
-
* // First entry
|
|
854
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
855
|
-
* mm.add(3, 'c');
|
|
856
|
-
* mm.add(1, 'a');
|
|
857
|
-
* console.log(mm.first()?.[0]); // 1;
|
|
858
|
-
*/
|
|
859
|
-
first(): [K, V[]] | undefined {
|
|
860
|
-
const k = this.#core.getLeftMost();
|
|
861
|
-
if (k === undefined) return undefined;
|
|
862
|
-
const b = this.get(k);
|
|
863
|
-
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
/**
|
|
867
|
-
* Returns the entry with the largest key.
|
|
868
|
-
* @remarks Time O(log n), Space O(1)
|
|
869
|
-
|
|
870
3591
|
|
|
871
3592
|
|
|
872
3593
|
|
|
@@ -880,67 +3601,10 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
880
3601
|
|
|
881
3602
|
|
|
882
3603
|
|
|
883
|
-
* @example
|
|
884
|
-
* // Last entry
|
|
885
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
886
|
-
* mm.add(1, 'a');
|
|
887
|
-
* mm.add(3, 'c');
|
|
888
|
-
* console.log(mm.last()?.[0]); // 3;
|
|
889
|
-
*/
|
|
890
|
-
last(): [K, V[]] | undefined {
|
|
891
|
-
const k = this.#core.getRightMost();
|
|
892
|
-
if (k === undefined) return undefined;
|
|
893
|
-
const b = this.get(k);
|
|
894
|
-
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
/**
|
|
898
|
-
* Removes and returns the entry with the smallest key.
|
|
899
|
-
* @remarks Time O(log n), Space O(1)
|
|
900
|
-
|
|
901
3604
|
|
|
902
3605
|
|
|
903
|
-
* @example
|
|
904
|
-
* // Remove and return first
|
|
905
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
906
|
-
* mm.add(2, 'b');
|
|
907
|
-
* mm.add(1, 'a');
|
|
908
|
-
* const first = mm.pollFirst();
|
|
909
|
-
* console.log(first?.[0]); // 1;
|
|
910
|
-
* console.log(mm.has(1)); // false;
|
|
911
|
-
*/
|
|
912
|
-
pollFirst(): [K, V[]] | undefined {
|
|
913
|
-
const e = this.first();
|
|
914
|
-
if (!e) return undefined;
|
|
915
|
-
this.delete(e[0]);
|
|
916
|
-
return e;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
/**
|
|
920
|
-
* Removes and returns the entry with the largest key.
|
|
921
|
-
* @remarks Time O(log n), Space O(1)
|
|
922
|
-
|
|
923
3606
|
|
|
924
3607
|
|
|
925
|
-
* @example
|
|
926
|
-
* // Remove and return last
|
|
927
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
928
|
-
* mm.add(1, 'a');
|
|
929
|
-
* mm.add(3, 'c');
|
|
930
|
-
* const last = mm.pollLast();
|
|
931
|
-
* console.log(last?.[0]); // 3;
|
|
932
|
-
*/
|
|
933
|
-
pollLast(): [K, V[]] | undefined {
|
|
934
|
-
const e = this.last();
|
|
935
|
-
if (!e) return undefined;
|
|
936
|
-
this.delete(e[0]);
|
|
937
|
-
return e;
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
/**
|
|
941
|
-
* Returns the entry with the smallest key >= given key.
|
|
942
|
-
* @remarks Time O(log n), Space O(1)
|
|
943
|
-
|
|
944
3608
|
|
|
945
3609
|
|
|
946
3610
|
|
|
@@ -982,26 +3646,24 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
982
3646
|
|
|
983
3647
|
|
|
984
3648
|
* @example
|
|
985
|
-
* //
|
|
986
|
-
* const mm = new TreeMultiMap<number,
|
|
987
|
-
* mm.add(
|
|
988
|
-
* mm.add(
|
|
989
|
-
* mm.
|
|
990
|
-
* console.log(
|
|
3649
|
+
* // Aggregate
|
|
3650
|
+
* const mm = new TreeMultiMap<number, number>();
|
|
3651
|
+
* mm.add(1, 10);
|
|
3652
|
+
* mm.add(2, 20);
|
|
3653
|
+
* const sum = mm.reduce((acc, v) => acc + v.reduce((a, b) => a + b, 0), 0);
|
|
3654
|
+
* console.log(sum); // 30;
|
|
991
3655
|
*/
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
const k
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
return
|
|
3656
|
+
reduce<U>(callback: (accumulator: U, value: V[], key: K, map: this) => U, initialValue: U): U {
|
|
3657
|
+
let acc = initialValue;
|
|
3658
|
+
for (const [k, v] of this) {
|
|
3659
|
+
acc = callback(acc, v, k, this);
|
|
3660
|
+
}
|
|
3661
|
+
return acc;
|
|
998
3662
|
}
|
|
999
3663
|
|
|
1000
3664
|
/**
|
|
1001
|
-
*
|
|
1002
|
-
* @remarks Time O(log n), Space O(
|
|
1003
|
-
|
|
1004
|
-
|
|
3665
|
+
* Sets multiple entries at once.
|
|
3666
|
+
* @remarks Time O(m log n), Space O(m) where m is input size
|
|
1005
3667
|
|
|
1006
3668
|
|
|
1007
3669
|
|
|
@@ -1041,26 +3703,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1041
3703
|
|
|
1042
3704
|
|
|
1043
3705
|
|
|
1044
|
-
* @example
|
|
1045
|
-
* // Greatest key ≤ target
|
|
1046
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1047
|
-
* mm.add(10, 'a');
|
|
1048
|
-
* mm.add(20, 'b');
|
|
1049
|
-
* mm.add(30, 'c');
|
|
1050
|
-
* console.log(mm.floor(25)?.[0]); // 20;
|
|
1051
|
-
*/
|
|
1052
|
-
floor(key: K): [K, V[]] | undefined {
|
|
1053
|
-
this._validateKey(key);
|
|
1054
|
-
const k = this.#core.floor(key);
|
|
1055
|
-
if (k === undefined) return undefined;
|
|
1056
|
-
const b = this.get(k);
|
|
1057
|
-
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
/**
|
|
1061
|
-
* Returns the entry with the smallest key > given key.
|
|
1062
|
-
* @remarks Time O(log n), Space O(1)
|
|
1063
|
-
|
|
1064
3706
|
|
|
1065
3707
|
|
|
1066
3708
|
|
|
@@ -1090,25 +3732,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1090
3732
|
|
|
1091
3733
|
|
|
1092
3734
|
|
|
1093
|
-
* @example
|
|
1094
|
-
* // Least key > target
|
|
1095
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1096
|
-
* mm.add(10, 'a');
|
|
1097
|
-
* mm.add(20, 'b');
|
|
1098
|
-
* console.log(mm.higher(10)?.[0]); // 20;
|
|
1099
|
-
*/
|
|
1100
|
-
higher(key: K): [K, V[]] | undefined {
|
|
1101
|
-
this._validateKey(key);
|
|
1102
|
-
const k = this.#core.higher(key);
|
|
1103
|
-
if (k === undefined) return undefined;
|
|
1104
|
-
const b = this.get(k);
|
|
1105
|
-
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
/**
|
|
1109
|
-
* Returns the entry with the largest key < given key.
|
|
1110
|
-
* @remarks Time O(log n), Space O(1)
|
|
1111
|
-
|
|
1112
3735
|
|
|
1113
3736
|
|
|
1114
3737
|
|
|
@@ -1138,26 +3761,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1138
3761
|
|
|
1139
3762
|
|
|
1140
3763
|
|
|
1141
|
-
* @example
|
|
1142
|
-
* // Greatest key < target
|
|
1143
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1144
|
-
* mm.add(10, 'a');
|
|
1145
|
-
* mm.add(20, 'b');
|
|
1146
|
-
* console.log(mm.lower(20)?.[0]); // 10;
|
|
1147
|
-
*/
|
|
1148
|
-
lower(key: K): [K, V[]] | undefined {
|
|
1149
|
-
this._validateKey(key);
|
|
1150
|
-
const k = this.#core.lower(key);
|
|
1151
|
-
if (k === undefined) return undefined;
|
|
1152
|
-
const b = this.get(k);
|
|
1153
|
-
return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
// ━━━ Tree utilities ━━━
|
|
1157
|
-
|
|
1158
|
-
/**
|
|
1159
|
-
* Prints the internal tree structure (for debugging).
|
|
1160
|
-
* @remarks Time O(n), Space O(n)
|
|
1161
3764
|
|
|
1162
3765
|
|
|
1163
3766
|
|
|
@@ -1197,18 +3800,23 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1197
3800
|
|
|
1198
3801
|
|
|
1199
3802
|
* @example
|
|
1200
|
-
* //
|
|
3803
|
+
* // Set multiple entries
|
|
1201
3804
|
* const mm = new TreeMultiMap<number, string>();
|
|
1202
|
-
* mm.
|
|
1203
|
-
*
|
|
3805
|
+
* mm.setMany([[1, ['a']], [2, ['b']]]);
|
|
3806
|
+
* console.log(mm.size); // 2;
|
|
1204
3807
|
*/
|
|
1205
|
-
|
|
1206
|
-
|
|
3808
|
+
setMany(keysNodesEntriesOrRaws: Iterable<K | [K | null | undefined, V[] | undefined]>): boolean[] {
|
|
3809
|
+
const results: boolean[] = [];
|
|
3810
|
+
for (const x of keysNodesEntriesOrRaws) {
|
|
3811
|
+
// Call implementation directly: entry can be K or [K, V[]] or [K, undefined]
|
|
3812
|
+
results.push(this.set(x));
|
|
3813
|
+
}
|
|
3814
|
+
return results;
|
|
1207
3815
|
}
|
|
1208
3816
|
|
|
1209
3817
|
/**
|
|
1210
|
-
*
|
|
1211
|
-
* @remarks Time O(n), Space O(
|
|
3818
|
+
* Searches for entries within a key range.
|
|
3819
|
+
* @remarks Time O(log n + k), Space O(k) where k is result size
|
|
1212
3820
|
|
|
1213
3821
|
|
|
1214
3822
|
|
|
@@ -1247,24 +3855,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1247
3855
|
|
|
1248
3856
|
|
|
1249
3857
|
|
|
1250
|
-
* @example
|
|
1251
|
-
* // Iterate entries
|
|
1252
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1253
|
-
* mm.add(1, 'a');
|
|
1254
|
-
* mm.add(2, 'b');
|
|
1255
|
-
* const keys: number[] = [];
|
|
1256
|
-
* mm.forEach((v, k) => keys.push(k));
|
|
1257
|
-
* console.log(keys); // [1, 2];
|
|
1258
|
-
*/
|
|
1259
|
-
forEach(callback: (value: V[], key: K, map: this) => void): void {
|
|
1260
|
-
for (const [k, v] of this) {
|
|
1261
|
-
callback(v, k, this);
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
/**
|
|
1266
|
-
* Creates a new map with entries that pass the predicate.
|
|
1267
|
-
* @remarks Time O(n), Space O(n)
|
|
1268
3858
|
|
|
1269
3859
|
|
|
1270
3860
|
|
|
@@ -1303,26 +3893,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1303
3893
|
|
|
1304
3894
|
|
|
1305
3895
|
|
|
1306
|
-
* @example
|
|
1307
|
-
* // Filter entries
|
|
1308
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1309
|
-
* mm.add(1, 'a');
|
|
1310
|
-
* mm.add(2, 'b');
|
|
1311
|
-
* mm.add(3, 'c');
|
|
1312
|
-
* const filtered = mm.filter((v, k) => k > 1);
|
|
1313
|
-
* console.log([...filtered.keys()]); // [2, 3];
|
|
1314
|
-
*/
|
|
1315
|
-
filter(predicate: (value: V[], key: K, map: this) => boolean): TreeMultiMap<K, V, R> {
|
|
1316
|
-
const filtered: [K, V[]][] = [];
|
|
1317
|
-
for (const [k, v] of this) {
|
|
1318
|
-
if (predicate(v, k, this)) filtered.push([k, v]);
|
|
1319
|
-
}
|
|
1320
|
-
return new TreeMultiMap<K, V, R>(filtered, { comparator: this.comparator });
|
|
1321
|
-
}
|
|
1322
|
-
|
|
1323
|
-
/**
|
|
1324
|
-
* Creates a new map by transforming each entry.
|
|
1325
|
-
* @remarks Time O(n log n), Space O(n)
|
|
1326
3896
|
|
|
1327
3897
|
|
|
1328
3898
|
|
|
@@ -1362,25 +3932,31 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1362
3932
|
|
|
1363
3933
|
|
|
1364
3934
|
* @example
|
|
1365
|
-
* //
|
|
3935
|
+
* // Find keys in range
|
|
1366
3936
|
* const mm = new TreeMultiMap<number, string>();
|
|
1367
|
-
* mm.add(
|
|
1368
|
-
*
|
|
1369
|
-
*
|
|
3937
|
+
* mm.add(10, 'a');
|
|
3938
|
+
* mm.add(20, 'b');
|
|
3939
|
+
* mm.add(30, 'c');
|
|
3940
|
+
* const result = mm.rangeSearch([15, 25]);
|
|
3941
|
+
* console.log(result.length); // 1;
|
|
1370
3942
|
*/
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
mapped.push(mapper(v, k, this));
|
|
1377
|
-
}
|
|
1378
|
-
return new TreeMultiMap<K, V2, R>(mapped, { comparator: this.comparator });
|
|
3943
|
+
rangeSearch<C extends (node: RedBlackTreeNode<K, V[]>) => unknown>(
|
|
3944
|
+
range: Range<K> | [K, K],
|
|
3945
|
+
callback?: C
|
|
3946
|
+
): ReturnType<C>[] {
|
|
3947
|
+
return this.#core.rangeSearch(range, callback as (node: RedBlackTreeNode<K, V[]>) => ReturnType<C>);
|
|
1379
3948
|
}
|
|
1380
3949
|
|
|
1381
3950
|
/**
|
|
1382
|
-
*
|
|
1383
|
-
* @remarks Time O(n), Space O(
|
|
3951
|
+
* Creates a shallow clone of this map.
|
|
3952
|
+
* @remarks Time O(n log n), Space O(n)
|
|
3953
|
+
|
|
3954
|
+
|
|
3955
|
+
|
|
3956
|
+
|
|
3957
|
+
|
|
3958
|
+
|
|
3959
|
+
|
|
1384
3960
|
|
|
1385
3961
|
|
|
1386
3962
|
|
|
@@ -1419,25 +3995,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1419
3995
|
|
|
1420
3996
|
|
|
1421
3997
|
|
|
1422
|
-
* @example
|
|
1423
|
-
* // Aggregate
|
|
1424
|
-
* const mm = new TreeMultiMap<number, number>();
|
|
1425
|
-
* mm.add(1, 10);
|
|
1426
|
-
* mm.add(2, 20);
|
|
1427
|
-
* const sum = mm.reduce((acc, v) => acc + v.reduce((a, b) => a + b, 0), 0);
|
|
1428
|
-
* console.log(sum); // 30;
|
|
1429
|
-
*/
|
|
1430
|
-
reduce<U>(callback: (accumulator: U, value: V[], key: K, map: this) => U, initialValue: U): U {
|
|
1431
|
-
let acc = initialValue;
|
|
1432
|
-
for (const [k, v] of this) {
|
|
1433
|
-
acc = callback(acc, v, k, this);
|
|
1434
|
-
}
|
|
1435
|
-
return acc;
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
|
-
/**
|
|
1439
|
-
* Sets multiple entries at once.
|
|
1440
|
-
* @remarks Time O(m log n), Space O(m) where m is input size
|
|
1441
3998
|
|
|
1442
3999
|
|
|
1443
4000
|
|
|
@@ -1468,24 +4025,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1468
4025
|
|
|
1469
4026
|
|
|
1470
4027
|
|
|
1471
|
-
* @example
|
|
1472
|
-
* // Set multiple entries
|
|
1473
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1474
|
-
* mm.setMany([[1, ['a']], [2, ['b']]]);
|
|
1475
|
-
* console.log(mm.size); // 2;
|
|
1476
|
-
*/
|
|
1477
|
-
setMany(keysNodesEntriesOrRaws: Iterable<K | [K | null | undefined, V[] | undefined]>): boolean[] {
|
|
1478
|
-
const results: boolean[] = [];
|
|
1479
|
-
for (const x of keysNodesEntriesOrRaws) {
|
|
1480
|
-
// Call implementation directly: entry can be K or [K, V[]] or [K, undefined]
|
|
1481
|
-
results.push(this.set(x));
|
|
1482
|
-
}
|
|
1483
|
-
return results;
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1486
|
-
/**
|
|
1487
|
-
* Searches for entries within a key range.
|
|
1488
|
-
* @remarks Time O(log n + k), Space O(k) where k is result size
|
|
1489
4028
|
|
|
1490
4029
|
|
|
1491
4030
|
|
|
@@ -1516,25 +4055,6 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
|
|
|
1516
4055
|
|
|
1517
4056
|
|
|
1518
4057
|
|
|
1519
|
-
* @example
|
|
1520
|
-
* // Find keys in range
|
|
1521
|
-
* const mm = new TreeMultiMap<number, string>();
|
|
1522
|
-
* mm.add(10, 'a');
|
|
1523
|
-
* mm.add(20, 'b');
|
|
1524
|
-
* mm.add(30, 'c');
|
|
1525
|
-
* const result = mm.rangeSearch([15, 25]);
|
|
1526
|
-
* console.log(result.length); // 1;
|
|
1527
|
-
*/
|
|
1528
|
-
rangeSearch<C extends (node: RedBlackTreeNode<K, V[]>) => unknown>(
|
|
1529
|
-
range: Range<K> | [K, K],
|
|
1530
|
-
callback?: C
|
|
1531
|
-
): ReturnType<C>[] {
|
|
1532
|
-
return this.#core.rangeSearch(range, callback as (node: RedBlackTreeNode<K, V[]>) => ReturnType<C>);
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
/**
|
|
1536
|
-
* Creates a shallow clone of this map.
|
|
1537
|
-
* @remarks Time O(n log n), Space O(n)
|
|
1538
4058
|
|
|
1539
4059
|
|
|
1540
4060
|
|