Assumendo indirizzi IPv4, vi è uno spazio di ricerca di 2 . Non è necessario più di 1 bit per indirizzo IP (0 == nessuna visita, 1 == visita). Senza considerare l'overhead di archiviazione, occorrerebbero 512 MB (2) da archiviare. Quindi un'implementazione semplicistica alloca un array da 512 MB (o una tabella con 2 righe, ognuna contenente un byte o 2 righe, ciascuna contenente un numero intero a 32 bit o 2 righe , ciascuna memorizza un numero intero a 64 bit, o ...)
È possibile ottimizzare questo per popolazione sparsa trasformandolo in un albero.
Definire una dimensione di "pagina" di 2 x bit. Assegnerai lo spazio di archiviazione per una pagina alla volta.
Dividere lo spazio di ricerca (2) in base alle dimensioni della pagina. Questo è il numero totale di pagine richieste per rappresentare ogni possibile indirizzo nel tuo spazio di ricerca.
Quindi, per determinare se c'è un hit nel tuo hash, dovrai prima determinare se la pagina è presente, e in tal caso, se è impostato il bit appropriato nella pagina. Per memorizzare un indirizzo nella cache, determinerai prima se la pagina è presente; se non lo creerai. Quindi imposterai il bit appropriato.
Questo stampo è abbastanza semplice per una tabella di database. Avresti bisogno solo di due colonne: un indice di pagina e un array binario. Quando si assegna una pagina, si memorizzerà semplicemente una riga nella tabella con l'indice di pagina corretto e una matrice binaria vuota.
Per esempio, per una dimensione di pagina 1024 bit (cedevole 2 pagine al massimo), si potrebbe strutturare la vostra tabella come questa:
CREATE TABLE VisitedIPs(
PageIndex int NOT NULL PRIMARY KEY,
PageData binary(128) NOT NULL
)
per verificare se un IP ha visitato, si usa codice simile (pseudocodice):
uint ip = address.To32Bit();
string sql =
"SELECT PageData " +
"FROM VisitedIPs " +
"WHERE PageIndex = " + (ip >> 10);
byte[] page = (byte[])GetFromDB(sql);
byte b = page[(ip & 0x3FF) >> 3];
bool hasVisited = (b & (1 << (ip & 7)) != 0;
Impostazione che un IP ha visitato è simile:
uint ip = address.To32Bit();
string sql =
"SELECT PageData " +
"FROM VisitedIPs " +
"WHERE PageIndex = " + (ip >> 10);
byte[] page = (byte[])GetFromDB(sql);
page[(ip & 0x3FF) >> 3] |= (1 << (ip & 7));
sql =
"UPDATE VisitedIPs " +
"SET PageData = @pageData " +
"WHERE PageIndex = " + (ip >> 10);
ExecSQL(sql, new SqlParam("@pageData", page));
Informazioni interessanti, non sapevo esistesse una cosa del genere. –
Sì, questa è quasi esattamente l'applicazione per cui sono stati progettati i filtri Bloom. Si noti inoltre che gli errori sono solo a senso unico (solo falsi positivi occasionali, mai falsi negativi). – ShreevatsaR
È bello averlo visto - non ne avevo mai sentito parlare, ma penso che l'uso di un array di bit potrebbe essere migliore in questo caso (suggerito da un'altra risposta). –