Bloom Filter
ProbabilistiskEn pladseffektiv probabilistisk datastruktur til at teste om et element er medlem af en mængde.
Kompleksitet
| Operation | Tidskompleksitet |
|---|---|
| Access | N/A |
| Search | O(k) |
| Insertion | O(k) |
| Deletion | N/A |
Beskrivelse
Et Bloom Filter er en fascinerende probabilistisk datastruktur der tillader hurtige medlemskabstests med minimal hukommelse. Den bruger flere hash-funktioner til at sætte bits i et bit-array når elementer tilføjes. Ved opslag hasher man elementet med samme funktioner og tjekker om alle tilsvarende bits er sat. Bloom filters har en interessant egenskab: falske positiver er mulige (siger elementet findes når det ikke gør), men falske negativer er umulige (hvis den siger nej, er elementet garanteret ikke der). Dette kompromis gør dem perfekte til scenarier hvor hukommelse er begrænset og lejlighedsvise falske positiver er acceptable. Bloom filters bruges i databaser til at undgå dyre diskopslag, i netværk til at reducere trafik, og i caching-systemer. De kan ikke slette elementer (brug Counting Bloom Filter til det) men er ekstremt pladseffektive sammenlignet med hash-tabeller.
Kode Eksempel
// JavaScript Bloom Filter implementation
class BloomFilter {
constructor(size = 100, hashCount = 3) {
this.size = size;
this.hashCount = hashCount;
this.bitArray = new Array(size).fill(0);
}
// Hash funktion
_hash(value, seed) {
let hash = 0;
const str = value.toString();
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) + hash) + str.charCodeAt(i) + seed;
hash = hash & hash; // Konverter til 32-bit heltal
}
return Math.abs(hash) % this.size;
}
// Tilføj element
add(value) {
for (let i = 0; i < this.hashCount; i++) {
const index = this._hash(value, i);
this.bitArray[index] = 1;
}
}
// Tjek om element muligvis findes
mightContain(value) {
for (let i = 0; i < this.hashCount; i++) {
const index = this._hash(value, i);
if (this.bitArray[index] === 0) {
return false; // Bestemt ikke til stede
}
}
return true; // Kan være til stede (mulig falsk positiv)
}
// Beregn falsk positiv-rate
getFalsePositiveRate() {
const bitsSet = this.bitArray.filter(bit => bit === 1).length;
const m = this.size;
const k = this.hashCount;
const n = bitsSet;
return Math.pow(1 - Math.exp(-k * n / m), k);
}
}
// Eksempel på anvendelse
const filter = new BloomFilter(1000, 3);
filter.add('bruger123@email.dk');
filter.add('bruger456@email.dk');
console.log(filter.mightContain('bruger123@email.dk')); // true
console.log(filter.mightContain('bruger999@email.dk')); // false (eller true - falsk positiv)Anvendelsesområder
- •Databaseoptimering (undgå diskopslag)
- •Webcrawler duplikat-URL-detektion
- •Spam-email-filtrering
- •Bitcoin wallet-adressetjek
- •CDN cache-kontrol
Fordele
- ✓Ekstremt pladseffektiv (bits vs fuld data)
- ✓Konstant tidsoperationer O(k)
- ✓Ingen falske negativer
- ✓Hurtigere end disk/netværksopslag
- ✓Skalerbar til milliarder af elementer
Ulemper
- ✗Falske positiver er mulige
- ✗Kan ikke slette elementer (standardversion)
- ✗Kan ikke liste indhold
- ✗Præcision degraderer med flere elementer
- ✗Kræver tuning af parametre
Eksempler fra den virkelige verden
- •Google Chrome sikker browsing (malware-URL'er)
- •Medium.com sporing af læste artikler
- •Akamai CDN cache-eksistenstjek
- •Cassandra database SSTable-filtrering
- •Bitcoin letvægtsklienter