data-structure-typed 2.4.4 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +34 -1
  3. package/dist/cjs/index.cjs +10639 -2151
  4. package/dist/cjs-legacy/index.cjs +10694 -2195
  5. package/dist/esm/index.mjs +10639 -2150
  6. package/dist/esm-legacy/index.mjs +10694 -2194
  7. package/dist/types/common/error.d.ts +23 -0
  8. package/dist/types/common/index.d.ts +1 -0
  9. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  10. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  11. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  12. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  13. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  14. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  15. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  16. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  17. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  18. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  19. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  20. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  21. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  22. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  23. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  24. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  25. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  26. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  27. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  28. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  29. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  30. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  31. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  32. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  33. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  34. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  35. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  36. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  37. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  38. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  39. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  40. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  41. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  42. package/dist/umd/data-structure-typed.js +10725 -2221
  43. package/dist/umd/data-structure-typed.min.js +4 -2
  44. package/package.json +5 -4
  45. package/src/common/error.ts +60 -0
  46. package/src/common/index.ts +2 -0
  47. package/src/data-structures/base/iterable-element-base.ts +2 -2
  48. package/src/data-structures/binary-tree/avl-tree.ts +146 -51
  49. package/src/data-structures/binary-tree/binary-indexed-tree.ts +317 -247
  50. package/src/data-structures/binary-tree/binary-tree.ts +567 -121
  51. package/src/data-structures/binary-tree/bst.ts +370 -37
  52. package/src/data-structures/binary-tree/red-black-tree.ts +328 -96
  53. package/src/data-structures/binary-tree/segment-tree.ts +378 -248
  54. package/src/data-structures/binary-tree/tree-map.ts +1411 -13
  55. package/src/data-structures/binary-tree/tree-multi-map.ts +1218 -215
  56. package/src/data-structures/binary-tree/tree-multi-set.ts +959 -69
  57. package/src/data-structures/binary-tree/tree-set.ts +1257 -15
  58. package/src/data-structures/graph/abstract-graph.ts +106 -1
  59. package/src/data-structures/graph/directed-graph.ts +233 -47
  60. package/src/data-structures/graph/map-graph.ts +59 -1
  61. package/src/data-structures/graph/undirected-graph.ts +308 -59
  62. package/src/data-structures/hash/hash-map.ts +254 -79
  63. package/src/data-structures/heap/heap.ts +305 -102
  64. package/src/data-structures/heap/max-heap.ts +48 -3
  65. package/src/data-structures/heap/min-heap.ts +59 -0
  66. package/src/data-structures/linked-list/doubly-linked-list.ts +303 -44
  67. package/src/data-structures/linked-list/singly-linked-list.ts +293 -65
  68. package/src/data-structures/linked-list/skip-linked-list.ts +707 -90
  69. package/src/data-structures/matrix/matrix.ts +433 -22
  70. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  71. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  72. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  73. package/src/data-structures/queue/deque.ts +358 -68
  74. package/src/data-structures/queue/queue.ts +223 -42
  75. package/src/data-structures/stack/stack.ts +184 -32
  76. package/src/data-structures/trie/trie.ts +227 -44
  77. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  78. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  79. package/src/types/data-structures/queue/deque.ts +7 -0
  80. package/src/utils/utils.ts +4 -2
@@ -7,21 +7,10 @@
7
7
  */
8
8
 
9
9
  import type { Comparator, TreeMultiMapOptions } from '../../types';
10
- import { Range } from '../../common';
10
+ import { ERR, Range } from '../../common';
11
11
  import { RedBlackTree, RedBlackTreeNode } from './red-black-tree';
12
12
  import { TreeSet } from './tree-set';
13
13
 
