Fleur – A bloom filter implementation in C
github.com
github.com
An efficient Bloom Filter should only allocate on heap exactly once: when allocating the initial bitmap. This implementation seems to be not very efficient as it allocates even during a simple query.
The usage of `static` variables makes the BloomFilter code unnecessarily dangerous to use when multiple threads are used even if every thread just wants to allocate and use totally separate bloom filters. Actually it could even cause issues with two bloom filters created after each other since even `Initialize` just returns a pointer to a single static `BloomFilter` :o I can't come up with a reason why you'd consider making anything in there `static`.
There is also strange code like this loop https://github.com/hashlookup/fleur/blob/4ee2644a850381d928a... that jumped into my eye.
Oh and btw I believe bloom_path can cause memory safety issues because it is not terminated with a null after strncopy.
I would additionally suggest to use some code formatting tool as it's a bit all over the place. But the variable/function names mix various styles as well.
The line below that is worse:
strncpy(bloom_path , argv[optind], 128);
If you pass something >= 128 chars then bloom_path won't be null terminated. In general strncpy should never be used for copying strings.
For expansion on that: https://ramblings.implicit.net/c/2014/05/02/c-functions-that...
And zeroing out data by freeing the memory and callocing new memory. Why not just write zeros into the memory instead of reallocating it from scratch only to overwrite it with zeros anyway?
Also written in C, with great performance (no comparison to this one, I haven't done it), and has been used in production by many companies for many years (since ~2012 or 2013).
Just pointing out other implementations if anyone is curious!
Fleur (and DCSO/bloom and DCSO/flor): fnv
bloomd: a combination of SpookyHash and murmur[2]
[1]: https://llimllib.github.io/bloomfilter-tutorial/ (I'll update it to add bloomd and spooky)
[2]: https://github.com/armon/bloomd/blob/23c19a7f5cbb35d7c3d970b...
[3]: I have a vague recollection of somebody telling me why combining two hashes in the way bloomd does for k >= 4 is a good idea but I can't remember - anybody have a good reference for me to link to? (edit: nvm, I already link the paper on my page! sheesh)
I've used this trick at scale on network gear and it works great.
Could you give a summary? The paper is quite mathematical and seems to lack a clear description of how to actually use the two hashes without reading in depth.
Even fast hash functions like Murmur add overhead, though, and the lower the desired false positive rate, the more hash functions you need (x hash functions for 2^-x false positive rate).
The conclusion of the paper is roughly that you can create new hash functions by recombining the outputs of two initial hash functions without compromising the statistical integrity of the filter, and this makes querying the filter a lot faster.
To be clear, even the two initial hash functions can be halves or quarters of a single hash function with an output larger than the filter needs, e.g. a filter that needs 64-bit hashes can run entirely on Murmur-128 using its bottom and top halves as the two hash functions.
For anyone trying to understand Bloom filters who may be interested in checking out an alternative C implementation (designed to be compiled to WebAssembly), I'll link mine below.
I used it to build a Bloom filter of every Hacker News submission ever for a privacy-preserving browser extension that tells you if the page you're currently on has been submitted before.
https://github.com/jstrieb/hackernews-button/blob/master/blo...