Bloom filter dan count-min sketch adalah struktur data probabilistik yang mengorbankan akurasi sempurna untuk efisiensi memori. Di episode ini kalian memahami bloom filter dengan O(1) insert/lookup dan false positive rate, count-min sketch untuk frequency estimation, serta mempraktikkan implementasi bloom filter dari nol.

Setelah di episode 20 kita memahami Union-Find — struktur data untuk merge dan query set — pada episode ini kita mempelajari struktur data probabilistik: Bloom filter dan count-min sketch. Keduanya mengorbankan akurasi sempurna untuk efisiensi memori yang luar biasa — trade-off yang sangat berharga dalam skala besar.
Bloom filter memberikan O(1) insert dan lookup dengan kemungkinan false positive tetapi tidak ada false negative. Artinya, bloom filter bisa salah mengatakan "mungkin ada" tetapi tidak pernah salah mengatakan "pasti tidak ada". Ini menjadikannya ideal untuk cache, anti-spam, dan deduplication.
Bloom filter adalah bit array dari m bits, digunakan bersama k hash functions. Insert dan lookup melibatkan hashing key dengan semua k hash functions dan mengecek/setting bit di posisi hasil hash.
False positive rate bergantung pada:
import mmh3
from bitarray import bitarray
class BloomFilter:
def __init__(self, size, num_hashes):
self.size = size
self.num_hashes = num_hashes
self.bit_array = bitarray(size)
self.bit_array.setall(0)
def add(self, item):
for i in range(self.num_hashes):
index = mmh3.hash(item, i) % self.size
self.bit_array[index] = 1
def contains(self, item):
for i in range(self.num_hashes):
index = mmh3.hash(item, i) % self.size
if self.bit_array[index] == 0:
return False
return Truebf = BloomFilter(1000, 7)
for i in range(500):
bf.add(f"item_{i}")
false_positives = 0
test_items = 1000
for i in range(500, 500 + test_items):
if bf.contains(f"item_{i}"):
false_positives += 1
print(f"False positive rate: {false_positives / test_items:.2%}")Count-min sketch adalah struktur data untuk estimasi frequency dengan bounded memory. Mirip bloom filter tetapi menggunakan counter (bukan bit) dan beberapa hash functions.
import mmh3
class CountMinSketch:
def __init__(self, width, depth):
self.width = width
self.depth = depth
self.table = [[0] * width for _ in range(depth)]
def add(self, item, count=1):
for i in range(self.depth):
index = mmh3.hash(str(item), i) % self.width
self.table[i][index] += count
def estimate(self, item):
return min(
self.table[i][mmh3.hash(str(item), i) % self.width]
for i in range(self.depth)
)| Aspek | Bloom Filter | Hash Set |
|---|---|---|
| Memory | Sangat efisien | Boros |
| False positive | Ya | Tidak |
| Delete | Tidak bisa | Bisa |
| Exact count | Tidak | Bisa |
| Use case | Pre-filter | Penyimpanan pasti |
Note
Bloom filter tidak mendukung delete karena menghapus elemen bisa mempengaruhi elemen lain. Untuk delete, gunakan counting bloom filter yang menggunakan counter (bukan bit) — tetapi ini membutuhkan lebih banyak memori.
Inti yang harus dibawa pulang:
Di episode 22 selanjutnya kita akan membahas LRU cache dan LFU cache — dua strategi eviction yang paling umum digunakan dalam caching systems. LRU menggunakan doubly-linked list + hash map untuk O(1) get/put dengan evicts least recently used. Ini adalah kombinasi dari beberapa struktur data yang sudah kita pelajari!