← Tilbage til strukturer

Bloom Filter

Probabilistisk

En pladseffektiv probabilistisk datastruktur til at teste om et element er medlem af en mængde.

Kompleksitet

OperationTidskompleksitet
AccessN/A
SearchO(k)
InsertionO(k)
DeletionN/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

Relaterede strukturer

Counting Bloom FilterCuckoo FilterQuotient FilterHyperLogLog