14
- /**
15
- * Node type used by TreeMultiMap (alias to RedBlackTreeNode for backward compatibility).
16
- *
17
- * @deprecated Direct node manipulation is discouraged. Use TreeMultiMap methods instead.
18
- */
19
- export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]> {
20
- constructor(key: K, value: V[] = []) {
21
- super(key, value);
22
- }
23
- }
24
-
25
14
  /**
26
15
  * TreeMultiMap (ordered MultiMap) — key → bucket (Array of values).
27
16
  *
@@ -31,169 +20,10 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
31
20
  * - Default iteration yields bucket entries: `[K, V[]]`.
32
21
  * - Navigable operations (`first/last/ceiling/...`) return entry tuples like TreeMap.
33
22
  * @example
34
- * // players ranked by score with their equipment
35
- * type Equipment = {
36
- * name: string; // Equipment name
37
- * quality: 'legendary' | 'epic' | 'rare' | 'common';
38
- * level: number;
39
- * };
40
- *
41
- * type Player = {
42
- * name: string;
43
- * score: number;
44
- * equipments: Equipment[];
45
- * };
46
- *
47
- * // Mock player data with their scores and equipment
48
- * const players: Player[] = [
49
- * {
50
- * name: 'DragonSlayer',
51
- * score: 8750,
52
- * equipments: [
53
- * { name: 'AWM', quality: 'legendary', level: 85 },
54
- * { name: 'Level 3 Helmet', quality: 'epic', level: 80 },
55
- * { name: 'Extended Quickdraw Mag', quality: 'rare', level: 75 },
56
- * { name: 'Compensator', quality: 'epic', level: 78 },
57
- * { name: 'Vertical Grip', quality: 'rare', level: 72 }
58
- * ]
59
- * },
60
- * {
61
- * name: 'ShadowNinja',
62
- * score: 7200,
63
- * equipments: [
64
- * { name: 'M416', quality: 'epic', level: 75 },
65
- * { name: 'Ghillie Suit', quality: 'rare', level: 70 },
66
- * { name: 'Red Dot Sight', quality: 'common', level: 65 },
67
- * { name: 'Extended QuickDraw Mag', quality: 'rare', level: 68 }
68
- * ]
69
- * },
70
- * {
71
- * name: 'RuneMaster',
72
- * score: 9100,
73
- * equipments: [
74
- * { name: 'KAR98K', quality: 'legendary', level: 90 },
75
- * { name: 'Level 3 Vest', quality: 'legendary', level: 85 },
76
- * { name: 'Holographic Sight', quality: 'epic', level: 82 },
77
- * { name: 'Suppressor', quality: 'legendary', level: 88 },
78
- * { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
79
- * ]
80
- * },
81
- * {
82
- * name: 'BattleKing',
83
- * score: 8500,
84
- * equipments: [
85
- * { name: 'AUG', quality: 'epic', level: 82 },
86
- * { name: 'Red Dot Sight', quality: 'rare', level: 75 },
87
- * { name: 'Extended Mag', quality: 'common', level: 70 },
88
- * { name: 'Tactical Stock', quality: 'rare', level: 76 }
89
- * ]
90
- * },
91
- * {
92
- * name: 'SniperElite',
93
- * score: 7800,
94
- * equipments: [
95
- * { name: 'M24', quality: 'legendary', level: 88 },
96
- * { name: 'Compensator', quality: 'epic', level: 80 },
97
- * { name: 'Scope 8x', quality: 'legendary', level: 85 },
98
- * { name: 'Level 2 Helmet', quality: 'rare', level: 75 }
99
- * ]
100
- * },
101
- * {
102
- * name: 'RushMaster',
103
- * score: 7500,
104
- * equipments: [
105
- * { name: 'Vector', quality: 'rare', level: 72 },
106
- * { name: 'Level 2 Helmet', quality: 'common', level: 65 },
107
- * { name: 'Quickdraw Mag', quality: 'common', level: 60 },
108
- * { name: 'Laser Sight', quality: 'rare', level: 68 }
109
- * ]
110
- * },
111
- * {
112
- * name: 'GhostWarrior',
113
- * score: 8200,
114
- * equipments: [
115
- * { name: 'SCAR-L', quality: 'epic', level: 78 },
116
- * { name: 'Extended Quickdraw Mag', quality: 'rare', level: 70 },
117
- * { name: 'Holographic Sight', quality: 'epic', level: 75 },
118
- * { name: 'Suppressor', quality: 'rare', level: 72 },
119
- * { name: 'Vertical Grip', quality: 'common', level: 65 }
120
- * ]
121
- * },
122
- * {
123
- * name: 'DeathDealer',
124
- * score: 7300,
125
- * equipments: [
126
- * { name: 'SKS', quality: 'epic', level: 76 },
127
- * { name: 'Holographic Sight', quality: 'rare', level: 68 },
128
- * { name: 'Extended Mag', quality: 'common', level: 65 }
129
- * ]
130
- * },
131
- * {
132
- * name: 'StormRider',
133
- * score: 8900,
134
- * equipments: [
135
- * { name: 'MK14', quality: 'legendary', level: 92 },
136
- * { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
137
- * { name: 'Scope 8x', quality: 'epic', level: 80 },
138
- * { name: 'Suppressor', quality: 'legendary', level: 88 },
139
- * { name: 'Tactical Stock', quality: 'rare', level: 75 }
140
- * ]
141
- * },
142
- * {
143
- * name: 'CombatLegend',
144
- * score: 7600,
145
- * equipments: [
146
- * { name: 'UMP45', quality: 'rare', level: 74 },
147
- * { name: 'Level 2 Vest', quality: 'common', level: 67 },
148
- * { name: 'Red Dot Sight', quality: 'common', level: 62 },
149
- * { name: 'Extended Mag', quality: 'rare', level: 70 }
150
- * ]
151
- * }
152
- * ];
153
- *
154
- * // Create a TreeMultiMap for player rankings
155
- * const playerRankings = new TreeMultiMap<number, Equipment, Player>(players, {
156
- * toEntryFn: ({ score, equipments }) => [score, equipments],
157
- * isMapMode: false
158
- * });
159
- *
160
- * const topPlayersEquipments = playerRankings.rangeSearch([8900, 10000], node => playerRankings.get(node.key));
161
- * console.log(topPlayersEquipments); // [
162
- * // [
163
- * // {
164
- * // name: 'MK14',
165
- * // quality: 'legendary',
166
- * // level: 92
167
- * // },
168
- * // { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
169
- * // {
170
- * // name: 'Scope 8x',
171
- * // quality: 'epic',
172
- * // level: 80
173
- * // },
174
- * // { name: 'Suppressor', quality: 'legendary', level: 88 },
175
- * // {
176
- * // name: 'Tactical Stock',
177
- * // quality: 'rare',
178
- * // level: 75
179
- * // }
180
- * // ],
181
- * // [
182
- * // { name: 'KAR98K', quality: 'legendary', level: 90 },
183
- * // {
184
- * // name: 'Level 3 Vest',
185
- * // quality: 'legendary',
186
- * // level: 85
187
- * // },
188
- * // { name: 'Holographic Sight', quality: 'epic', level: 82 },
189
- * // {
190
- * // name: 'Suppressor',
191
- * // quality: 'legendary',
192
- * // level: 88
193
- * // },
194
- * // { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
195
- * // ]
196
- * // ];
23
+ * // Morris traversal (O(1) space)
24
+ * const tmm = new TreeMultiMap<number>([5, 3, 7]);
25
+ * const result = tmm.morris(n => n.key, 'IN');
26
+ * console.log(result.length); // > 0;
197
27
  */
