* Copyright (c) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
* LRU Cache implementation using Map's insertion order
* for efficient least-recently-used eviction.
*/
export class LRUCache<K extends unknown, T extends Object> {
protected cache: Map<K, T>;
public maxSize: number;
constructor(maxSize: number = 100) {
if (maxSize <= 0) {
throw new Error('Cache size must be positive');
}
this.cache = new Map();
this.maxSize = maxSize;
}
* Get a value from the cache
* @param key Cache key
* @returns The cached value or undefined if not found
*/
public get(key: K): T | undefined {
const value = this.cache.get(key);
if (value !== undefined) {
this.cache.delete(key);
this.cache.set(key, value);
}
return value;
}
* Set a value in the cache
* @param key Cache key
* @param value Value to cache
*/
public set(key: K, value: T): void {
if (this.cache.has(key)) {
this.cache.delete(key);
} else if (this.cache.size >= this.maxSize) {
const firstKey = this.cache.keys().next().value;
if (firstKey !== undefined) {
this.cache.delete(firstKey);
}
}
this.cache.set(key, value);
}
* Check if a key exists in the cache
* @param key Cache key to check
* @returns True if the key exists
*/
public has(key: K): boolean {
return this.cache.has(key);
}
* Delete a key from the cache
* @param key Cache key to delete
* @returns True if the key was deleted
*/
public delete(key: K): boolean {
return this.cache.delete(key);
}
* Clear all items from the cache
*/
public clear(): void {
this.cache.clear();
}
* Get the current number of items in the cache
* @returns Number of cached items
*/
public size(): number {
return this.cache.size;
}
* Get all cache keys (in order of most recently used)
* @returns Array of keys
*/
public keys(): K[] {
return Array.from(this.cache.keys()).reverse();
}
* Get all cache values (in order of most recently used)
* @returns Array of values
*/
public values(): T[] {
return Array.from(this.cache.values()).reverse();
}
* Get all cache entries (in order of most recently used)
* @returns Array of [key, value] pairs
*/
public entries(): [K, T][] {
return Array.from(this.cache.entries()).reverse();
}
* Resize the cache (evicts LRU items if new size is smaller)
* @param newSize New maximum cache size
*/
public resize(newSize: number): void {
if (newSize <= 0) {
throw new Error('Cache size must be positive');
}
this.maxSize = newSize;
while (this.cache.size > this.maxSize) {
const firstKey = this.cache.keys().next().value!;
this.cache.delete(firstKey);
}
}
* Execute a function for each cache entry (from most to least recently used)
* @param callback Function to execute
*/
public forEach(callback: (value: T, key: K) => void): void {
this.entries().forEach(([key, value]) => callback(value, key));
}
}