Live data from Hacker News

Bloom filters explained in a single image

exampl.io

41–50 of 50 posts

Re: Bloom filters explained in a single image

#41

I've just thought about how you could also have a "Bloom Map", basically as a HashSet is to Bloom Filter, a HashMap would be to a Bloom Map. It would be able to answer lookups with either "Definitely not present" or "Might map to value XYZ".

A use of the bloom filter is to determine whether you need to make an expensive call to storage to check for a match. You use a smaller fraction of memory to avoid 99 out of 100 disk accesses than you would to have a full index of the data.

Re: Bloom filters explained in a single image

#44
post #28

Bloom filters explained in a single HN comment: 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. N…

I think this is a great explanation for using a bloom filter and getting a feel for why you can get false positives but not false negatives.

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!

Re: Bloom filters explained in a single image

#45
post #28

Bloom filters explained in a single HN comment: 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. N…

I don't think that's quite right though. A bloom filter does not keep a list of hashes. If it did it'd grow with every item added to the set, and it doesn't. A bloom filter adds a new hash by bitwise-or-ing it with the currently stored value. Checking if a hash is present in the bloom filter is as simple as checking that all the 1 bits in the bash are 1 bits in the stored value in the bloom filter. This makes sure there are never any false negatives because bits only ever get turned on, never off. False positives are possible because of either direct hash collisions, or unrelated hashes turning on enough bits for a match.

Re: Bloom filters explained in a single image

#46
post #45
post #28

Bloom filters explained in a single HN comment: 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. N…

I don't think that's quite right though. A bloom filter does not keep a list of hashes. If it did it'd grow with every item added to the set, and it doesn't. A bloom filter adds a new hash by bitwise-or-ing it with the currently stored value. Checking if a hash is present in the bloom filter is as simple as checking that all the 1 bits in the bash are 1 bits in the stored value in the bloom filter. This makes sure th…

So it means with a dataset big enough, your bloom filter is virtualy all 1s, and will return true for every values you want to check regardless if it is actually in there ? Is there a threshold you can monitor to avoid this situation ?

Re: Bloom filters explained in a single image

#47
post #26

thanks for the post, it inspired this naive code: 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…

This looks fantastic! I also implemented one from scratch[0], and I was doing something very similar at first. Then I found the Python hash() function returns different outputs for the same input when you restart the interpreter. I really like your implementation, it's functional and easy to understand! [0] https://ricardoanderegg.com/posts/understanding-bloom-filter...

Nice!

> found the Python hash() function returns different outputs for the same input when you restart the interpreter

I wasn't aware of this >>

Re: Bloom filters explained in a single image

#48
post #46
post #45

Earlier quoted context omitted.

I don't think that's quite right though. A bloom filter does not keep a list of hashes. If it did it'd grow with every item added to the set, and it doesn't. A bloom filter adds a new hash by bitwise-or-ing it with the currently stored value. Checking if a hash is present in the bloom filter is as simple as checking that all the 1 bits in the bash are 1 bits in the stored value in the bloom filter. This makes sure th…

So it means with a dataset big enough, your bloom filter is virtualy all 1s, and will return true for every values you want to check regardless if it is actually in there ? Is there a threshold you can monitor to avoid this situation ?

Yes, if a dataset keeps growing, the whole bloom filter will eventually become 1s. If you know the (approximate) expected size of your dataset and the probabilities of false positives you can tolerate, you can calculate how big the filter should be and how many hashing functions you have to use.

I guess there are other techniques to dynamically grow the filter when you need it.

Re: Bloom filters explained in a single image

#49
post #45
post #28

Bloom filters explained in a single HN comment: 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. N…

I don't think that's quite right though. A bloom filter does not keep a list of hashes. If it did it'd grow with every item added to the set, and it doesn't. A bloom filter adds a new hash by bitwise-or-ing it with the currently stored value. Checking if a hash is present in the bloom filter is as simple as checking that all the 1 bits in the bash are 1 bits in the stored value in the bloom filter. This makes sure th…

It's indeed not a list of hashes but (as I said) a set of hashes. Usuaully the size of the set is static and determined when creating the bloom filter (how many bits in the bitmap). The hashes are not full blown hashes like a sha1 sum or similar but a bit (or a few) in the bitmap. You only add to the set and never remove. The bitwise or-ing with the stored value is the mentioned hash collision and just an implementation detail. It's still a set of hashes.

"unrelated hashes turning on enough bits for a match" is the case of hash collisions or I am misunderstanding that part.

Post reply on HN