-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathlruCache.js
More file actions
63 lines (54 loc) · 1.53 KB
/
lruCache.js
File metadata and controls
63 lines (54 loc) · 1.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Minimal LRU + TTL cache used when Redis is not configured
class LRUCache {
constructor({ max = 100, ttl = 6 * 3600 * 1000 } = {}) {
this.max = max;
this.ttl = ttl;
this.map = new Map(); // key -> { value, expires }
}
_now() { return Date.now(); }
_pruneExpired() {
const now = this._now();
for (const [k, v] of this.map.entries()) {
if (v.expires && v.expires < now) {
this.map.delete(k);
}
}
}
get(key) {
this._pruneExpired();
if (!this.map.has(key)) return undefined;
const entry = this.map.get(key);
if (entry.expires && entry.expires < this._now()) {
this.map.delete(key);
return undefined;
}
// Promote (LRU)
this.map.delete(key);
this.map.set(key, entry);
return entry.value;
}
set(key, value) {
this._pruneExpired();
if (this.map.has(key)) this.map.delete(key);
this.map.set(key, { value, expires: this.ttl ? this._now() + this.ttl : null });
// Evict LRU
if (this.map.size > this.max) {
const oldestKey = this.map.keys().next().value;
this.map.delete(oldestKey);
}
}
delete(key) {
this.map.delete(key);
}
has(key) {
return this.get(key) !== undefined;
}
keys() {
this._pruneExpired();
return Array.from(this.map.keys());
}
clear() {
this.map.clear();
}
}
module.exports = LRUCache;