AI solution for JavaScript Coding Question on BFE.dev
169. LRU - Chrome storage automatic eviction
Here's one possible implementation of the LRUStorage
class:
interface OriginData { origin: string lastUsed: number size: number persistent: boolean}class LRUStorage { private originMap: Map<string, OriginData> private timestampFn: () => number constructor(public capacity: number, getTimestamp: () => number) { this.originMap = new Map() this.timestampFn = getTimestamp } private evict(): void { let lruOrigin: string | undefined = undefined let oldestTimestamp = this.timestampFn() for (const [origin, data] of this.originMap) { if (!data.persistent && data.lastUsed < oldestTimestamp) { lruOrigin = origin oldestTimestamp = data.lastUsed } } if (lruOrigin !== undefined) { this.originMap.delete(lruOrigin) } } getData(origin: string): OriginData | undefined { const data = this.originMap.get(origin) if (data !== undefined) { data.lastUsed = this.timestampFn() return data } else { return undefined } } setData(origin: string, size: number): boolean { if (this.capacity < size) { return false } while (this.originMap.size > 0 && this.getTotalSize() + size > this.capacity) { this.evict() } const data: OriginData = { origin, lastUsed: this.timestampFn(), size, persistent: false, } this.originMap.set(origin, data) return true } makePersistent(origin: string): void { const data = this.originMap.get(origin) if (data !== undefined) { data.persistent = true } } clearData(origin: string): void { this.originMap.delete(origin) } private getTotalSize(): number { let totalSize = 0 for (const data of this.originMap.values()) { totalSize += data.size } return totalSize }}
This implementation uses a Map
to store the origin data, with the origin string as the key and an OriginData
object as the value. The OriginData
interface has fields for the origin string, the timestamp of the last time the data was used (lastUsed
), the size of the data in bytes (size
), and a flag representing whether the data is "persistent" and can't be evicted (persistent
).
The constructor takes a capacity parameter and a function that returns the current timestamp as arguments. The evict
method finds and removes the least recently used non-persistent origin data in the map. The getData
method returns the OriginData
object for a given origin string and updates its lastUsed
timestamp. The setData
method adds or updates the OriginData
object for a given origin string and size, and also evicts non-persistent data until the total size is below the capacity. The makePersistent
method sets the persistent
flag for a given origin data object. The clearData
method removes the origin data object for a given origin string from the map. The getTotalSize
method calculates the total size of all the origin data in the map.