- Introduced blog routing using Next.js App Router - Implemented dynamic [slug] pages for blog posts - Added MDX-based content loading via lib/posts - Integrated shared TopBar layout with navigation - Established clear content, lib and component separation
96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
/**
|
|
* LRU (Least Recently Used) Cache implementation using a doubly-linked list
|
|
* and hash map for O(1) operations.
|
|
*
|
|
* Algorithm:
|
|
* - Uses a doubly-linked list to maintain access order (most recent at head)
|
|
* - Hash map provides O(1) key-to-node lookup
|
|
* - Sentinel head/tail nodes simplify edge case handling
|
|
* - Size-based eviction supports custom size calculation functions
|
|
*
|
|
* Data Structure Layout:
|
|
* HEAD <-> [most recent] <-> ... <-> [least recent] <-> TAIL
|
|
*
|
|
* Operations:
|
|
* - get(): Move accessed node to head (mark as most recent)
|
|
* - set(): Add new node at head, evict from tail if over capacity
|
|
* - Eviction: Remove least recent node (tail.prev) when size exceeds limit
|
|
*/
|
|
export declare class LRUCache<T> {
|
|
private readonly cache;
|
|
private readonly head;
|
|
private readonly tail;
|
|
private totalSize;
|
|
private readonly maxSize;
|
|
private readonly calculateSize;
|
|
constructor(maxSize: number, calculateSize?: (value: T) => number);
|
|
/**
|
|
* Adds a node immediately after the head (marks as most recently used).
|
|
* Used when inserting new items or when an item is accessed.
|
|
* PRECONDITION: node must be disconnected (prev/next should be null)
|
|
*/
|
|
private addToHead;
|
|
/**
|
|
* Removes a node from its current position in the doubly-linked list.
|
|
* Updates the prev/next pointers of adjacent nodes to maintain list integrity.
|
|
* PRECONDITION: node must be connected (prev/next are non-null)
|
|
*/
|
|
private removeNode;
|
|
/**
|
|
* Moves an existing node to the head position (marks as most recently used).
|
|
* This is the core LRU operation - accessed items become most recent.
|
|
*/
|
|
private moveToHead;
|
|
/**
|
|
* Removes and returns the least recently used node (the one before tail).
|
|
* This is called during eviction when the cache exceeds capacity.
|
|
* PRECONDITION: cache is not empty (ensured by caller)
|
|
*/
|
|
private removeTail;
|
|
/**
|
|
* Sets a key-value pair in the cache.
|
|
* If the key exists, updates the value and moves to head.
|
|
* If new, adds at head and evicts from tail if necessary.
|
|
*
|
|
* Time Complexity:
|
|
* - O(1) for uniform item sizes
|
|
* - O(k) where k is the number of items evicted (can be O(N) for variable sizes)
|
|
*/
|
|
set(key: string, value: T): void;
|
|
/**
|
|
* Checks if a key exists in the cache.
|
|
* This is a pure query operation - does NOT update LRU order.
|
|
*
|
|
* Time Complexity: O(1)
|
|
*/
|
|
has(key: string): boolean;
|
|
/**
|
|
* Retrieves a value by key and marks it as most recently used.
|
|
* Moving to head maintains the LRU property for future evictions.
|
|
*
|
|
* Time Complexity: O(1)
|
|
*/
|
|
get(key: string): T | undefined;
|
|
/**
|
|
* Returns an iterator over the cache entries. The order is outputted in the
|
|
* order of most recently used to least recently used.
|
|
*/
|
|
[Symbol.iterator](): IterableIterator<[string, T]>;
|
|
/**
|
|
* Removes a specific key from the cache.
|
|
* Updates both the hash map and doubly-linked list.
|
|
*
|
|
* Time Complexity: O(1)
|
|
*/
|
|
remove(key: string): void;
|
|
/**
|
|
* Returns the number of items in the cache.
|
|
*/
|
|
get size(): number;
|
|
/**
|
|
* Returns the current total size of all cached items.
|
|
* This uses the custom size calculation if provided.
|
|
*/
|
|
get currentSize(): number;
|
|
}
|