Q139FreeComputer Architecture
Make the least-recently-used cache O(1)
Interview prompt
Question
Redesign the LRU cache so successful get, put, recency updates, and eviction all take average O(1) time.

Candidate starting point
Implementation scaffold
// Implement here: Explain why the full predicate is captured before insertion.
class LRUNode;
int key;
LRUNode prev;
LRUNode next;
function new(int key);
this.key = key;
endfunction
endclass
class LRUCacheO1;
int capacity;
int value_by_key[int];
LRUNode node_by_key[int];
LRUNode head;
LRUNode tail;
function new(int capacity);
this.capacity = (capacity > 0) ? capacity : 0;
endfunction
function void unlink(LRUNode node);
// Implement here: detach this node while preserving head and tail.
endfunction
function void append_mru(LRUNode node);
// Implement here: append this detached node as MRU.
endfunction
function void touch(int key);
LRUNode node;
// Implement here: move this existing key to MRU.
endfunction
function bit get(int key, output int value);
// Implement here: report a hit and return its value while updating recency.
endfunction
function void put(int key, int value);
LRUNode node;
int evict_key;
bit full_before_insert;
// Implement here: insert or update and enforce capacity.
endfunction
endclassReviewed example
Trace one case
Input
capacity=2; put(1,10), put(2,20), get(1), put(3,30)Expected output
key 2 is evicted; node-map entries are {1,3}; LRU-to-MRU list is [1,3]Direct node lookup and constant-time unlink/append preserve the same LRU behavior without a scan.
What to cover
Requirements
- Preserve the lookup, update, insertion, and eviction behavior of the simple LRU cache.
- Map each key directly to its recency node.
- Unlink and append a node without scanning the cache.
- Evict the head/LRU key from the value map, node map, and linked list together.
