Qué es LRU y cómo implementar un mecanismo de caché LRU en JavaScript
- 668Palabras
- 3Minutos
- 08 Aug, 2024
Introducción
LRU es la abreviatura de Least Recently Used (menos recientemente usado), y es una estrategia de reemplazo de caché. Cuando la caché alcanza su límite de almacenamiento, LRU elimina la entrada menos recientemente usada. Esta estrategia se basa en la suposición de que los datos usados recientemente probablemente se volverán a usar en el futuro, mientras que los datos menos recientemente usados probablemente no se usarán nuevamente.
Implementación de una caché LRU en JavaScript
Para implementar una caché LRU en JavaScript, se puede utilizar Map
combinado con una lista doblemente enlazada
. Map
asegura el orden de inserción de los elementos, y la lista doblemente enlazada ayuda a mover eficientemente los elementos más recientemente usados al inicio y eliminar los elementos menos recientemente usados.
Implementación del código
A continuación se muestra una implementación simple de la caché LRU:
1// Definición de la clase del nodo de la lista doblemente enlazada2class Node {3 constructor(key, value) {4 this.key = key;5 this.value = value;6 this.prev = null;7 this.next = null;8 }9}10
11// Definición de la clase de la caché LRU12class LRUCache {13 constructor(capacity) {14 this.capacity = capacity; // Capacidad de la caché15 this.map = new Map(); // Almacenar datos de la caché16 this.head = new Node(null, null); // Nodo cabeza virtual17 this.tail = new Node(null, null); // Nodo cola virtual18 this.head.next = this.tail;19 this.tail.prev = this.head;20 }21
22 // Obtener el valor de la caché23 get(key) {24 if (!this.map.has(key)) {25 return -1; // Si la caché no tiene la clave, retorna -126 }27
28 const node = this.map.get(key);29 this._remove(node); // Eliminar el nodo de la lista doblemente enlazada30 this._add(node); // Agregar el nodo al final de la lista (indicando que fue recientemente usado)31
32 return node.value;33 }34
35 // Agregar o actualizar el valor de la caché36 put(key, value) {37 if (this.map.has(key)) {38 this._remove(this.map.get(key)); // Si la caché ya tiene la clave, eliminar el nodo antiguo39 }40
41 const newNode = new Node(key, value);42 this._add(newNode); // Agregar el nuevo nodo al final de la lista43 this.map.set(key, newNode);44
45 if (this.map.size > this.capacity) {46 const lruNode = this.head.next; // Obtener el nodo menos recientemente usado47 this._remove(lruNode); // Eliminar el nodo menos recientemente usado de la lista48 this.map.delete(lruNode.key); // Eliminar la clave menos recientemente usada de la caché49 }50 }51
52 // Eliminar el nodo de la lista doblemente enlazada53 _remove(node) {54 node.prev.next = node.next;55 node.next.prev = node.prev;56 }57
58 // Agregar el nodo al final de la lista doblemente enlazada59 _add(node) {60 node.prev = this.tail.prev;61 node.next = this.tail;62 this.tail.prev.next = node;63 this.tail.prev = node;64 }65}
Ejemplo de uso
1const lru = new LRUCache(2);2
3lru.put(1, 1);4lru.put(2, 2);5console.log(lru.get(1)); // Imprime 16lru.put(3, 3); // Elimina la clave 27console.log(lru.get(2)); // Imprime -1 (no encontrado)8lru.put(4, 4); // Elimina la clave 19console.log(lru.get(1)); // Imprime -1 (no encontrado)10console.log(lru.get(3)); // Imprime 311console.log(lru.get(4)); // Imprime 4
Explicación del código
- Clase Node: utilizada para los nodos de la lista doblemente enlazada, contiene
key
,value
y los punterosprev
ynext
. - Clase LRUCache: la clase principal que gestiona la caché, se inicializa con una capacidad
capacity
y crea unMap
y dos nodos centinelahead
ytail
. - Método get: obtiene el valor de la caché, si existe, mueve el nodo al final (indicando que fue recientemente usado).
- Método put: inserta un nuevo valor en la caché, si la clave ya existe, elimina el nodo antiguo. Después de insertar el nuevo nodo, verifica si se supera la capacidad, si es así, elimina el nodo al principio de la lista (indicando que es el menos recientemente usado).
- Método _remove: elimina el nodo de la lista doblemente enlazada.
- Método _add: agrega el nodo al final de la lista doblemente enlazada.
Esta implementación asegura que las operaciones get
y put
se puedan completar en tiempo de complejidad constante ( O(1) ).
Conclusión
Con el código y los comentarios anteriores, entendemos cómo implementar una caché LRU simple en JavaScript. La caché LRU es una estrategia de reemplazo de caché comúnmente utilizada y se aplica ampliamente en varios sistemas de caché. Espero que este artículo te ayude a comprender mejor el principio y la aplicación de la caché LRU.