0
# Quick LRU
1
2
Quick LRU is a high-performance Least Recently Used (LRU) cache implementation that extends JavaScript's native Map class with memory management capabilities. It supports advanced features including configurable maximum cache size with automatic eviction, optional time-based expiration with lazy cleanup, customizable eviction callbacks, and comprehensive cache management methods.
3
4
## Package Information
5
6
- **Package Name**: quick-lru
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install quick-lru`
10
11
## Core Imports
12
13
```javascript
14
import QuickLRU from 'quick-lru';
15
```
16
17
For CommonJS:
18
19
```javascript
20
const QuickLRU = require('quick-lru');
21
```
22
23
## Basic Usage
24
25
```javascript
26
import QuickLRU from 'quick-lru';
27
28
// Create a cache with maximum 1000 items
29
const cache = new QuickLRU({ maxSize: 1000 });
30
31
// Set values
32
cache.set('π¦', 'π');
33
cache.set('π', 'π');
34
35
// Get values
36
cache.get('π¦'); // 'π'
37
38
// Check existence
39
cache.has('π¦'); // true
40
41
// Get without affecting recency
42
cache.peek('π¦'); // 'π'
43
44
// Cache with expiration
45
const cacheWithTTL = new QuickLRU({
46
maxSize: 100,
47
maxAge: 60000, // 60 seconds
48
onEviction: (key, value) => console.log(`Evicted ${key}: ${value}`)
49
});
50
51
cacheWithTTL.set('temp', 'data', { maxAge: 30000 }); // 30 second override
52
```
53
54
## Architecture
55
56
Quick LRU uses a dual-cache design for optimal performance:
57
58
- **Current Cache**: Most recently accessed items, implemented as a Map
59
- **Old Cache**: Previously accessed items that get moved to current cache on access
60
- **Two-Phase Eviction**: When current cache fills, it becomes the old cache and a new current cache is created
61
- **Lazy Expiration**: Items are only checked for expiration during access operations
62
- **Map Compatibility**: Full compatibility with Map interface while adding caching functionality
63
64
## Capabilities
65
66
### Constructor
67
68
Creates a new QuickLRU cache instance.
69
70
```typescript { .api }
71
class QuickLRU<KeyType, ValueType> extends Map<KeyType, ValueType> {
72
constructor(options: Options<KeyType, ValueType>);
73
}
74
75
interface Options<KeyType, ValueType> {
76
/** Maximum number of items before evicting least recently used items */
77
readonly maxSize: number;
78
/** Maximum milliseconds an item should remain in cache (default: Infinity) */
79
readonly maxAge?: number;
80
/** Called right before an item is evicted from the cache */
81
onEviction?: (key: KeyType, value: ValueType) => void;
82
}
83
```
84
85
**Usage Example:**
86
87
```javascript
88
// Basic cache
89
const cache = new QuickLRU({ maxSize: 100 });
90
91
// Cache with TTL and eviction callback
92
const advancedCache = new QuickLRU({
93
maxSize: 50,
94
maxAge: 300000, // 5 minutes
95
onEviction: (key, value) => {
96
console.log(`Evicted ${key}`);
97
// Cleanup logic for URLs, file handles, etc.
98
}
99
});
100
```
101
102
### Core Cache Operations
103
104
#### Set Item
105
106
Sets an item in the cache with optional per-item expiration.
107
108
```typescript { .api }
109
/**
110
* Set an item in the cache
111
* @param key - The key to store the value under
112
* @param value - The value to store
113
* @param options - Optional settings for this specific item
114
* @returns The cache instance for chaining
115
*/
116
set(key: KeyType, value: ValueType, options?: { maxAge?: number }): this;
117
```
118
119
**Usage Example:**
120
121
```javascript
122
cache.set('user:123', userData);
123
cache.set('session:abc', sessionData, { maxAge: 3600000 }); // 1 hour TTL
124
```
125
126
#### Get Item
127
128
Retrieves an item from the cache and marks it as recently used.
129
130
```typescript { .api }
131
/**
132
* Get an item from the cache
133
* @param key - The key to retrieve
134
* @returns The stored value or undefined if not found or expired
135
*/
136
get(key: KeyType): ValueType | undefined;
137
```
138
139
#### Check Existence
140
141
Checks if an item exists in the cache without affecting its recency.
142
143
```typescript { .api }
144
/**
145
* Check if an item exists in the cache
146
* @param key - The key to check
147
* @returns True if the item exists and is not expired
148
*/
149
has(key: KeyType): boolean;
150
```
151
152
#### Peek Item
153
154
Gets an item without marking it as recently used.
155
156
```typescript { .api }
157
/**
158
* Get an item without marking it as recently used
159
* @param key - The key to peek at
160
* @returns The stored value or undefined if not found or expired
161
*/
162
peek(key: KeyType): ValueType | undefined;
163
```
164
165
#### Delete Item
166
167
Removes an item from the cache.
168
169
```typescript { .api }
170
/**
171
* Delete an item from the cache
172
* @param key - The key to delete
173
* @returns True if the item was removed, false if it didn't exist
174
*/
175
delete(key: KeyType): boolean;
176
```
177
178
#### Clear Cache
179
180
Removes all items from the cache.
181
182
```typescript { .api }
183
/**
184
* Delete all items from the cache
185
*/
186
clear(): void;
187
```
188
189
### Cache Management
190
191
#### Check Expiration Time
192
193
Gets the remaining time to live for an item.
194
195
```typescript { .api }
196
/**
197
* Get remaining time to live for an item in milliseconds
198
* @param key - The key to check
199
* @returns Milliseconds until expiration, Infinity if no expiration, or undefined if item doesn't exist
200
*/
201
expiresIn(key: KeyType): number | undefined;
202
```
203
204
**Usage Example:**
205
206
```javascript
207
cache.set('temp', 'data', { maxAge: 60000 });
208
setTimeout(() => {
209
const ttl = cache.expiresIn('temp');
210
console.log(`Item expires in ${ttl}ms`);
211
}, 30000);
212
```
213
214
#### Resize Cache
215
216
Updates the maximum cache size, discarding items as necessary.
217
218
```typescript { .api }
219
/**
220
* Update the maximum cache size
221
* @param maxSize - New maximum size (must be > 0)
222
* @throws TypeError if maxSize is not a number greater than 0
223
*/
224
resize(maxSize: number): void;
225
```
226
227
**Usage Example:**
228
229
```javascript
230
const cache = new QuickLRU({ maxSize: 100 });
231
// Later, dynamically adjust size based on memory constraints
232
cache.resize(50); // Evicts oldest items if needed
233
```
234
235
### Properties
236
237
#### Current Size
238
239
Gets the current number of items in the cache.
240
241
```typescript { .api }
242
/**
243
* The current number of items stored in the cache
244
*/
245
get size(): number;
246
```
247
248
#### Maximum Size
249
250
Gets the maximum number of items the cache can hold.
251
252
```typescript { .api }
253
/**
254
* The maximum number of items the cache can hold
255
*/
256
get maxSize(): number;
257
```
258
259
### Iteration Methods
260
261
#### Keys Iterator
262
263
Iterates over all keys in the cache.
264
265
```typescript { .api }
266
/**
267
* Iterator for all keys in the cache
268
* @returns Iterator of keys in recency order (oldest first)
269
*/
270
keys(): IterableIterator<KeyType>;
271
```
272
273
#### Values Iterator
274
275
Iterates over all values in the cache.
276
277
```typescript { .api }
278
/**
279
* Iterator for all values in the cache
280
* @returns Iterator of values in recency order (oldest first)
281
*/
282
values(): IterableIterator<ValueType>;
283
```
284
285
#### Default Iterator
286
287
Default iterator for the cache (same as entriesAscending).
288
289
```typescript { .api }
290
/**
291
* Default iterator returning key-value pairs
292
* @returns Iterator of [key, value] pairs in recency order (oldest first)
293
*/
294
[Symbol.iterator](): IterableIterator<[KeyType, ValueType]>;
295
```
296
297
**Usage Example:**
298
299
```javascript
300
// Using for...of loop
301
for (const [key, value] of cache) {
302
console.log(`${key}: ${value}`);
303
}
304
305
// Using spread operator
306
const entries = [...cache];
307
```
308
309
#### Entries Ascending
310
311
Iterates over entries from oldest to newest.
312
313
```typescript { .api }
314
/**
315
* Iterator for entries in ascending recency order (oldest first)
316
* @returns Iterator of [key, value] pairs
317
*/
318
entriesAscending(): IterableIterator<[KeyType, ValueType]>;
319
```
320
321
#### Entries Descending
322
323
Iterates over entries from newest to oldest.
324
325
```typescript { .api }
326
/**
327
* Iterator for entries in descending recency order (newest first)
328
* @returns Iterator of [key, value] pairs
329
*/
330
entriesDescending(): IterableIterator<[KeyType, ValueType]>;
331
```
332
333
#### Entries (Map Compatible)
334
335
Map-compatible entries method (same as entriesAscending).
336
337
```typescript { .api }
338
/**
339
* Iterator for entries (Map compatibility)
340
* @returns Iterator of [key, value] pairs in ascending recency order
341
*/
342
entries(): IterableIterator<[KeyType, ValueType]>;
343
```
344
345
#### ForEach Method
346
347
Executes a callback for each entry in the cache.
348
349
```typescript { .api }
350
/**
351
* Execute a callback for each entry in the cache
352
* @param callbackFunction - Function called for each entry
353
* @param thisArgument - Value to use as 'this' when executing callback
354
*/
355
forEach(
356
callbackFunction: (value: ValueType, key: KeyType, cache: this) => void,
357
thisArgument?: any
358
): void;
359
```
360
361
**Usage Example:**
362
363
```javascript
364
cache.forEach((value, key) => {
365
console.log(`Processing ${key}: ${value}`);
366
});
367
```
368
369
### Utility Methods
370
371
#### String Representation
372
373
Returns a string representation of the cache.
374
375
```typescript { .api }
376
/**
377
* Returns string representation of the cache
378
* @returns String in format "QuickLRU(currentSize/maxSize)"
379
*/
380
toString(): string;
381
```
382
383
#### Symbol.toStringTag
384
385
Provides the string tag for Object.prototype.toString.
386
387
```typescript { .api }
388
/**
389
* String tag for Object.prototype.toString
390
*/
391
get [Symbol.toStringTag](): 'QuickLRU';
392
```
393
394
#### Node.js Inspect
395
396
Custom inspect method for Node.js util.inspect.
397
398
```typescript { .api }
399
/**
400
* Custom inspect method for Node.js util.inspect
401
* @returns String representation of the cache
402
*/
403
[Symbol.for('nodejs.util.inspect.custom')](): string;
404
```
405
406
## Error Handling
407
408
Quick LRU throws TypeError in the following cases:
409
410
- **Constructor**: When `maxSize` is not a number greater than 0
411
- **Constructor**: When `maxAge` is explicitly set to 0 (use undefined for no expiration)
412
- **resize()**: When `maxSize` parameter is not a number greater than 0
413
414
```javascript
415
// These will throw TypeError
416
try {
417
new QuickLRU({ maxSize: 0 }); // maxSize must be > 0
418
new QuickLRU({ maxSize: 100, maxAge: 0 }); // maxAge cannot be 0
419
} catch (error) {
420
console.error(error.message);
421
}
422
```
423
424
## Advanced Usage Patterns
425
426
### Memory-Conscious Caching
427
428
```javascript
429
const cache = new QuickLRU({
430
maxSize: 1000,
431
maxAge: 300000, // 5 minutes
432
onEviction: (key, value) => {
433
// Cleanup resources
434
if (value && typeof value.cleanup === 'function') {
435
value.cleanup();
436
}
437
}
438
});
439
```
440
441
### Dynamic Cache Sizing
442
443
```javascript
444
// Monitor memory usage and adjust cache size
445
function adjustCacheSize(cache, memoryUsage) {
446
const targetSize = memoryUsage > 0.8 ? 50 : 200;
447
if (cache.maxSize !== targetSize) {
448
cache.resize(targetSize);
449
}
450
}
451
```
452
453
### Time-Based Expiration Patterns
454
455
```javascript
456
// Different TTLs for different data types
457
cache.set('user:profile', userData, { maxAge: 3600000 }); // 1 hour
458
cache.set('user:session', sessionData, { maxAge: 1800000 }); // 30 minutes
459
cache.set('static:config', configData); // Uses default maxAge
460
```