graph-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 (84) hide show
  1. package/dist/cjs/index.cjs +1324 -220
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +1325 -219
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +1324 -221
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +1325 -220
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/common/error.d.ts +23 -0
  10. package/dist/types/common/index.d.ts +1 -0
  11. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  12. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  13. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  17. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  18. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  19. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  20. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  21. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  22. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  23. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  24. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  25. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  26. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  27. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  28. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  29. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  30. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  31. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  32. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  33. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  34. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  35. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  36. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  37. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  38. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  39. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  40. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  41. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  42. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  43. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  44. package/dist/umd/graph-typed.js +1323 -217
  45. package/dist/umd/graph-typed.js.map +1 -1
  46. package/dist/umd/graph-typed.min.js +3 -1
  47. package/dist/umd/graph-typed.min.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/common/error.ts +60 -0
  50. package/src/common/index.ts +2 -0
  51. package/src/data-structures/base/iterable-element-base.ts +2 -2
  52. package/src/data-structures/binary-tree/avl-tree.ts +134 -51
  53. package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
  54. package/src/data-structures/binary-tree/binary-tree.ts +542 -121
  55. package/src/data-structures/binary-tree/bst.ts +346 -37
  56. package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
  57. package/src/data-structures/binary-tree/segment-tree.ts +372 -248
  58. package/src/data-structures/binary-tree/tree-map.ts +1292 -13
  59. package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
  60. package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
  61. package/src/data-structures/binary-tree/tree-set.ts +1143 -15
  62. package/src/data-structures/graph/abstract-graph.ts +106 -1
  63. package/src/data-structures/graph/directed-graph.ts +223 -47
  64. package/src/data-structures/graph/map-graph.ts +59 -1
  65. package/src/data-structures/graph/undirected-graph.ts +299 -59
  66. package/src/data-structures/hash/hash-map.ts +243 -79
  67. package/src/data-structures/heap/heap.ts +291 -102
  68. package/src/data-structures/heap/max-heap.ts +48 -3
  69. package/src/data-structures/heap/min-heap.ts +59 -0
  70. package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
  71. package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
  72. package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
  73. package/src/data-structures/matrix/matrix.ts +425 -22
  74. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  75. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  76. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  77. package/src/data-structures/queue/deque.ts +343 -68
  78. package/src/data-structures/queue/queue.ts +211 -42
  79. package/src/data-structures/stack/stack.ts +174 -32
  80. package/src/data-structures/trie/trie.ts +215 -44
  81. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  82. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  83. package/src/types/data-structures/queue/deque.ts +7 -0
  84. 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,47 @@ 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
+ * @example
155
+ * // Check if empty
156
+ * console.log(new TreeMultiMap().isEmpty()); // true;
286
157
  */
