* Get a value from the cache, constructing it via `constructor` on miss. * * On hit: moves the entry to most-recently-used position and returns it. * On miss: calls `constructor()` to create the value, inserts it, and * returns it. If the cache is full, the least-recently-used entry is
(key: K, constructor: () => V)
| 58 | * @returns The cached or newly constructed value. |
| 59 | */ |
| 60 | get(key: K, constructor: () => V): V { |
| 61 | const existing = this.cache.get(key); |
| 62 | if (existing !== undefined) { |
| 63 | // Move to most-recently-used position |
| 64 | this.cache.delete(key); |
| 65 | this.cache.set(key, existing); |
| 66 | return existing; |
| 67 | } |
| 68 | // Evict LRU entry if at capacity |
| 69 | if (this.cache.size >= this.maxSize) { |
| 70 | const oldest = this.cache.keys().next().value; |
| 71 | if (oldest !== undefined) { |
| 72 | if (this.onEvict) { |
| 73 | this.onEvict(oldest, this.cache.get(oldest)!); |
| 74 | } |
| 75 | this.cache.delete(oldest); |
| 76 | } |
| 77 | } |
| 78 | const value = constructor(); |
| 79 | this.cache.set(key, value); |
| 80 | return value; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Check whether eviction would be needed for a new entry. |