← Hub Principal |
⏱️

06: High-Performance LRU Cache (O(1) Eviction)

Rust 2021 (Memory Architecture)
Arquitetura de Caches & Sistemas Operacionais Módulo 06

Cache LRU (Least Recently Used) em O(1)

Uma das estruturas mais fundamentais em bancos de dados (como Redis, PostgreSQL shared buffers) e kernels de sistemas operacionais (Linux Page Cache). Combina duas estruturas ortogonais para atingir leitura, escrita, promoção de prioridade e descarte de dados com complexidade rigorosamente constante.


01. O Dilema de Engenharia: Por que duas estruturas?

Nenhuma estrutura de dados isolada consegue resolver o problema do LRU Cache em $O(1)$:

Tabela Hash Isolada

Oferece busca em O(1), mas não possui nenhuma noção de ordem temporal. Descobrir qual elemento é o mais antigo exigiria escanear toda a tabela em O(N).

Lista Ligada / Array Isolado

Mantém a ordem temporal com facilidade (O(1) na cabeça e na cauda), mas buscar um item aleatório pelo nome da chave requer varredura linear em O(N).

A Solução Híbrida:

O HashMap<K, NonNull<Node<K, V>>> mapeia chaves diretamente para os ponteiros da Lista Duplamente Ligada. Ao fazer get() ou put(), encontramos o nó em $O(1)$ via Hash e o desanexamos e reconectamos no topo da lista em $O(1)$ manipulando os ponteiros prev e next.

02. Análise Comparativa de Políticas de Descarte

Política Critério de Descarte Custo Temporal Vulnerabilidade
LRU (Este Módulo) Menos recentemente acessado O(1) Scans em lote limpam o cache (*cache pollution*)
LFU (Least Frequently) Menor frequência de acessos O(1) com 2 listas Itens históricos antigos monopolizam a memória
FIFO (First-In First-Out) Mais antigo por tempo de criação O(1) Descarta chaves críticas que continuam em uso ativo

03. Gerenciamento de Memória & Safe Encapsulation

Como o HashMap e a lista duplamente ligada apontam para as mesmas instâncias no Heap, o compilador de Rust proibiria o empréstimo duplo caso usássemos referências normais (&mut Node).

Ponteiros Não-Nulos (NonNull) & Drop Seguro:

Utilizamos NonNull<Node<K, V>>. Todos os blocos unsafe ficam estritamente confinados aos métodos internos de mutação de ponteiro (detach, attach_to_head). A API pública expõe uma interface segura e idiomática.

Na destruição do cache, a implementação manual da trait Drop percorre a lista reconvertendo cada ponteiro cru em Box<Node<K, V>>, assegurando que 100% da memória seja devolvida ao sistema operacional sem vazamentos.

cargo run --bin lru_cache
Ambiente pronto. Clique em "Compilar & Executar" para rodar o LRU Cache e observar a eviction policy em tempo real.