Is this a Bloom filter?
A Bloom filter is, IMO, a data structure that uses a bit array smaller than the domain of values that it's storing the presence of, and uses several hashes to optimize the false positive rate.
What we have here, is (mostly) a bit array. You could argue that it is a Bloom filter with extreme parameters: only one hash, but (almost) the maximum number of entries. But I don't really see that as Bloom filter, it doesn't have the space vs false-positives trade off that Bloom filters have.
A Bloom filter with approximately 232 entries (very extreme, but that's what we have here so let's compare it to that) could have a lower false-positive rate, for example if we expect to insert a billion elements then the number of hash functions should be 3 and the probability of a false-positive would be approximately 12.7%, while with 1 hash function (which is what is implemented here) it would be approximately 20%.
In such an extreme case (with this many entries), it does not help to implement the extra hashes by re-hashing the hash, the extra hashes would have to be truly independent hashes (which also means that the interface cannot simply take one hash, that is not enough information). Otherwise, if multiple values all hash to some integer h
, the hashes of that hash would also all be the same anyway, so the extra hashes would not help to disambiguate the value. With fewer entries you can sometimes reuse the same hash, for example with 210 entries you can extract three 10-bit hashes from a 32-bit hash, and still have a couple of bits left over.
Bug
int.MinValue
is a perfectly fine hash, but -HashCode - 1
would evaluate to int.MaxValue
, which is just out of bounds (the underlying BitArray
hash a length of int.MaxValue
, so this is out of bounds by just 1).
Both bit arrays have length int.MaxValue
, so we're "missing" two entries compared to the full domain of int
. Zero is explicitly ignored, but another value has to be sacrificed as well to make things fit. The natural choice is int.MinValue
. Of course another option is implementing your own bit array (which is very easy actually), then it can simply have 232 entries and no quirks.
A Bloom filter with 232 entries is extreme anyway. If you use fewer than 231 entries, it would fit in a single BitArray
without any trouble.