Cache LRU in C

Ho bisogno di memorizzare nella cache un numero grande (ma variabile) di file piccoli (da 1 kilobyte a 10 megabyte) in memoria, per un’applicazione C (in un ambiente * nix). Dal momento che non voglio mangiare tutta la mia memoria, mi piacerebbe impostare il limite della memoria rigida (diciamo 64 megabyte) e spingere i file in una tabella hash con il nome del file come chiave e disporre delle voci con il minimo uso . Quello di cui credo sia necessario è una cache LRU.

Davvero, preferirei non fare il mio, quindi se qualcuno sa dove posso trovare una libreria funzionante, per favore indica la via? In caso contrario, qualcuno può fornire un semplice esempio di cache LRU in C? Post correlati hanno indicato che una tabella hash con una lista doppiamente collegata, ma non sono nemmeno chiaro su come una lista doppiamente legata mantiene LRU.

Nota a margine: mi rendo conto che questa è quasi esattamente la funzione di memcache, ma non è un’opzione per me. Ho anche dato un’occhiata alla fonte sperando di illuminarmi sul caching di LRU, senza successo.

Post correlati hanno indicato che una tabella hash con una lista doppiamente collegata, ma non sono nemmeno chiaro su come una lista doppiamente legata mantiene LRU.

Sto solo facendo una supposizione qui, ma potresti fare qualcosa del genere (usando pseudo-C qui perché sono pigro). Ecco le strutture dati di base:

struct File { // hash key string Name; // doubly-linked list File* Previous; File* Next; // other file data... } struct Cache { HashTable Table // some existing hashtable implementation File* First; // most recent File* Last; // least recent } 

Ed ecco come aprire e chiudere un file:

 File* Open(Cache* cache, string name) { if (look up name in cache->Table succeeds) { File* found = find it from the hash table lookup move it to the front of the list } else { File* newFile = open the file and create a new node for it insert it at the beginning of the list if (the cache is full now) { remove the last file from the list close it remove it from the hashtable too } } } 

L’hashtable ti permette di trovare rapidamente i nodes per nome, e l’elenco collegato ti consente di mantenerli in ordine d’uso. Dal momento che puntano agli stessi nodes, puoi passare da uno all’altro. Questo ti permette di cercare un file per nome, ma poi spostarlo nella lista in seguito.

Ma potrei essere totalmente in errore su tutto questo.

Se stai usando Linux, penso che il sistema operativo farà tutto il necessario, soprattutto se ti fadvise chiamata di sistema fadvise per far sapere al sistema quali file hai intenzione di usare in seguito.

koders.com individua alcuni; quello che è più facile da adattare e riutilizzare (se si sta bene con le sue condizioni di licenza) sembra essere questo dal progetto FreeType (ci vorrà del tempo per capire il suo, ehm, interessante lavoro del preprocessore). Nel peggiore dei casi, dovrebbe mostrare un approccio in base al quale è ansible implementare una cache LRU in C.

La maggior parte delle implementazioni di cache LRU riutilizzabili (e ce ne sono molte da trovare sulla rete), ovviamente, usano linguaggi handier (Java, C ++, C #, Python, …) che offrono strutture dati più forti e, in genere, gestione della memoria.

Sembra che tu possa build una cache LRU in C con uthash .

Quello che mi piace di più di uthash è che si tratta di un semplice file di intestazione, con un sacco di macro, quindi le dipendenze extra sono ridotte al minimo.

Non sono a conoscenza di eventuali librerie di ambiente generali UNIX in C, ma non dovrebbe essere difficile da implementare.

Per gli esempi di codice, suggerisco di dare un’occhiata a qualsiasi delle implementazioni di hash table gazillion (oi) là fuori. Indipendentemente dal fatto che la tabella utilizzi un elenco collegato o una struttura ad albero per l’elaborazione effettiva, non è insolito che venga utilizzata una qualche forma di memorizzazione nella cache (come MRU), quindi potrebbe darti un’idea di come potrebbe essere un’implementazione. Alcuni semplici Garbage Collector e vari bit di software che richiedono un algoritmo di sostituzione delle pagine possono anche essere degni di attenzione.

In pratica, contrassegni le cose quando sono accessibili e invecchiano i riferimenti. Se si aumenta l’età delle cose all’accesso anziché a tutti i peer dell’elemento a cui si accede, ovviamente si salva un ciclo agli accessi e si spinge il peso sull’operazione di scadenza. Avrai voglia di fare un po ‘di profilazione leggera per trovare un’idea generale di quanto meno recente è sufficientemente! Abbastanza recente per il tuo compito. Quando arrivi a quel punto, aggiorni la cache di conseguenza.