Blog Hoch
Jan 2026·1 tup leghDe'wI' chenmoHta'

LRU cache pagh vo' mach

#algorithms#javascript#performance

LRU (least-recently-used) cache items fixed number hold. full 'ej chu' item chel poQ vaj poH tIn touch pagh item evict. Hoch Daq tu'lu': browser tab management, database buffer pools, Python functools.lru_cache, in-memory API response caches. data structure yaj vaD Dun: naive version Dun, efficient version cha' structures combine.

naive version 'ej Dun pagh

obvious implementation { key, value } pairs array: access Hoch item tu', front Daq jaH, capacity law' vaj last item drop.

class NaiveLRU {
  constructor(capacity) {
    this.capacity = capacity;
    this.items = []; // most recently used at the front
  }

  get(key) {
    const index = this.items.findIndex((item) => item.key === key);
    if (index === -1) return undefined;
    const [item] = this.items.splice(index, 1);
    this.items.unshift(item);
    return item.value;
  }

  put(key, value) {
    const index = this.items.findIndex((item) => item.key === key);
    if (index !== -1) this.items.splice(index, 1);
    this.items.unshift({ key, value });
    if (this.items.length > this.capacity) this.items.pop();
  }
}

Qu' 'ach findIndex 'ej splice O(n). cache few hundred entries vaj Qagh pagh; LRU cache hot path Daq Qu' - O(n) cache n law' vaj purpose Qaw'.

O(1) version: hash map + doubly linked list

efficient implementation cha' structures combine:

  • hash map key node, O(1) lookup.
  • doubly linked list nodes order (most- least-recently-used), O(1) reorder 'ej eviction.

map node instant access; linked list node front Daq jaH pagh tail drop (pIm shift pagh). wa' structure neH cha' properties nob pagh: array ordering nob 'ach O(1) key lookup pagh; map lookup nob 'ach ordering pagh.

class Node {
  constructor(key, value) {
    this.key = key;
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.map = new Map(); // key -> Node

    // Sentinel head/tail nodes remove the need for null-checks at the edges.
    this.head = new Node(null, null);
    this.tail = new Node(null, null);
    this.head.next = this.tail;
    this.tail.prev = this.head;
  }

  #remove(node) {
    node.prev.next = node.next;
    node.next.prev = node.prev;
  }

  #addToFront(node) {
    node.next = this.head.next;
    node.prev = this.head;
    this.head.next.prev = node;
    this.head.next = node;
  }

  get(key) {
    const node = this.map.get(key);
    if (!node) return undefined;
    this.#remove(node);
    this.#addToFront(node);
    return node.value;
  }

  put(key, value) {
    const existing = this.map.get(key);
    if (existing) {
      existing.value = value;
      this.#remove(existing);
      this.#addToFront(existing);
      return;
    }

    if (this.map.size >= this.capacity) {
      const lru = this.tail.prev;
      this.#remove(lru);
      this.map.delete(lru.key);
    }

    const node = new Node(key, value);
    this.map.set(key, node);
    this.#addToFront(node);
  }
}

operation Hoch - get, put, eviction - O(1). sentinel head 'ej tail nodes trick: pagh vaj empty list chel pagh last node remove special-case null checks poQ. rap head.next reH "most recent real node pagh tail" - list code Daq empty pagh.

try

const cache = new LRUCache(3);

cache.put('a', 1);
cache.put('b', 2);
cache.put('c', 3);
cache.get('a');       // touches 'a' — order is now b, c, a
cache.put('d', 4);    // capacity exceeded — evicts 'b', the actual least-recently-used

cache.get('b'); // undefined — evicted
cache.get('a'); // 1 — still present
cache.get('d'); // 4 — still present

JavaScript shortcut

hand-roll poQ pagh vaj JavaScript Map insertion order preserve 'ej key re-insert (end Daq jaH) - LRU code Dach:

class SimpleLRU {
  constructor(capacity) {
    this.capacity = capacity;
    this.map = new Map();
  }

  get(key) {
    if (!this.map.has(key)) return undefined;
    const value = this.map.get(key);
    this.map.delete(key);
    this.map.set(key, value); // re-insert = move to the "most recent" end
    return value;
  }

  put(key, value) {
    if (this.map.has(key)) this.map.delete(key);
    else if (this.map.size >= this.capacity) {
      this.map.delete(this.map.keys().next().value); // oldest key
    }
    this.map.set(key, value);
  }
}

O(1) per operation: Map delete-and-reinsert O(1), .keys().next() oldest key O(1) (scan pagh - insertion order first entry nob). real-world use Hoch vaD 'oH version ship; linked-list version wa'logh hand build Dun (Map nuq Qu' yaj).

yaj

naive array-based LRU Dun - cache hot path Daq meaningful size vaj O(n) lookup reorder cost profiles Daq tu'. hash-map-plus-linked-list standard fix, broader pattern: structure wa' fast lookup, pIm fast ordering, cha' poQ vaj wa' choose pagh - combine 'ej synchronize.

chu'TypeScript Generics yajqanREST API Idempotency Keys