@@ -145,20 +145,40 @@ export function filterCell(
145145}
146146
147147/**
148- * A Least Recently Used (LRU) cache implemented using a Map.
148+ * A Least Recently Used (LRU) cache implemented by extending the built-in Map.
149149 *
150- * This class extends the built-in Map to provide an LRU cache with a fixed capacity.
151- * When the cache is full, the least recently used entry is automatically evicted.
150+ * This class preserves all Map behaviors while adding LRU eviction semantics:
151+ * - When an entry is accessed via get() it becomes the most recently used.
152+ * - When an entry is inserted via set() it becomes the most recently used.
153+ * - If insertion causes the cache to exceed its capacity, the least recently used
154+ * entry is evicted automatically.
152155 *
153- * @template K The type of the keys in the cache.
154- * @template V The type of the values in the cache.
156+ * Implementation notes:
157+ * - The Map (super) stores key-value pairs and provides O(1) get/set/delete semantics.
158+ * - A Set named `lru` maintains usage order: the iteration order of the Set goes from
159+ * least-recently-used (first) to most-recently-used (last). We update that Set on
160+ * accesses and insertions to keep order correct.
161+ *
162+ * @template K Type of keys in the cache.
163+ * @template V Type of values in the cache.
155164 */
156165export class MapLru < K , V > extends Map < K , V > {
157166 /**
158- * Constructs a new MapLru instance.
167+ * Internal ordered set used to track key usage.
168+ *
169+ * The Set preserves insertion order; keys are re-inserted on access so that the
170+ * first element in the Set is always the least recently used key.
171+ */
172+ private readonly lru : Set < K > = new Set ( ) ;
173+
174+ /**
175+ * Create a new MapLru with a fixed capacity.
176+ *
177+ * The capacity is the maximum number of entries the cache will hold. When the cache
178+ * grows beyond this capacity the least recently used entry is removed.
159179 *
160- * @param capacity The maximum number of entries the cache can hold. Must be a positive integer .
161- * @throws {Error } If the capacity is not a positive integer.
180+ * @param capacity Maximum number of entries allowed in the cache .
181+ * @throws {Error } If capacity is not a positive integer.
162182 */
163183 constructor ( private readonly capacity : number ) {
164184 super ( ) ;
@@ -168,50 +188,87 @@ export class MapLru<K, V> extends Map<K, V> {
168188 }
169189
170190 /**
171- * Retrieves a value from the cache.
191+ * Retrieve a value from the cache and mark the key as most-recently-used .
172192 *
173- * If the key is present in the cache, the value is moved to the most-recently-used position.
193+ * Behavior details:
194+ * - If the key is present, it is moved to the most-recently-used position in the
195+ * internal LRU tracking Set and its associated value is returned.
196+ * - If the key is not present, undefined is returned and the LRU order is unchanged.
174197 *
175- * @param key The key of the value to retrieve .
176- * @returns The value associated with the key, or undefined if the key is not present.
198+ * @param key Key whose associated value is to be returned .
199+ * @returns The value associated with the specified key, or ** undefined** if not present.
177200 */
178201 override get ( key : K ) : V | undefined {
179- // Check if the key exists. If not, return undefined.
202+ // If the Map does not contain the key , return undefined without changing LRU order .
180203 if ( ! super . has ( key ) ) {
181204 return undefined ;
182205 }
183206
184- const value = super . get ( key ) as V ;
207+ // Move to most-recently-used position by deleting then re-adding the key.
208+ this . lru . delete ( key ) ;
209+ this . lru . add ( key ) ;
185210
186- // Move to most-recently-used position
187- super . delete ( key ) ;
188- super . set ( key , value ) ;
189-
190- return value ;
211+ // super.get is safe to cast because we just confirmed the key exists.
212+ return super . get ( key ) as V ;
191213 }
192214
193215 /**
194- * Inserts a new value into the cache, or updates an existing value .
216+ * Insert or update a key/ value pair and mark the key as most-recently-used .
195217 *
196- * If the key is already present in the cache, it is first deleted so that the re-insertion
197- * moves it to the most-recently-used position.
198- * If the cache is over capacity after the insertion, the least recently used entry is evicted.
218+ * Behavior details:
219+ * - If the key already exists, it's updated and moved to the most-recently-used position.
220+ * - If insertion causes the cache size to exceed capacity, the least-recently-used key
221+ * (the first key in the LRU Set) is evicted from both the Map and the LRU Set.
199222 *
200- * @param key The key of the value to insert or update.
201- * @param value The value to associate with the key.
202- * @returns This MapLru instance.
223+ * @param key Key to insert or update.
224+ * @param value Value to associate with the key.
225+ * @returns This MapLru instance (allows chaining) .
203226 */
204227 override set ( key : K , value : V ) : this {
205- // Delete and re-insert to move key to the end (most-recently-used)
206- super . delete ( key ) ;
228+ // Store/update the value in the underlying Map.
207229 super . set ( key , value ) ;
208230
209- // Evict oldest if over capacity
231+ // Ensure key is at the most-recently-used position.
232+ this . lru . delete ( key ) ;
233+ this . lru . add ( key ) ;
234+
235+ // If over capacity, evict the least-recently-used key (first key in Set iteration).
210236 if ( super . size > this . capacity ) {
211- const oldestKey = super . keys ( ) . next ( ) . value ! ;
237+ // .next().value is guaranteed to exist here because size > capacity >= 1
238+ const oldestKey = this . lru . keys ( ) . next ( ) . value ! ;
212239 super . delete ( oldestKey ) ;
240+ this . lru . delete ( oldestKey ) ;
213241 }
214242
215243 return this ;
216244 }
245+
246+ /**
247+ * Remove a key and its associated value from the cache.
248+ *
249+ * This removes the key from both the underlying Map and the LRU tracking Set.
250+ *
251+ * @param key Key to remove.
252+ * @returns **true** if the key was present and removed; **false** if the key was not present.
253+ */
254+ override delete ( key : K ) : boolean {
255+ // Attempt to delete from the underlying Map first; if it didn't exist, no changes are needed.
256+ if ( ! super . delete ( key ) ) {
257+ return false ;
258+ }
259+ // Ensure LRU tracking no longer references the deleted key.
260+ this . lru . delete ( key ) ;
261+ return true ;
262+ }
263+
264+ /**
265+ * Remove all entries from the cache.
266+ *
267+ * This clears both the underlying Map storage and the internal LRU tracking Set,
268+ * ensuring no stale keys remain in the LRU structure after the cache is emptied.
269+ */
270+ override clear ( ) : void {
271+ super . clear ( ) ;
272+ this . lru . clear ( ) ;
273+ }
217274}
0 commit comments