287
158
  isEmpty(): boolean {
288
159
  return this.size === 0;
@@ -291,6 +162,50 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
291
162
  /**
292
163
  * Removes all entries from the map.
293
164
  * @remarks Time O(1), Space O(1)
165
+
166
+
167
+
168
+
169
+
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
+ * @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;
294
209
  */
295
210
  clear(): void {
296
211
  this.#core.clear();
@@ -299,6 +214,14 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
299
214
  /**
300
215
  * Bucket length for a key (missing => 0).
301
216
  * @remarks Time O(log n), Space O(1)
217
+
218
+
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;
302
225
  */
303
226
  count(key: K): number {
304
227
  const b = this.get(key);
@@ -308,6 +231,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
308
231
  /**
309
232
  * Total number of values across all buckets (Σ bucket.length).
310
233
  * @remarks Time O(n), Space O(1)
234
+
235
+
236
+ * @example
237
+ * // Total number of values
238
+ * const mm = new TreeMultiMap<number, string>();
239
+ * mm.add(1, 'a');
240
+ * mm.add(1, 'b');
241
+ * mm.add(2, 'c');
242
+ * console.log(mm.totalSize); // 3;
311
243
  */
312
244
  get totalSize(): number {
313
245
  let sum = 0;
@@ -318,6 +250,64 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
318
250
  /**
319
251
  * Whether the map contains the given key.
320
252
  * @remarks Time O(log n), Space O(1)
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
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
+ * @example
306
+ * // Check key existence
307
+ * const mm = new TreeMultiMap<number, string>();
308
+ * mm.add(1, 'a');
309
+ * console.log(mm.has(1)); // true;
310
+ * console.log(mm.has(2)); // false;
321
311
  */
322
312
  has(key: K): boolean {
323
313
  this._validateKey(key);
@@ -327,6 +317,64 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
327
317
  /**
328
318
  * Live bucket reference (do not auto-delete key if bucket becomes empty via mutation).
329
319
  * @remarks Time O(log n), Space O(1)
320
+
321
+
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+
335
+
336
+
337
+
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
+ * @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'];
330
378
  */
331
379
  get(key: K): V[] | undefined {
332
380
  this._validateKey(key);
@@ -336,6 +384,45 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
336
384
  /**
337
385
  * Append a single value.
338
386
  * @remarks Time O(log n), Space O(1)
387
+
388
+
389
+
390
+
391
+
392
+
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+
402
+
403
+
404
+
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
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'];
339
426
  */
340
427
  add(key: K, value: V): boolean {
341
428
  this._validateKey(key);
@@ -350,6 +437,62 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
350
437
  /**
351
438
  * Alias for compatibility with existing TreeMultiMap semantics.
352
439
  * @remarks Time O(log n), Space O(1) for single value; O(log n + m) for bucket append
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
455
+
456
+
457
+
458
+
459
+
460
+
461
+
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+ * @example
491
+ * // Set values for key
492
+ * const mm = new TreeMultiMap<number, string>();
493
+ * mm.set(1, 'a');
494
+ * mm.set(1, 'b');
495
+ * console.log(mm.get(1)); // ['a', 'b'];
353
496
  */
354
497
  set(entry: [K | null | undefined, V[] | undefined] | K | null | undefined, value?: V): boolean;
355
498
  set(key: K, value: V): boolean;
@@ -379,6 +522,65 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
379
522
  /**
380
523
  * Deletes a key and its entire bucket.
381
524
  * @remarks Time O(log n), Space O(1)
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
+ * @example
578
+ * // Remove key
579
+ * const mm = new TreeMultiMap<number, string>();
580
+ * mm.add(1, 'a');
581
+ * mm.add(2, 'b');
582
+ * mm.delete(1);
583
+ * console.log(mm.has(1)); // false;
382
584
  */
383
585
  delete(key: K): boolean {
384
586
  this._validateKey(key);
@@ -388,6 +590,14 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
388
590
  /**
389
591
  * Check if a specific value exists in a key's bucket.
390
592
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
593
+
594
+
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;
391
601
  */
392
602
  hasEntry(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
393
603
  const bucket = this.get(key);
@@ -398,6 +608,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
398
608
  /**
399
609
  * Delete a single occurrence of a value from a key's bucket.
400
610
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
611
+
612
+
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'];
401
620
  */
402
621
  deleteValue(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): boolean {
403
622
  const bucket = this.get(key);
@@ -412,6 +631,16 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
412
631
  /**
413
632
  * Delete all occurrences of a value from a key's bucket.
414
633
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
634
+
635
+
636
+ * @example
637
+ * // Delete all matching values
638
+ * const mm = new TreeMultiMap<number, string>();
639
+ * mm.add(1, 'a');
640
+ * mm.add(1, 'a');
641
+ * mm.add(1, 'b');
642
+ * const count = mm.deleteValues(1, 'a');
643
+ * console.log(count); // 2;
415
644
  */
416
645
  deleteValues(key: K, value: V, eq: (a: V, b: V) => boolean = Object.is): number {
417
646
  const bucket = this.get(key);
@@ -436,13 +665,57 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
436
665
  *[Symbol.iterator](): Iterator<[K, V[]]> {
437
666
  for (const [k, v] of this.#core) {
438
667
  // core always stores buckets, but guard anyway
439
- yield [k, v ?? ([] as V[])];
668
+ yield [k, v ?? /* istanbul ignore next */ ([] as V[])];
440
669
  }
441
670
  }
442
671
 
443
672
  /**
444
673
  * Iterates over all keys.
445
674
  * @remarks Time O(n), Space O(1)
675
+
676
+
677
+
678
+
679
+
680
+
681
+
682
+
683
+
684
+
685
+
686
+
687
+
688
+
689
+
690
+
691
+
692
+
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
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];
446
719
  */
447
720
  *keys(): IterableIterator<K> {
448
721
  yield* this.#core.keys();
@@ -451,6 +724,50 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
451
724
  /**
452
725
  * Iterates over all buckets.
453
726
  * @remarks Time O(n), Space O(1)
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
+ * @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']];
454
771
  */
455
772
  *values(): IterableIterator<V[]> {
456
773
  for (const [, bucket] of this) yield bucket;
@@ -461,6 +778,14 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
461
778
  /**
462
779
  * Iterates over all entries for a specific key.
463
780
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
781
+
782
+
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']];
464
789
  */
465
790
  *entriesOf(key: K): IterableIterator<[K, V]> {
466
791
  const bucket = this.get(key);
@@ -471,6 +796,14 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
471
796
  /**
472
797
  * Iterates over all values for a specific key.
473
798
  * @remarks Time O(log n + m), Space O(1) where m is bucket size
799
+
800
+
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'];
474
807
  */
475
808
  *valuesOf(key: K): IterableIterator<V> {
476
809
  const bucket = this.get(key);
@@ -481,6 +814,15 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
481
814
  /**
482
815
  * Iterates over all [key, value] pairs (flattened from buckets).
483
816
  * @remarks Time O(T), Space O(1) where T is totalSize
817
+
818
+
819
+ * @example
820
+ * // All key-value pairs flattened
821
+ * const mm = new TreeMultiMap<number, string>();
822
+ * mm.add(1, 'a');
823
+ * mm.add(1, 'b');
824
+ * mm.add(2, 'c');
825
+ * console.log([...mm.flatEntries()]); // [[1, 'a'], [1, 'b'], [2, 'c']];
484
826
  */
485
827
  *flatEntries(): IterableIterator<[K, V]> {
486
828
  for (const [k, bucket] of this) {
@@ -493,38 +835,79 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
493
835
  /**
494
836
  * Returns the entry with the smallest key.
495
837
  * @remarks Time O(log n), Space O(1)
496
- * @example
497
- * const map = new TreeMultiMap([[1, ['a']], [2, ['b']]]);
498
- * map.first(); // [1, ['a']]
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+
849
+
850
+
851
+
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;
499
858
  */
500
859
  first(): [K, V[]] | undefined {
501
860
  const k = this.#core.getLeftMost();
502
861
  if (k === undefined) return undefined;
503
862
  const b = this.get(k);
504
- return b === undefined ? undefined : [k, b];
863
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
505
864
  }
506
865
 
507
866
  /**
508
867
  * Returns the entry with the largest key.
509
868
  * @remarks Time O(log n), Space O(1)
510
- * @example
511
- * const map = new TreeMultiMap([[1, ['a']], [2, ['b']]]);
512
- * map.last(); // [2, ['b']]
869
+
870
+
871
+
872
+
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
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;
513
889
  */
514
890
  last(): [K, V[]] | undefined {
515
891
  const k = this.#core.getRightMost();
516
892
  if (k === undefined) return undefined;
517
893
  const b = this.get(k);
518
- return b === undefined ? undefined : [k, b];
894
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
519
895
  }
520
896
 
521
897
  /**
522
898
  * Removes and returns the entry with the smallest key.
523
899
  * @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
900
+
901
+
902
+
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;
528
911
  */
529
912
  pollFirst(): [K, V[]] | undefined {
530
913
  const e = this.first();
@@ -536,10 +919,16 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
536
919
  /**
537
920
  * Removes and returns the entry with the largest key.
538
921
  * @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
922
+
923
+
924
+
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;
543
932
  */
544
933
  pollLast(): [K, V[]] | undefined {
545
934
  const e = this.last();
@@ -551,65 +940,217 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
551
940
  /**
552
941
  * Returns the entry with the smallest key >= given key.
553
942
  * @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']]
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
+ * @example
985
+ * // Least key ≥ target
986
+ * const mm = new TreeMultiMap<number, string>();
987
+ * mm.add(10, 'a');
988
+ * mm.add(20, 'b');
989
+ * mm.add(30, 'c');
990
+ * console.log(mm.ceiling(15)?.[0]); // 20;
558
991
  */
559
992
  ceiling(key: K): [K, V[]] | undefined {
560
993
  this._validateKey(key);
561
994
  const k = this.#core.ceiling(key);
562
995
  if (k === undefined) return undefined;
563
996
  const b = this.get(k);
564
- return b === undefined ? undefined : [k, b];
997
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
565
998
  }
566
999
 
567
1000
  /**
568
1001
  * Returns the entry with the largest key <= given key.
569
1002
  * @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']]
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
+
1029
+
1030
+
1031
+
1032
+
1033
+
1034
+
1035
+
1036
+
1037
+
1038
+
1039
+
1040
+
1041
+
1042
+
1043
+
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;
574
1051
  */
575
1052
  floor(key: K): [K, V[]] | undefined {
576
1053
  this._validateKey(key);
577
1054
  const k = this.#core.floor(key);
578
1055
  if (k === undefined) return undefined;
579
1056
  const b = this.get(k);
580
- return b === undefined ? undefined : [k, b];
1057
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
581
1058
  }
582
1059
 
583
1060
  /**
584
1061
  * Returns the entry with the smallest key > given key.
585
1062
  * @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']]
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
+ * @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;
590
1099
  */
591
1100
  higher(key: K): [K, V[]] | undefined {
592
1101
  this._validateKey(key);
593
1102
  const k = this.#core.higher(key);
594
1103
  if (k === undefined) return undefined;
595
1104
  const b = this.get(k);
596
- return b === undefined ? undefined : [k, b];
1105
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
597
1106
  }
598
1107
 
599
1108
  /**
600
1109
  * Returns the entry with the largest key < given key.
601
1110
  * @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']]
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
+ * @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;
606
1147
  */
607
1148
  lower(key: K): [K, V[]] | undefined {
608
1149
  this._validateKey(key);
609
1150
  const k = this.#core.lower(key);
610
1151
  if (k === undefined) return undefined;
611
1152
  const b = this.get(k);
612
- return b === undefined ? undefined : [k, b];
1153
+ return b === undefined ? /* istanbul ignore next -- defensive: key in core always has bucket */ undefined : [k, b];
613
1154
  }
614
1155
 
615
1156
  // ━━━ Tree utilities ━━━
@@ -617,6 +1158,49 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
617
1158
  /**
618
1159
  * Prints the internal tree structure (for debugging).
619
1160
  * @remarks Time O(n), Space O(n)
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
+ * @example
1200
+ * // Display tree
1201
+ * const mm = new TreeMultiMap<number, string>();
1202
+ * mm.add(1, 'a');
1203
+ * expect(() => mm.print()).not.toThrow();
620
1204
  */
621
1205
  print(): void {
622
1206
  this.#core.print();
@@ -625,6 +1209,52 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
625
1209
  /**
626
1210
  * Executes a callback for each entry.
627
1211
  * @remarks Time O(n), Space O(1)
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
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];
628
1258
  */
629
1259
  forEach(callback: (value: V[], key: K, map: this) => void): void {
630
1260
  for (const [k, v] of this) {
@@ -635,6 +1265,52 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
635
1265
  /**
636
1266
  * Creates a new map with entries that pass the predicate.
637
1267
  * @remarks Time O(n), Space O(n)
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
+ * @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];
638
1314
  */
639
1315
  filter(predicate: (value: V[], key: K, map: this) => boolean): TreeMultiMap<K, V, R> {
640
1316
  const filtered: [K, V[]][] = [];
@@ -647,6 +1323,50 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
647
1323
  /**
648
1324
  * Creates a new map by transforming each entry.
649
1325
  * @remarks Time O(n log n), Space O(n)
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
+ * @example
1365
+ * // Transform values
1366
+ * const mm = new TreeMultiMap<number, string>();
1367
+ * mm.add(1, 'a');
1368
+ * const mapped = mm.map((v, k) => [k, v.map(s => s.toUpperCase())] as [number, string[]]);
1369
+ * console.log(mapped.get(1)); // ['A'];
650
1370
  */
651
1371
  map<V2>(
652
1372
  mapper: (value: V[], key: K, map: this) => [K, V2[]]
@@ -661,6 +1381,51 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
661
1381
  /**
662
1382
  * Reduces all entries to a single value.
663
1383
  * @remarks Time O(n), Space O(1)
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
+ * @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;
664
1429
  */
665
1430
  reduce<U>(callback: (accumulator: U, value: V[], key: K, map: this) => U, initialValue: U): U {
666
1431
  let acc = initialValue;
@@ -673,6 +1438,41 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
673
1438
  /**
674
1439
  * Sets multiple entries at once.
675
1440
  * @remarks Time O(m log n), Space O(m) where m is input size
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
+
1466
+
1467
+
1468
+
1469
+
1470
+
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;
676
1476
  */
677
1477
  setMany(keysNodesEntriesOrRaws: Iterable<K | [K | null | undefined, V[] | undefined]>): boolean[] {
678
1478
  const results: boolean[] = [];
@@ -686,6 +1486,44 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
686
1486
  /**
687
1487
  * Searches for entries within a key range.
688
1488
  * @remarks Time O(log n + k), Space O(k) where k is result size
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
+ * @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;
689
1527
  */
690
1528
  rangeSearch<C extends (node: RedBlackTreeNode<K, V[]>) => unknown>(
691
1529
  range: Range<K> | [K, K],
@@ -697,6 +1535,51 @@ export class TreeMultiMap<K = any, V = any, R = any> implements Iterable<[K, V[]
697
1535
  /**
698
1536
  * Creates a shallow clone of this map.
699
1537
  * @remarks Time O(n log n), Space O(n)
1538
+
1539
+
1540
+
1541
+
1542
+
1543
+
1544
+
1545
+
1546
+
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
+ * @example
1577
+ * // Deep clone
1578
+ * const mm = new TreeMultiMap<number, string>();
1579
+ * mm.add(1, 'a');
1580
+ * const copy = mm.clone();
1581
+ * copy.delete(1);
1582
+ * console.log(mm.has(1)); // true;
700
1583
  */
701
1584
  clone(): TreeMultiMap<K, V, R> {
702
1585
  return new TreeMultiMap<K, V, R>(this, { comparator: this.comparator, isMapMode: this.#core.isMapMode });