Bloom filters explained in a single image
exampl.io
exampl.io
They are an efficient implementation of a Set that contains hashes of the elements.
bloomfilter.add("foo") will internally add hash("foo") to the Set
bloomfilter.has("foo") checks if the Set contains hash("foo")
False positives arise due to different elements hashing to the same hash. If "foo" and "bar" hash to the same value, bloomfilter.has("bar") would return true.
No false negatives are possible.
They are used when an actual check for an element in a datastructure is quite costly and the hitrate for not-in-the-datastructure is non-trivial and can therefor be skipped if the bloomfilter gives a negative.
Also, your last sentence is a great summary of when they should be used. I included a few use cases, but I should have also included something like what you said.
I'll take that into account for future posts, thanks!
"unrelated hashes turning on enough bits for a match" is the case of hash collisions or I am misunderstanding that part.
I guess there are other techniques to dynamically grow the filter when you need it.
Super useful and succinct!
This explanation could apply to a few hash-set style implimentations but I think it misses what made the bloom filter so beautiful and elegant when I'd discovered it. It's a specific data structure with it's own memory/performance/tuning profiles!
fig 3 here
https://www.sciencedirect.com/science/article/pii/S138912861...
is a much better "single image" explanation (insofar as any single image could be sufficiently explanatory) of bloom filters.
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.428...
In my case, I found them a beautiful data structure that is simple to understand but very useful. I also draw the images for learning myself about a topic, maybe others find the format useful, so I have started sharing them.
But yes, I have definitely planned to draw/explain other data structures and computer science concepts. I did bloom filters now because I'm exploring concepts related to hashing and cryptography.
If you’re exploring cryptography, I highly recommend looking into Shamir’s secret sharing algorithm. It’s very elegant and doesn’t require much in the way of higher math to understand.
A beautiful Beautiful algorithm
Also, you don't seem to have them available in popular container or general-purpose libraries.
I did a brown bag where I work recently when I walked though how to implement one and was approached after by some of the smartest engineers I know saying thank you I think I finally get it.
I have created that site to summarize concepts I find interesting, while providing examples or use cases.
My biggest inspiration comes from Julia Evans and her zines[0]. I started drawing the things I was learning about, and I thought the format could be useful for other people.
Right now I'm diving into a mix of hashing functions/cryptography, data structures and databases. I usually spend a few days learning about a concept, and then I try to summarize it in a constrained drawing frame (I use Excalidraw[1] to do it and some logos from drwn.io[2]). I'm happy to accept suggestions about interesting topics to explore, draw and summarize.
[0] https://wizardzines.com/ [1] https://excalidraw.com/ [2] https://drwn.io/
class BloomFilter:
def __init__(self, size):
self.f = [0] * size
def contains(self, s):
h1, h2, h3 = self.hashes(s)
if self.f[h1] * self.f[h2] * self.f[h3] == 1:
return 'Value might be in the set.'
else:
return 'Value is definitely not in the set.'
def hashes(self, s):
h1 = hash(s) % len(self.f)
h2 = hash(s + 'salt') % len(self.f)
h3 = hash(s + 'more salt') % len(self.f)
return h1, h2, h3
def insert(self, s):
h1, h2, h3 = self.hashes(s)
self.f[h1] = self.f[h2] = self.f[h3] = 1
bf = BloomFilter(64)
bf.insert('bill')
print(f"{bf.contains('bill') = }")
print(f"{bf.contains('bob') = }")
Out:
bf.contains('bill') = 'Value might be in the set.'
bf.contains('bob') = 'Value is definitely not in the set.'[0] https://ricardoanderegg.com/posts/understanding-bloom-filter...
> found the Python hash() function returns different outputs for the same input when you restart the interpreter
I wasn't aware of this >>
This contains multiple paragraphs and figures. You couldn't screenshot a wikipedia page and claim the same!
You can watch it at 2.5x speed without missing out on anything:
https://academy.bit2me.com/wp-content/uploads/2020/06/como-f...
https://python.land/bloom-filter
There.
The main drawback is that, because the elements won't be completely evenly distributed among the small Bloom Filters, you need some additional space to compensate and keep the false positive rate low.
[1] https://www.cs.amherst.edu/~ccmcgeoch/cs34/papers/cacheeffic...
2) Have a leakier bloom that fits in your L1/L2 cache size. You may have to have 2 layers of bloom filters, and this will be highly dependent on the relative expenses of the various operations.