In 1970, Burton H. Bloom described a data structure that could answer "have I seen this before?" using a handful of bits instead of storing the item itself. The idea is elegant: hash each element with independent hash functions and set the corresponding bits in a bit array of size . To query, check all bits — if any is zero, the element is definitely absent; if all are one, it is probably present. The false-positive rate is approximately , where is the number of elements inserted.
The catch is permanent: the classic Bloom filter cannot delete elements. Setting a bit for one element may share a bit with another, so clearing it would corrupt the filter for those other elements. For decades this was an accepted limitation — until engineers ran into systems where items expire, users unsubscribe, or cached entries are evicted.
Three main variants have emerged to fill that gap, each making a different bet on the space-speed-accuracy trade-off:
- Counting filter (Fan et al., 1998): replace each bit with a small counter. Insertions increment; deletions decrement. Simple, but counters consume 3–4× more space.
- Cuckoo filter (Fan et al., 2014): store compact fingerprints in a hash table that uses cuckoo hashing to displace items. Supports deletion natively and often outperforms Bloom filters at false-positive rates below 3%.
- Blocked Bloom filter (Putze et al., 2007): partition the bit array into fixed-size blocks that each fit in a single cache line. No deletion, but much faster in practice because every lookup touches exactly one cache line.
Each variant is a solved engineering problem with known closed-form bounds — the real question is which trade-off fits your workload. See also probabilistic data structures for the classic filter's foundation.
Comments
Loading comments...