bunqueue 2.3.1 → 2.4.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/application/queueManager.d.ts.map +1 -1
- package/dist/application/queueManager.js +1 -37
- package/dist/application/queueManager.js.map +1 -1
- package/dist/application/statsManager.d.ts +10 -0
- package/dist/application/statsManager.d.ts.map +1 -1
- package/dist/application/statsManager.js +42 -0
- package/dist/application/statsManager.js.map +1 -1
- package/dist/client/jobConversion.d.ts +3 -76
- package/dist/client/jobConversion.d.ts.map +1 -1
- package/dist/client/jobConversion.js +2 -100
- package/dist/client/jobConversion.js.map +1 -1
- package/dist/client/jobConversionHelpers.d.ts +13 -0
- package/dist/client/jobConversionHelpers.d.ts.map +1 -0
- package/dist/client/jobConversionHelpers.js +105 -0
- package/dist/client/jobConversionHelpers.js.map +1 -0
- package/dist/client/jobConversionTypes.d.ts +81 -0
- package/dist/client/jobConversionTypes.d.ts.map +1 -0
- package/dist/client/jobConversionTypes.js +6 -0
- package/dist/client/jobConversionTypes.js.map +1 -0
- package/dist/client/queue/addBatcher.d.ts +60 -0
- package/dist/client/queue/addBatcher.d.ts.map +1 -0
- package/dist/client/queue/addBatcher.js +137 -0
- package/dist/client/queue/addBatcher.js.map +1 -0
- package/dist/client/queue/queue.d.ts +1 -0
- package/dist/client/queue/queue.d.ts.map +1 -1
- package/dist/client/queue/queue.js +25 -2
- package/dist/client/queue/queue.js.map +1 -1
- package/dist/client/types.d.ts +16 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/types.js.map +1 -1
- package/dist/client/worker/worker.d.ts +4 -95
- package/dist/client/worker/worker.d.ts.map +1 -1
- package/dist/client/worker/worker.js +50 -282
- package/dist/client/worker/worker.js.map +1 -1
- package/dist/client/worker/workerHeartbeat.d.ts +16 -0
- package/dist/client/worker/workerHeartbeat.d.ts.map +1 -0
- package/dist/client/worker/workerHeartbeat.js +44 -0
- package/dist/client/worker/workerHeartbeat.js.map +1 -0
- package/dist/client/worker/workerPull.d.ts +21 -0
- package/dist/client/worker/workerPull.d.ts.map +1 -0
- package/dist/client/worker/workerPull.js +60 -0
- package/dist/client/worker/workerPull.js.map +1 -0
- package/dist/client/worker/workerRateLimiter.d.ts +37 -0
- package/dist/client/worker/workerRateLimiter.d.ts.map +1 -0
- package/dist/client/worker/workerRateLimiter.js +84 -0
- package/dist/client/worker/workerRateLimiter.js.map +1 -0
- package/dist/domain/queue/shard.d.ts +8 -23
- package/dist/domain/queue/shard.d.ts.map +1 -1
- package/dist/domain/queue/shard.js +30 -90
- package/dist/domain/queue/shard.js.map +1 -1
- package/dist/domain/queue/shardCounters.d.ts +36 -0
- package/dist/domain/queue/shardCounters.d.ts.map +1 -0
- package/dist/domain/queue/shardCounters.js +68 -0
- package/dist/domain/queue/shardCounters.js.map +1 -0
- package/dist/domain/queue/waiterManager.d.ts +19 -0
- package/dist/domain/queue/waiterManager.d.ts.map +1 -0
- package/dist/domain/queue/waiterManager.js +64 -0
- package/dist/domain/queue/waiterManager.js.map +1 -0
- package/dist/shared/boundedMap.d.ts +31 -0
- package/dist/shared/boundedMap.d.ts.map +1 -0
- package/dist/shared/boundedMap.js +78 -0
- package/dist/shared/boundedMap.js.map +1 -0
- package/dist/shared/boundedSet.d.ts +27 -0
- package/dist/shared/boundedSet.d.ts.map +1 -0
- package/dist/shared/boundedSet.js +64 -0
- package/dist/shared/boundedSet.js.map +1 -0
- package/dist/shared/lru.d.ts +5 -197
- package/dist/shared/lru.d.ts.map +1 -1
- package/dist/shared/lru.js +5 -538
- package/dist/shared/lru.js.map +1 -1
- package/dist/shared/lruMap.d.ts +43 -0
- package/dist/shared/lruMap.d.ts.map +1 -0
- package/dist/shared/lruMap.js +142 -0
- package/dist/shared/lruMap.js.map +1 -0
- package/dist/shared/lruSet.d.ts +37 -0
- package/dist/shared/lruSet.d.ts.map +1 -0
- package/dist/shared/lruSet.js +106 -0
- package/dist/shared/lruSet.js.map +1 -0
- package/dist/shared/ttlMap.d.ts +82 -0
- package/dist/shared/ttlMap.d.ts.map +1 -0
- package/dist/shared/ttlMap.js +169 -0
- package/dist/shared/ttlMap.js.map +1 -0
- package/package.json +1 -1
package/dist/shared/lru.js
CHANGED
|
@@ -2,542 +2,9 @@
|
|
|
2
2
|
* LRU (Least Recently Used) Cache implementations
|
|
3
3
|
* Bounded collections with automatic eviction
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
export class LRUMap {
|
|
12
|
-
cache = new Map();
|
|
13
|
-
maxSize;
|
|
14
|
-
onEvict;
|
|
15
|
-
// Doubly-linked list head (most recent) and tail (least recent)
|
|
16
|
-
head = null;
|
|
17
|
-
tail = null;
|
|
18
|
-
constructor(maxSize, onEvict) {
|
|
19
|
-
this.maxSize = maxSize;
|
|
20
|
-
this.onEvict = onEvict;
|
|
21
|
-
}
|
|
22
|
-
/** Move node to front (most recently used) - O(1) */
|
|
23
|
-
moveToFront(node) {
|
|
24
|
-
if (node === this.head)
|
|
25
|
-
return; // Already at front
|
|
26
|
-
// Detach from current position
|
|
27
|
-
if (node.prev)
|
|
28
|
-
node.prev.next = node.next;
|
|
29
|
-
if (node.next)
|
|
30
|
-
node.next.prev = node.prev;
|
|
31
|
-
if (node === this.tail)
|
|
32
|
-
this.tail = node.prev;
|
|
33
|
-
// Move to front
|
|
34
|
-
node.prev = null;
|
|
35
|
-
node.next = this.head;
|
|
36
|
-
if (this.head)
|
|
37
|
-
this.head.prev = node;
|
|
38
|
-
this.head = node;
|
|
39
|
-
this.tail ??= node;
|
|
40
|
-
}
|
|
41
|
-
/** Remove node from list - O(1) */
|
|
42
|
-
removeNode(node) {
|
|
43
|
-
if (node.prev)
|
|
44
|
-
node.prev.next = node.next;
|
|
45
|
-
if (node.next)
|
|
46
|
-
node.next.prev = node.prev;
|
|
47
|
-
if (node === this.head)
|
|
48
|
-
this.head = node.next;
|
|
49
|
-
if (node === this.tail)
|
|
50
|
-
this.tail = node.prev;
|
|
51
|
-
}
|
|
52
|
-
/** Add node to front - O(1) */
|
|
53
|
-
addToFront(node) {
|
|
54
|
-
node.prev = null;
|
|
55
|
-
node.next = this.head;
|
|
56
|
-
if (this.head)
|
|
57
|
-
this.head.prev = node;
|
|
58
|
-
this.head = node;
|
|
59
|
-
this.tail ??= node;
|
|
60
|
-
}
|
|
61
|
-
get(key) {
|
|
62
|
-
const node = this.cache.get(key);
|
|
63
|
-
if (!node)
|
|
64
|
-
return undefined;
|
|
65
|
-
// Move to front - O(1) without delete+re-insert
|
|
66
|
-
this.moveToFront(node);
|
|
67
|
-
return node.value;
|
|
68
|
-
}
|
|
69
|
-
set(key, value) {
|
|
70
|
-
const existing = this.cache.get(key);
|
|
71
|
-
if (existing) {
|
|
72
|
-
// Update value and move to front
|
|
73
|
-
existing.value = value;
|
|
74
|
-
this.moveToFront(existing);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
// Evict if at capacity
|
|
78
|
-
if (this.cache.size >= this.maxSize && this.tail) {
|
|
79
|
-
const evicted = this.tail;
|
|
80
|
-
this.cache.delete(evicted.key);
|
|
81
|
-
this.removeNode(evicted);
|
|
82
|
-
this.onEvict?.(evicted.key, evicted.value);
|
|
83
|
-
}
|
|
84
|
-
// Add new node
|
|
85
|
-
const node = { key, value, prev: null, next: null };
|
|
86
|
-
this.cache.set(key, node);
|
|
87
|
-
this.addToFront(node);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
has(key) {
|
|
91
|
-
return this.cache.has(key);
|
|
92
|
-
}
|
|
93
|
-
delete(key) {
|
|
94
|
-
const node = this.cache.get(key);
|
|
95
|
-
if (!node)
|
|
96
|
-
return false;
|
|
97
|
-
this.removeNode(node);
|
|
98
|
-
return this.cache.delete(key);
|
|
99
|
-
}
|
|
100
|
-
clear() {
|
|
101
|
-
this.cache.clear();
|
|
102
|
-
this.head = null;
|
|
103
|
-
this.tail = null;
|
|
104
|
-
}
|
|
105
|
-
get size() {
|
|
106
|
-
return this.cache.size;
|
|
107
|
-
}
|
|
108
|
-
*keys() {
|
|
109
|
-
// Iterate from tail (oldest) to head (newest) to match original Map behavior
|
|
110
|
-
let current = this.tail;
|
|
111
|
-
while (current) {
|
|
112
|
-
yield current.key;
|
|
113
|
-
current = current.prev;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
*values() {
|
|
117
|
-
// Iterate from tail (oldest) to head (newest) to match original Map behavior
|
|
118
|
-
let current = this.tail;
|
|
119
|
-
while (current) {
|
|
120
|
-
yield current.value;
|
|
121
|
-
current = current.prev;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
*entries() {
|
|
125
|
-
// Iterate from tail (oldest) to head (newest) to match original Map behavior
|
|
126
|
-
let current = this.tail;
|
|
127
|
-
while (current) {
|
|
128
|
-
yield [current.key, current.value];
|
|
129
|
-
current = current.prev;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
forEach(callback) {
|
|
133
|
-
// Iterate from tail (oldest) to head (newest) to match original Map behavior
|
|
134
|
-
let current = this.tail;
|
|
135
|
-
while (current) {
|
|
136
|
-
callback(current.value, current.key);
|
|
137
|
-
current = current.prev;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
[Symbol.iterator]() {
|
|
141
|
-
return this.entries();
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* LRU Set - automatically evicts least recently used entries
|
|
146
|
-
* Optimized with doubly-linked list for O(1) move-to-front
|
|
147
|
-
*/
|
|
148
|
-
export class LRUSet {
|
|
149
|
-
cache = new Map();
|
|
150
|
-
maxSize;
|
|
151
|
-
onEvict;
|
|
152
|
-
// Doubly-linked list head (most recent) and tail (least recent)
|
|
153
|
-
head = null;
|
|
154
|
-
tail = null;
|
|
155
|
-
constructor(maxSize, onEvict) {
|
|
156
|
-
this.maxSize = maxSize;
|
|
157
|
-
this.onEvict = onEvict;
|
|
158
|
-
}
|
|
159
|
-
/** Move node to front - O(1) */
|
|
160
|
-
moveToFront(node) {
|
|
161
|
-
if (node === this.head)
|
|
162
|
-
return;
|
|
163
|
-
if (node.prev)
|
|
164
|
-
node.prev.next = node.next;
|
|
165
|
-
if (node.next)
|
|
166
|
-
node.next.prev = node.prev;
|
|
167
|
-
if (node === this.tail)
|
|
168
|
-
this.tail = node.prev;
|
|
169
|
-
node.prev = null;
|
|
170
|
-
node.next = this.head;
|
|
171
|
-
if (this.head)
|
|
172
|
-
this.head.prev = node;
|
|
173
|
-
this.head = node;
|
|
174
|
-
this.tail ??= node;
|
|
175
|
-
}
|
|
176
|
-
/** Remove node from list - O(1) */
|
|
177
|
-
removeNode(node) {
|
|
178
|
-
if (node.prev)
|
|
179
|
-
node.prev.next = node.next;
|
|
180
|
-
if (node.next)
|
|
181
|
-
node.next.prev = node.prev;
|
|
182
|
-
if (node === this.head)
|
|
183
|
-
this.head = node.next;
|
|
184
|
-
if (node === this.tail)
|
|
185
|
-
this.tail = node.prev;
|
|
186
|
-
}
|
|
187
|
-
/** Add node to front - O(1) */
|
|
188
|
-
addToFront(node) {
|
|
189
|
-
node.prev = null;
|
|
190
|
-
node.next = this.head;
|
|
191
|
-
if (this.head)
|
|
192
|
-
this.head.prev = node;
|
|
193
|
-
this.head = node;
|
|
194
|
-
this.tail ??= node;
|
|
195
|
-
}
|
|
196
|
-
add(value) {
|
|
197
|
-
const existing = this.cache.get(value);
|
|
198
|
-
if (existing) {
|
|
199
|
-
// Move to front
|
|
200
|
-
this.moveToFront(existing);
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
// Evict if at capacity
|
|
204
|
-
if (this.cache.size >= this.maxSize && this.tail) {
|
|
205
|
-
const evicted = this.tail;
|
|
206
|
-
this.cache.delete(evicted.value);
|
|
207
|
-
this.removeNode(evicted);
|
|
208
|
-
this.onEvict?.(evicted.value);
|
|
209
|
-
}
|
|
210
|
-
// Add new node
|
|
211
|
-
const node = { value, prev: null, next: null };
|
|
212
|
-
this.cache.set(value, node);
|
|
213
|
-
this.addToFront(node);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
has(value) {
|
|
217
|
-
return this.cache.has(value);
|
|
218
|
-
}
|
|
219
|
-
delete(value) {
|
|
220
|
-
const node = this.cache.get(value);
|
|
221
|
-
if (!node)
|
|
222
|
-
return false;
|
|
223
|
-
this.removeNode(node);
|
|
224
|
-
return this.cache.delete(value);
|
|
225
|
-
}
|
|
226
|
-
clear() {
|
|
227
|
-
this.cache.clear();
|
|
228
|
-
this.head = null;
|
|
229
|
-
this.tail = null;
|
|
230
|
-
}
|
|
231
|
-
get size() {
|
|
232
|
-
return this.cache.size;
|
|
233
|
-
}
|
|
234
|
-
*values() {
|
|
235
|
-
// Iterate from tail (oldest) to head (newest) to match original Set behavior
|
|
236
|
-
let current = this.tail;
|
|
237
|
-
while (current) {
|
|
238
|
-
yield current.value;
|
|
239
|
-
current = current.prev;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
[Symbol.iterator]() {
|
|
243
|
-
return this.values();
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Bounded Set - fast FIFO eviction without LRU tracking
|
|
248
|
-
* Optimized for high-throughput scenarios where recency doesn't matter
|
|
249
|
-
* Uses batch eviction to avoid per-item iterator overhead
|
|
250
|
-
*/
|
|
251
|
-
export class BoundedSet {
|
|
252
|
-
cache = new Set();
|
|
253
|
-
maxSize;
|
|
254
|
-
onEvict;
|
|
255
|
-
/** Evict 10% of items at once to amortize iterator cost */
|
|
256
|
-
evictBatchSize;
|
|
257
|
-
constructor(maxSize, onEvict) {
|
|
258
|
-
this.maxSize = maxSize;
|
|
259
|
-
this.onEvict = onEvict;
|
|
260
|
-
this.evictBatchSize = Math.max(1, Math.floor(maxSize * 0.1));
|
|
261
|
-
}
|
|
262
|
-
add(value) {
|
|
263
|
-
// Fast path: already exists - no-op
|
|
264
|
-
if (this.cache.has(value))
|
|
265
|
-
return;
|
|
266
|
-
// Batch evict if at capacity - amortizes iterator cost
|
|
267
|
-
if (this.cache.size >= this.maxSize) {
|
|
268
|
-
this.evictBatch();
|
|
269
|
-
}
|
|
270
|
-
this.cache.add(value);
|
|
271
|
-
}
|
|
272
|
-
/** Evict multiple items at once - more efficient than one at a time */
|
|
273
|
-
evictBatch() {
|
|
274
|
-
const toEvict = [];
|
|
275
|
-
const iter = this.cache.values();
|
|
276
|
-
for (let i = 0; i < this.evictBatchSize; i++) {
|
|
277
|
-
const { value, done } = iter.next();
|
|
278
|
-
if (done)
|
|
279
|
-
break;
|
|
280
|
-
toEvict.push(value);
|
|
281
|
-
}
|
|
282
|
-
for (const value of toEvict) {
|
|
283
|
-
this.cache.delete(value);
|
|
284
|
-
this.onEvict?.(value);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
has(value) {
|
|
288
|
-
return this.cache.has(value);
|
|
289
|
-
}
|
|
290
|
-
delete(value) {
|
|
291
|
-
return this.cache.delete(value);
|
|
292
|
-
}
|
|
293
|
-
clear() {
|
|
294
|
-
this.cache.clear();
|
|
295
|
-
}
|
|
296
|
-
get size() {
|
|
297
|
-
return this.cache.size;
|
|
298
|
-
}
|
|
299
|
-
values() {
|
|
300
|
-
return this.cache.values();
|
|
301
|
-
}
|
|
302
|
-
[Symbol.iterator]() {
|
|
303
|
-
return this.cache[Symbol.iterator]();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Bounded Map - fast FIFO eviction without LRU tracking
|
|
308
|
-
* Optimized for high-throughput scenarios where recency doesn't matter
|
|
309
|
-
* Uses batch eviction to avoid per-item iterator overhead
|
|
310
|
-
*/
|
|
311
|
-
export class BoundedMap {
|
|
312
|
-
cache = new Map();
|
|
313
|
-
maxSize;
|
|
314
|
-
onEvict;
|
|
315
|
-
/** Evict 10% of items at once to amortize iterator cost */
|
|
316
|
-
evictBatchSize;
|
|
317
|
-
constructor(maxSize, onEvict) {
|
|
318
|
-
this.maxSize = maxSize;
|
|
319
|
-
this.onEvict = onEvict;
|
|
320
|
-
this.evictBatchSize = Math.max(1, Math.floor(maxSize * 0.1));
|
|
321
|
-
}
|
|
322
|
-
get(key) {
|
|
323
|
-
return this.cache.get(key);
|
|
324
|
-
}
|
|
325
|
-
set(key, value) {
|
|
326
|
-
// Fast path: key already exists - update in place
|
|
327
|
-
if (this.cache.has(key)) {
|
|
328
|
-
this.cache.set(key, value);
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
// Batch evict if at capacity
|
|
332
|
-
if (this.cache.size >= this.maxSize) {
|
|
333
|
-
this.evictBatch();
|
|
334
|
-
}
|
|
335
|
-
this.cache.set(key, value);
|
|
336
|
-
}
|
|
337
|
-
/** Evict multiple items at once - more efficient than one at a time */
|
|
338
|
-
evictBatch() {
|
|
339
|
-
const toEvict = [];
|
|
340
|
-
const iter = this.cache.entries();
|
|
341
|
-
for (let i = 0; i < this.evictBatchSize; i++) {
|
|
342
|
-
const { value, done } = iter.next();
|
|
343
|
-
if (done)
|
|
344
|
-
break;
|
|
345
|
-
toEvict.push({ key: value[0], value: value[1] });
|
|
346
|
-
}
|
|
347
|
-
for (const { key, value } of toEvict) {
|
|
348
|
-
this.cache.delete(key);
|
|
349
|
-
this.onEvict?.(key, value);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
has(key) {
|
|
353
|
-
return this.cache.has(key);
|
|
354
|
-
}
|
|
355
|
-
delete(key) {
|
|
356
|
-
return this.cache.delete(key);
|
|
357
|
-
}
|
|
358
|
-
clear() {
|
|
359
|
-
this.cache.clear();
|
|
360
|
-
}
|
|
361
|
-
get size() {
|
|
362
|
-
return this.cache.size;
|
|
363
|
-
}
|
|
364
|
-
keys() {
|
|
365
|
-
return this.cache.keys();
|
|
366
|
-
}
|
|
367
|
-
values() {
|
|
368
|
-
return this.cache.values();
|
|
369
|
-
}
|
|
370
|
-
entries() {
|
|
371
|
-
return this.cache.entries();
|
|
372
|
-
}
|
|
373
|
-
forEach(callback) {
|
|
374
|
-
this.cache.forEach(callback);
|
|
375
|
-
}
|
|
376
|
-
[Symbol.iterator]() {
|
|
377
|
-
return this.cache[Symbol.iterator]();
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* TTL Map - entries expire after timeout
|
|
382
|
-
* Optimized with MinHeap for O(log n) insert and O(k) cleanup
|
|
383
|
-
*
|
|
384
|
-
* IMPORTANT: You MUST call stop() when done with this instance to prevent memory leaks.
|
|
385
|
-
* The cleanup interval will keep running until stop() is called, preventing the instance
|
|
386
|
-
* from being garbage collected.
|
|
387
|
-
*
|
|
388
|
-
* @example
|
|
389
|
-
* ```typescript
|
|
390
|
-
* const map = new TTLMap<string, number>(60_000); // 60s TTL
|
|
391
|
-
* try {
|
|
392
|
-
* map.set('key', 123);
|
|
393
|
-
* // use map...
|
|
394
|
-
* } finally {
|
|
395
|
-
* map.stop(); // REQUIRED: stops cleanup interval
|
|
396
|
-
* }
|
|
397
|
-
* ```
|
|
398
|
-
*
|
|
399
|
-
* Memory leak prevention:
|
|
400
|
-
* - Each heap entry stores (expiresAt, key)
|
|
401
|
-
* - During cleanup, we verify the key still exists in cache AND has matching expiresAt
|
|
402
|
-
* - Stale entries (deleted keys or updated TTLs) are skipped and removed from heap
|
|
403
|
-
* - Periodic compaction rebuilds heap when stale ratio exceeds threshold
|
|
404
|
-
*/
|
|
405
|
-
export class TTLMap {
|
|
406
|
-
cache = new Map();
|
|
407
|
-
ttlMs;
|
|
408
|
-
cleanupInterval = null;
|
|
409
|
-
/**
|
|
410
|
-
* Expiry heap: MinHeap of (expiresAt, key) for efficient cleanup
|
|
411
|
-
* O(log n) insert instead of O(n) with array splice
|
|
412
|
-
*/
|
|
413
|
-
expiryHeap = new MinHeap((a, b) => a.expiresAt - b.expiresAt);
|
|
414
|
-
/** Count of stale entries in heap (deleted or updated keys) */
|
|
415
|
-
staleCount = 0;
|
|
416
|
-
/** Rebuild heap when stale entries exceed this ratio of heap size */
|
|
417
|
-
static COMPACTION_THRESHOLD = 0.5;
|
|
418
|
-
/** Minimum heap size before considering compaction (avoid frequent rebuilds for small heaps) */
|
|
419
|
-
static MIN_COMPACTION_SIZE = 100;
|
|
420
|
-
/**
|
|
421
|
-
* Create a new TTLMap instance.
|
|
422
|
-
*
|
|
423
|
-
* @param ttlMs - Default time-to-live for entries in milliseconds
|
|
424
|
-
* @param cleanupIntervalMs - Interval between cleanup runs (default: 60000ms / 1 minute).
|
|
425
|
-
* Lower values = more frequent cleanup but higher CPU usage.
|
|
426
|
-
* Set based on expected entry volume and TTL duration.
|
|
427
|
-
*/
|
|
428
|
-
constructor(ttlMs, cleanupIntervalMs = 60_000) {
|
|
429
|
-
this.ttlMs = ttlMs;
|
|
430
|
-
this.startCleanup(cleanupIntervalMs);
|
|
431
|
-
}
|
|
432
|
-
startCleanup(intervalMs) {
|
|
433
|
-
this.cleanupInterval = setInterval(() => {
|
|
434
|
-
this.cleanup();
|
|
435
|
-
}, intervalMs);
|
|
436
|
-
}
|
|
437
|
-
/** O(k log n) cleanup where k = expired entries */
|
|
438
|
-
cleanup() {
|
|
439
|
-
const now = Date.now();
|
|
440
|
-
// Remove expired entries from heap - O(k log n)
|
|
441
|
-
while (!this.expiryHeap.isEmpty) {
|
|
442
|
-
const top = this.expiryHeap.peek();
|
|
443
|
-
if (!top || top.expiresAt > now)
|
|
444
|
-
break;
|
|
445
|
-
this.expiryHeap.pop();
|
|
446
|
-
const { key, expiresAt } = top;
|
|
447
|
-
// Verify entry still exists and has same expiry (might have been updated or deleted)
|
|
448
|
-
const entry = this.cache.get(key);
|
|
449
|
-
if (entry?.expiresAt === expiresAt) {
|
|
450
|
-
// Valid expired entry - delete from cache
|
|
451
|
-
this.cache.delete(key);
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
// Stale heap entry (key deleted or TTL updated) - already removed, decrement counter
|
|
455
|
-
if (this.staleCount > 0)
|
|
456
|
-
this.staleCount--;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
// Compact heap if too many stale entries accumulated
|
|
460
|
-
this.maybeCompact();
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Rebuild heap if stale entry ratio exceeds threshold
|
|
464
|
-
* This prevents unbounded heap growth from delete() and set() updates
|
|
465
|
-
*/
|
|
466
|
-
maybeCompact() {
|
|
467
|
-
const heapSize = this.expiryHeap.size;
|
|
468
|
-
if (heapSize >= TTLMap.MIN_COMPACTION_SIZE &&
|
|
469
|
-
this.staleCount / heapSize > TTLMap.COMPACTION_THRESHOLD) {
|
|
470
|
-
this.rebuildHeap();
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
/** Rebuild heap with only valid entries - O(n log n) */
|
|
474
|
-
rebuildHeap() {
|
|
475
|
-
this.expiryHeap.clear();
|
|
476
|
-
this.staleCount = 0;
|
|
477
|
-
// Re-add all valid cache entries to heap
|
|
478
|
-
for (const [key, entry] of this.cache) {
|
|
479
|
-
this.expiryHeap.push({ expiresAt: entry.expiresAt, key });
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
get(key) {
|
|
483
|
-
const entry = this.cache.get(key);
|
|
484
|
-
if (!entry)
|
|
485
|
-
return undefined;
|
|
486
|
-
if (entry.expiresAt <= Date.now()) {
|
|
487
|
-
this.cache.delete(key);
|
|
488
|
-
this.staleCount++; // Heap entry is now stale
|
|
489
|
-
return undefined;
|
|
490
|
-
}
|
|
491
|
-
return entry.value;
|
|
492
|
-
}
|
|
493
|
-
/** O(log n) insert with MinHeap instead of O(n) with array splice */
|
|
494
|
-
set(key, value, ttlMs) {
|
|
495
|
-
const expiresAt = Date.now() + (ttlMs ?? this.ttlMs);
|
|
496
|
-
// Check if key already exists - old heap entry becomes stale
|
|
497
|
-
if (this.cache.has(key)) {
|
|
498
|
-
this.staleCount++;
|
|
499
|
-
}
|
|
500
|
-
this.cache.set(key, { value, expiresAt });
|
|
501
|
-
// Add to expiry heap - O(log n) with MinHeap
|
|
502
|
-
this.expiryHeap.push({ expiresAt, key });
|
|
503
|
-
}
|
|
504
|
-
has(key) {
|
|
505
|
-
return this.get(key) !== undefined;
|
|
506
|
-
}
|
|
507
|
-
delete(key) {
|
|
508
|
-
const existed = this.cache.delete(key);
|
|
509
|
-
if (existed) {
|
|
510
|
-
// Heap entry is now stale - will be cleaned up lazily or during compaction
|
|
511
|
-
this.staleCount++;
|
|
512
|
-
}
|
|
513
|
-
return existed;
|
|
514
|
-
}
|
|
515
|
-
clear() {
|
|
516
|
-
this.cache.clear();
|
|
517
|
-
this.expiryHeap.clear();
|
|
518
|
-
this.staleCount = 0;
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Stop the cleanup interval. MUST be called when done with this instance
|
|
522
|
-
* to prevent memory leaks. The interval keeps a reference to the instance,
|
|
523
|
-
* preventing garbage collection until stop() is called.
|
|
524
|
-
*/
|
|
525
|
-
stop() {
|
|
526
|
-
if (this.cleanupInterval) {
|
|
527
|
-
clearInterval(this.cleanupInterval);
|
|
528
|
-
this.cleanupInterval = null;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
get size() {
|
|
532
|
-
return this.cache.size;
|
|
533
|
-
}
|
|
534
|
-
/** Get heap size (for debugging/monitoring) */
|
|
535
|
-
get heapSize() {
|
|
536
|
-
return this.expiryHeap.size;
|
|
537
|
-
}
|
|
538
|
-
/** Get count of stale heap entries (for debugging/monitoring) */
|
|
539
|
-
get staleEntryCount() {
|
|
540
|
-
return this.staleCount;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
5
|
+
export { LRUMap } from './lruMap';
|
|
6
|
+
export { LRUSet } from './lruSet';
|
|
7
|
+
export { BoundedSet } from './boundedSet';
|
|
8
|
+
export { BoundedMap } from './boundedMap';
|
|
9
|
+
export { TTLMap } from './ttlMap';
|
|
543
10
|
//# sourceMappingURL=lru.js.map
|
package/dist/shared/lru.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lru.js","sourceRoot":"","sources":["../../src/shared/lru.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lru.js","sourceRoot":"","sources":["../../src/shared/lru.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAgB,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LRU Map - Map with automatic least-recently-used eviction
|
|
3
|
+
*/
|
|
4
|
+
/** Map-like interface for LRU compatibility */
|
|
5
|
+
export interface MapLike<K, V> {
|
|
6
|
+
get(key: K): V | undefined;
|
|
7
|
+
set(key: K, value: V): void;
|
|
8
|
+
has(key: K): boolean;
|
|
9
|
+
delete(key: K): boolean;
|
|
10
|
+
clear(): void;
|
|
11
|
+
readonly size: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* LRU Map - automatically evicts least recently used entries
|
|
15
|
+
* Optimized with doubly-linked list for O(1) move-to-front
|
|
16
|
+
* without delete+re-insert overhead
|
|
17
|
+
*/
|
|
18
|
+
export declare class LRUMap<K, V> implements MapLike<K, V> {
|
|
19
|
+
private readonly cache;
|
|
20
|
+
private readonly maxSize;
|
|
21
|
+
private readonly onEvict?;
|
|
22
|
+
private head;
|
|
23
|
+
private tail;
|
|
24
|
+
constructor(maxSize: number, onEvict?: (key: K, value: V) => void);
|
|
25
|
+
/** Move node to front (most recently used) - O(1) */
|
|
26
|
+
private moveToFront;
|
|
27
|
+
/** Remove node from list - O(1) */
|
|
28
|
+
private removeNode;
|
|
29
|
+
/** Add node to front - O(1) */
|
|
30
|
+
private addToFront;
|
|
31
|
+
get(key: K): V | undefined;
|
|
32
|
+
set(key: K, value: V): void;
|
|
33
|
+
has(key: K): boolean;
|
|
34
|
+
delete(key: K): boolean;
|
|
35
|
+
clear(): void;
|
|
36
|
+
get size(): number;
|
|
37
|
+
keys(): IterableIterator<K>;
|
|
38
|
+
values(): IterableIterator<V>;
|
|
39
|
+
entries(): IterableIterator<[K, V]>;
|
|
40
|
+
forEach(callback: (value: V, key: K) => void): void;
|
|
41
|
+
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=lruMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lruMap.d.ts","sourceRoot":"","sources":["../../src/shared/lruMap.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC;IAC3B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC3B,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC5B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IACrB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAUD;;;;GAIG;AACH,qBAAa,MAAM,CAAC,CAAC,EAAE,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA6B;IAGtD,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,IAAI,CAA8B;gBAE9B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI;IAKjE,qDAAqD;IACrD,OAAO,CAAC,WAAW;IAgBnB,mCAAmC;IACnC,OAAO,CAAC,UAAU;IAOlB,+BAA+B;IAC/B,OAAO,CAAC,UAAU;IAQlB,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAS1B,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAuB3B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAQvB,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAS3B,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAS7B,OAAO,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IASpC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,IAAI;IASnD,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAG9C"}
|