198
28
  export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]]> {
199
29
  readonly #core: RedBlackTree<K, V[], R>;
@@ -261,15 +91,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
261
91
  // reuse TreeSet strict validation (same policy)
262
92
  // NOTE: TreeSet._validateKey is private, so we replicate the checks.
263
93
  if (typeof key === 'number') {
264
- if (Number.isNaN(key)) throw new TypeError('TreeMultiMap: NaN is not a valid key');
94
+ if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeMultiMap'));
265
95
  return;
266
96
  }
267
97
  if (typeof key === 'string') return;
268
98
  if (key instanceof Date) {
269
- if (Number.isNaN(key.getTime())) throw new TypeError('TreeMultiMap: invalid Date key');
99
+ if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeMultiMap'));
270
100
  return;
271
101
  }
272
- throw new TypeError('TreeMultiMap: comparator is required for non-number/non-string/non-Date keys');
102
+ throw new TypeError(ERR.comparatorRequired('TreeMultiMap'));
273
103
  }
274
104
 
275
105
  /**
@@ -283,6 +113,52 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
283
113
  /**
284
114
  * Whether the map is empty.
285
115
  * @remarks Time O(1), Space O(1)
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+ * @example
160
+ * // Check if empty
161
+ * console.log(new TreeMultiMap().isEmpty()); // true;
286
162
  */
287
163
  isEmpty(): boolean {
288
164
  return this.size === 0;
@@ -291,6 +167,55 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
291
167
  /**
292
168
  * Removes all entries from the map.
293
169
  * @remarks Time O(1), Space O(1)
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+ * @example
214
+ * // Remove all entries
215
+ * const mm = new TreeMultiMap<number, string>();
216
+ * mm.add(1, 'a');
217
+ * mm.clear();
218
+ * console.log(mm.isEmpty()); // true;
294
219
  */
295
220
  clear(): void {
296
221
  this.#core.clear();
@@ -299,6 +224,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
299
224
  /**
300
225
  * Bucket length for a key (missing => 0).
301
226
  * @remarks Time O(log n), Space O(1)
227
+
228
+
229
+
230
+ * @example
231
+ * // Count values for key
232
+ * const mm = new TreeMultiMap<number, string>();
233
+ * mm.add(1, 'a');
234
+ * mm.add(1, 'b');
235
+ * console.log(mm.count(1)); // 2;
302
236
  */
303
237
  count(key: K): number {
304
238
  const b = this.get(key);
@@ -308,6 +242,16 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
308
242
  /**
309
243
  * Total number of values across all buckets (Σ bucket.length).
310
244
  * @remarks Time O(n), Space O(1)
245
+
246
+
247
+
248
+ * @example
249
+ * // Total number of values
250
+ * const mm = new TreeMultiMap<number, string>();
251
+ * mm.add(1, 'a');
252
+ * mm.add(1, 'b');
253
+ * mm.add(2, 'c');
254
+ * console.log(mm.totalSize); // 3;
311
255
  */
312
256
  get totalSize(): number {
313
257
  let sum = 0;
@@ -318,6 +262,70 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
318
262
  /**
319
263
  * Whether the map contains the given key.
320
264
  * @remarks Time O(log n), Space O(1)
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+
290
+
291
+
292
+
293
+
294
+
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
321
+
322
+
323
+ * @example
324
+ * // Check key existence
325
+ * const mm = new TreeMultiMap<number, string>();
326
+ * mm.add(1, 'a');
327
+ * console.log(mm.has(1)); // true;
328
+ * console.log(mm.has(2)); // false;
321
329
  */
322
330
  has(key: K): boolean {
323
331
  this._validateKey(key);
@@ -327,6 +335,70 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
327
335
  /**
328
336
  * Live bucket reference (do not auto-delete key if bucket becomes empty via mutation).
329
337
  * @remarks Time O(log n), Space O(1)
338
+
339
+
340
+
341
+
342
+
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+
366
+
367
+
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+ * @example
397
+ * // Get values for key
398
+ * const mm = new TreeMultiMap<number, string>();
399
+ * mm.add(1, 'a');
400
+ * mm.add(1, 'b');
401
+ * console.log(mm.get(1)); // ['a', 'b'];
330
402
  */
331
403
  get(key: K): V[] | undefined {
332
404
  this._validateKey(key);
@@ -336,6 +408,50 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
336
408
  /**
337
409
  * Append a single value.
338
410
  * @remarks Time O(log n), Space O(1)
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+
422
+
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+ * @example
449
+ * // Add key-value pair
450
+ * const mm = new TreeMultiMap<number, string>();
451
+ * mm.add(1, 'a');
452
+ * mm.add(1, 'b');
453
+ * mm.add(2, 'c');
454
+ * console.log(mm.get(1)); // ['a', 'b'];
339
455
  */
340
456
  add(key: K, value: V): boolean {
341
457
  this._validateKey(key);
@@ -350,6 +466,68 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
350
466
  /**
351
467
  * Alias for compatibility with existing TreeMultiMap semantics.
352
468
  * @remarks Time O(log n), Space O(1) for single value; O(log n + m) for bucket append
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+
496
+
497
+
498
+
499
+
500
+
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+ * @example
526
+ * // Set values for key
527
+ * const mm = new TreeMultiMap<number, string>();
528
+ * mm.set(1, 'a');
529
+ * mm.set(1, 'b');
530
+ * console.log(mm.get(1)); // ['a', 'b'];
353
531
  */
354
532
  set(entry: [K | null | undefined, V[] | undefined] | K | null | undefined, value?: V): boolean;
355
533
  set(key: K, value: V): boolean;
@@ -379,6 +557,71 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
379
557
  /**
380
558
  * Deletes a key and its entire bucket.
381
559
  * @remarks Time O(log n), Space O(1)
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
+ * @example
619
+ * // Remove key
620
+ * const mm = new TreeMultiMap<number, string>();
621
+ * mm.add(1, 'a');
622
+ * mm.add(2, 'b');
623
+ * mm.delete(1);
624
+ * console.log(mm.has(1)); // false;
382
625
  */
383
626
  delete(key: K): boolean {
384
627
  this._validateKey(key);
@@ -388,6 +631,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
388
631
  /**
389
632
  * Check if a specific value exists in a key's bucket.
390
633
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
634
+
635
+
636
+
637
+ * @example
638
+ * // Check specific key-value
639
+ * const mm = new TreeMultiMap<number, string>();
640
+ * mm.add(1, 'a');
641
+ * console.log(mm.hasEntry(1, 'a')); // true;
642
+ * console.log(mm.hasEntry(1, 'z')); // false;
391
643
  */
392
644
  hasEntry(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
393
645
  const bucket = this.get(key);
@@ -398,6 +650,16 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
398
650
  /**
399
651
  * Delete a single occurrence of a value from a key's bucket.
400
652
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
653
+
654
+
655
+
656
+ * @example
657
+ * // Delete specific value
658
+ * const mm = new TreeMultiMap<number, string>();
659
+ * mm.add(1, 'a');
660
+ * mm.add(1, 'b');
661
+ * mm.deleteValue(1, 'a');
662
+ * console.log(mm.get(1)); // ['b'];
401
663
  */
402
664
  deleteValue(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
403
665
  const bucket = this.get(key);
@@ -412,6 +674,17 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
412
674
  /**
413
675
  * Delete all occurrences of a value from a key's bucket.
414
676
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
677
+
678
+
679
+
680
+ * @example
681
+ * // Delete all matching values
682
+ * const mm = new TreeMultiMap<number, string>();
683
+ * mm.add(1, 'a');
684
+ * mm.add(1, 'a');
685
+ * mm.add(1, 'b');
686
+ * const count = mm.deleteValues(1, 'a');
687
+ * console.log(count); // 2;
415
688
  */
416
689
  deleteValues(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): number {
417
690
  const bucket = this.get(key);
@@ -436,13 +709,62 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
436
709
  *[Symbol.iterator](): Iterator<[K, V[]]> {
437
710
  for (const [k, v] of this.#core) {
438
711
  // core always stores buckets, but guard anyway
439
- yield [k, v ?? ([] as V[])];
712
+ yield [k, v ?? /* istanbul ignore next */ ([] as V[])];
440
713
  }
441
714
  }
442
715
 
443
716
  /**
444
717
  * Iterates over all keys.
445
718
  * @remarks Time O(n), Space O(1)
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
+ * @example
763
+ * // Iterate keys
764
+ * const mm = new TreeMultiMap<number, string>();
765
+ * mm.add(3, 'c');
766
+ * mm.add(1, 'a');
767
+ * console.log([...mm.keys()]); // [1, 3];
446
768
  */
447
769
  *keys(): IterableIterator<K> {
448
770
  yield* this.#core.keys();
@@ -451,6 +773,55 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
451
773
  /**
452
774
  * Iterates over all buckets.
453
775
  * @remarks Time O(n), Space O(1)
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
+ * @example
820
+ * // Iterate value arrays
821
+ * const mm = new TreeMultiMap<number, string>();
822
+ * mm.add(1, 'a');
823
+ * mm.add(1, 'b');
824
+ * console.log([...mm.values()]); // [['a', 'b']];
454
825
  */
455
826
  *values(): IterableIterator<V[]> {
456
827
  for (const [, bucket] of this) yield bucket;
@@ -461,6 +832,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
461
832
  /**
462
833
  * Iterates over all entries for a specific key.
463
834
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
835
+
836
+
837
+
838
+ * @example
839
+ * // Get entries for key
840
+ * const mm = new TreeMultiMap<number, string>();
841
+ * mm.add(1, 'a');
842
+ * mm.add(1, 'b');
843
+ * console.log([...mm.entriesOf(1)]); // [[1, 'a'], [1, 'b']];
464
844
  */
465
845
  *entriesOf(key: K): IterableIterator<[K, V]> {
466
846
  const bucket = this.get(key);
@@ -471,6 +851,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
471
851
  /**
472
852
  * Iterates over all values for a specific key.
473
853
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
854
+
855
+
856
+
857
+ * @example
858
+ * // Get flat values for key
859
+ * const mm = new TreeMultiMap<number, string>();
860
+ * mm.add(1, 'a');
861
+ * mm.add(1, 'b');
862
+ * console.log([...mm.valuesOf(1)]); // ['a', 'b'];
474
863
  */
475
864
  *valuesOf(key: K): IterableIterator<V> {
476
865
  const bucket = this.get(key);
@@ -481,6 +870,16 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
481
870
  /**
482
871
  * Iterates over all [key, value] pairs (flattened from buckets).
483
872
  * @remarks Time O(T), Space O(1) where T is totalSize
873
+
874
+
875
+
876
+ * @example
877
+ * // All key-value pairs flattened
878
+ * const mm = new TreeMultiMap<number, string>();
879
+ * mm.add(1, 'a');
880
+ * mm.add(1, 'b');
881
+ * mm.add(2, 'c');
882
+ * console.log([...mm.flatEntries()]); // [[1, 'a'], [1, 'b'], [2, 'c']];
484
883
  */
485
884
  *flatEntries(): IterableIterator<[K, V]> {
486
885
  for (const [k, bucket] of this) {
@@ -493,38 +892,84 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
493
892
  /**
494
893
  * Returns the entry with the smallest key.
495
894
  * @remarks Time O(log n), Space O(1)
496
- * @example
497
- * const map = new TreeMultiMap([[1, ['a']], [2, ['b']]]);
498
- * map.first(); // [1, ['a']]
895
+
896
+
897
+
898
+
899
+
900
+
901
+
902
+
903
+
904
+
905
+
906
+
907
+
908
+
909
+
910
+
911
+ * @example
912
+ * // First entry
913
+ * const mm = new TreeMultiMap<number, string>();
914
+ * mm.add(3, 'c');
915
+ * mm.add(1, 'a');
916
+ * console.log(mm.first()?.[0]); // 1;
499
917
  */
500
918
  first(): [K, V[]] | undefined {
501
919
  const k = this.#core.getLeftMost();
502
920
  if (k === undefined) return undefined;
503
921
  const b = this.get(k);
504
- return b === undefined ? undefined : [k, b];
922
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
505
923
  }
506
924
 
507
925
  /**
508
926
  * Returns the entry with the largest key.
509
927
  * @remarks Time O(log n), Space O(1)
510
- * @example
511
- * const map = new TreeMultiMap([[1, ['a']], [2, ['b']]]);
512
- * map.last(); // [2, ['b']]
928
+
929
+
930
+
931
+
932
+
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+ * @example
945
+ * // Last entry
946
+ * const mm = new TreeMultiMap<number, string>();
947
+ * mm.add(1, 'a');
948
+ * mm.add(3, 'c');
949
+ * console.log(mm.last()?.[0]); // 3;
513
950
  */
514
951
  last(): [K, V[]] | undefined {
515
952
  const k = this.#core.getRightMost();
516
953
  if (k === undefined) return undefined;
517
954
  const b = this.get(k);
518
- return b === undefined ? undefined : [k, b];
955
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
519
956
  }
520
957
 
521
958
  /**
522
959
  * Removes and returns the entry with the smallest key.
523
960
  * @remarks Time O(log n), Space O(1)
524
- * @example
525
- * const map = new TreeMultiMap([[1, ['a']], [2, ['b']]]);
526
- * map.pollFirst(); // [1, ['a']]
527
- * map.has(1); // false
961
+
962
+
963
+
964
+
965
+ * @example
966
+ * // Remove and return first
967
+ * const mm = new TreeMultiMap<number, string>();
968
+ * mm.add(2, 'b');
969
+ * mm.add(1, 'a');
970
+ * const first = mm.pollFirst();
971
+ * console.log(first?.[0]); // 1;
972
+ * console.log(mm.has(1)); // false;
528
973
  */
529
974
  pollFirst(): [K, V[]] | undefined {
530
975
  const e = this.first();
@@ -536,10 +981,17 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
536
981
  /**
537
982
  * Removes and returns the entry with the largest key.
538
983
  * @remarks Time O(log n), Space O(1)
539
- * @example
540
- * const map = new TreeMultiMap([[1, ['a']], [2, ['b']]]);
541
- * map.pollLast(); // [2, ['b']]
542
- * map.has(2); // false
984
+
985
+
986
+
987
+
988
+ * @example
989
+ * // Remove and return last
990
+ * const mm = new TreeMultiMap<number, string>();
991
+ * mm.add(1, 'a');
992
+ * mm.add(3, 'c');
993
+ * const last = mm.pollLast();
994
+ * console.log(last?.[0]); // 3;
543
995
  */
544
996
  pollLast(): [K, V[]] | undefined {
545
997
  const e = this.last();
@@ -551,65 +1003,235 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
551
1003
  /**
552
1004
  * Returns the entry with the smallest key >= given key.
553
1005
  * @remarks Time O(log n), Space O(1)
554
- * @example
555
- * const map = new TreeMultiMap([[10, ['a']], [20, ['b']], [30, ['c']]]);
556
- * map.ceiling(15); // [20, ['b']]
557
- * map.ceiling(20); // [20, ['b']]
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+
1018
+
1019
+
1020
+
1021
+
1022
+
1023
+
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
1031
+
1032
+
1033
+
1034
+
1035
+
1036
+
1037
+
1038
+
1039
+
1040
+
1041
+
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+ * @example
1053
+ * // Least key ≥ target
1054
+ * const mm = new TreeMultiMap<number, string>();
1055
+ * mm.add(10, 'a');
1056
+ * mm.add(20, 'b');
1057
+ * mm.add(30, 'c');
1058
+ * console.log(mm.ceiling(15)?.[0]); // 20;
558
1059
  */
559
1060
  ceiling(key: K): [K, V[]] | undefined {
560
1061
  this._validateKey(key);
561
1062
  const k = this.#core.ceiling(key);
562
1063
  if (k === undefined) return undefined;
563
1064
  const b = this.get(k);
564
- return b === undefined ? undefined : [k, b];
1065
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
565
1066
  }
566
1067
 
567
1068
  /**
568
1069
  * Returns the entry with the largest key <= given key.
569
1070
  * @remarks Time O(log n), Space O(1)
570
- * @example
571
- * const map = new TreeMultiMap([[10, ['a']], [20, ['b']], [30, ['c']]]);
572
- * map.floor(25); // [20, ['b']]
573
- * map.floor(20); // [20, ['b']]
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
+ * @example
1118
+ * // Greatest key ≤ target
1119
+ * const mm = new TreeMultiMap<number, string>();
1120
+ * mm.add(10, 'a');
1121
+ * mm.add(20, 'b');
1122
+ * mm.add(30, 'c');
1123
+ * console.log(mm.floor(25)?.[0]); // 20;
574
1124
  */
575
1125
  floor(key: K): [K, V[]] | undefined {
576
1126
  this._validateKey(key);
577
1127
  const k = this.#core.floor(key);
578
1128
  if (k === undefined) return undefined;
579
1129
  const b = this.get(k);
580
- return b === undefined ? undefined : [k, b];
1130
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
581
1131
  }
582
1132
 
583
1133
  /**
584
1134
  * Returns the entry with the smallest key > given key.
585
1135
  * @remarks Time O(log n), Space O(1)
586
- * @example
587
- * const map = new TreeMultiMap([[10, ['a']], [20, ['b']], [30, ['c']]]);
588
- * map.higher(10); // [20, ['b']]
589
- * map.higher(15); // [20, ['b']]
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
+ * @example
1171
+ * // Least key > target
1172
+ * const mm = new TreeMultiMap<number, string>();
1173
+ * mm.add(10, 'a');
1174
+ * mm.add(20, 'b');
1175
+ * console.log(mm.higher(10)?.[0]); // 20;
590
1176
  */
591
1177
  higher(key: K): [K, V[]] | undefined {
592
1178
  this._validateKey(key);
593
1179
  const k = this.#core.higher(key);
594
1180
  if (k === undefined) return undefined;
595
1181
  const b = this.get(k);
596
- return b === undefined ? undefined : [k, b];
1182
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
597
1183
  }
598
1184
 
599
1185
  /**
600
1186
  * Returns the entry with the largest key < given key.
601
1187
  * @remarks Time O(log n), Space O(1)
602
- * @example
603
- * const map = new TreeMultiMap([[10, ['a']], [20, ['b']], [30, ['c']]]);
604
- * map.lower(20); // [10, ['a']]
605
- * map.lower(15); // [10, ['a']]
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
+ * @example
1223
+ * // Greatest key < target
1224
+ * const mm = new TreeMultiMap<number, string>();
1225
+ * mm.add(10, 'a');
1226
+ * mm.add(20, 'b');
1227
+ * console.log(mm.lower(20)?.[0]); // 10;
606
1228
  */
607
1229
  lower(key: K): [K, V[]] | undefined {
608
1230
  this._validateKey(key);
609
1231
  const k = this.#core.lower(key);
610
1232
  if (k === undefined) return undefined;
611
1233
  const b = this.get(k);
612
- return b === undefined ? undefined : [k, b];
1234
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
613
1235
  }
614
1236
 
615
1237
  // ━━━ Tree utilities ━━━
@@ -617,6 +1239,54 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
617
1239
  /**
618
1240
  * Prints the internal tree structure (for debugging).
619
1241
  * @remarks Time O(n), Space O(n)
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
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
+ * @example
1286
+ * // Display tree
1287
+ * const mm = new TreeMultiMap<number, string>();
1288
+ * mm.add(1, 'a');
1289
+ * expect(() => mm.print()).not.toThrow();
620
1290
  */
621
1291
  print(): void {
622
1292
  this.#core.print();
@@ -625,6 +1295,57 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
625
1295
  /**
626
1296
  * Executes a callback for each entry.
627
1297
  * @remarks Time O(n), Space O(1)
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
+ * @example
1342
+ * // Iterate entries
1343
+ * const mm = new TreeMultiMap<number, string>();
1344
+ * mm.add(1, 'a');
1345
+ * mm.add(2, 'b');
1346
+ * const keys: number[] = [];
1347
+ * mm.forEach((v, k) => keys.push(k));
1348
+ * console.log(keys); // [1, 2];
628
1349
  */
629
1350
  forEach(callback: (value: V[], key: K, map: this) => void): void {
630
1351
  for (const [k, v] of this) {
@@ -635,6 +1356,57 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
635
1356
  /**
636
1357
  * Creates a new map with entries that pass the predicate.
637
1358
  * @remarks Time O(n), Space O(n)
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
+ * @example
1403
+ * // Filter entries
1404
+ * const mm = new TreeMultiMap<number, string>();
1405
+ * mm.add(1, 'a');
1406
+ * mm.add(2, 'b');
1407
+ * mm.add(3, 'c');
1408
+ * const filtered = mm.filter((v, k) => k > 1);
1409
+ * console.log([...filtered.keys()]); // [2, 3];
638
1410
  */
639
1411
  filter(predicate: (value: V[], key: K, map: this) => boolean): TreeMultiMap<K, V, R> {
640
1412
  const filtered: [K, V[]][] = [];
@@ -647,6 +1419,55 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
647
1419
  /**
648
1420
  * Creates a new map by transforming each entry.
649
1421
  * @remarks Time O(n log n), Space O(n)
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+
1458
+
1459
+
1460
+
1461
+
1462
+
1463
+
1464
+
1465
+ * @example
1466
+ * // Transform values
1467
+ * const mm = new TreeMultiMap<number, string>();
1468
+ * mm.add(1, 'a');
1469
+ * const mapped = mm.map((v, k) => [k, v.map(s => s.toUpperCase())] as [number, string[]]);
1470
+ * console.log(mapped.get(1)); // ['A'];
650
1471
  */
651
1472
  map<V2>(
652
1473
  mapper: (value: V[], key: K, map: this) => [K, V2[]]
@@ -661,6 +1482,56 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
661
1482
  /**
662
1483
  * Reduces all entries to a single value.
663
1484
  * @remarks Time O(n), Space O(1)
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+
1525
+
1526
+
1527
+
1528
+ * @example
1529
+ * // Aggregate
1530
+ * const mm = new TreeMultiMap<number, number>();
1531
+ * mm.add(1, 10);
1532
+ * mm.add(2, 20);
1533
+ * const sum = mm.reduce((acc, v) => acc + v.reduce((a, b) => a + b, 0), 0);
1534
+ * console.log(sum); // 30;
664
1535
  */
665
1536
  reduce<U>(callback: (accumulator: U, value: V[], key: K, map: this) => U, initialValue: U): U {
666
1537
  let acc = initialValue;
@@ -673,6 +1544,46 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
673
1544
  /**
674
1545
  * Sets multiple entries at once.
675
1546
  * @remarks Time O(m log n), Space O(m) where m is input size
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+
1569
+
1570
+
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+
1580
+
1581
+
1582
+ * @example
1583
+ * // Set multiple entries
1584
+ * const mm = new TreeMultiMap<number, string>();
1585
+ * mm.setMany([[1, ['a']], [2, ['b']]]);
1586
+ * console.log(mm.size); // 2;
676
1587
  */
677
1588
  setMany(keysNodesEntriesOrRaws: Iterable<K | [K | null | undefined, V[] | undefined]>): boolean[] {
678
1589
  const results: boolean[] = [];
@@ -686,6 +1597,48 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
686
1597
  /**
687
1598
  * Searches for entries within a key range.
688
1599
  * @remarks Time O(log n + k), Space O(k) where k is result size
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
+ * @example
1635
+ * // Find keys in range
1636
+ * const mm = new TreeMultiMap<number, string>();
1637
+ * mm.add(10, 'a');
1638
+ * mm.add(20, 'b');
1639
+ * mm.add(30, 'c');
1640
+ * const result = mm.rangeSearch([15, 25]);
1641
+ * console.log(result.length); // 1;
689
1642
  */
690
1643
  rangeSearch<C extends (node: RedBlackTreeNode<K, V[]>) => unknown>(
691
1644
  range: Range<K> | [K, K],
@@ -697,6 +1650,56 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
697
1650
  /**
698
1651
  * Creates a shallow clone of this map.
699
1652
  * @remarks Time O(n log n), Space O(n)
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
+ * @example
1697
+ * // Deep clone
1698
+ * const mm = new TreeMultiMap<number, string>();
1699
+ * mm.add(1, 'a');
1700
+ * const copy = mm.clone();
1701
+ * copy.delete(1);
1702
+ * console.log(mm.has(1)); // true;
700
1703
  */
701
1704
  clone(): TreeMultiMap<K, V, R> {
702
1705
  return new TreeMultiMap<K, V, R>(this, { comparator: this.comparator, isMapMode: this.#core.isMapMode });