OFilter

OFilter is an opinionated Bloom filter implemented in Rust.

It implements:

The basic Bloom filter is inspired from the existing and stable bloomfilter crate but does not directly depend on it. The API is slightly different, and makes a few opinionated changes.

In practice, I am using this filter to implement a self-expiring KV store.

OFilter icon

Status

While this is, to my knowledge, not used in "real" production, this is not a very complex codebase and it comes with a rather complete test suite, so it should be OK to use it. Most of the bricks it builds on are well-tested, widely used packages. Again, DISCLAIMER, use at your own risks.

Build Status Crates.io Gitlab License

Benchmarks

Taken from a random CI job:

running 7 tests test tests::bench_extern_crate_bloom ... bench: 287 ns/iter (+/- 37) test tests::bench_extern_crate_bloomfilter ... bench: 232 ns/iter (+/- 7) test tests::bench_ofilter_bloom ... bench: 81 ns/iter (+/- 5) test tests::bench_ofilter_stream ... bench: 257 ns/iter (+/- 39) test tests::bench_ofilter_sync_bloom ... bench: 101 ns/iter (+/- 1) test tests::bench_ofilter_sync_stream ... bench: 280 ns/iter (+/- 14) test tests::bench_standard_hashset ... bench: 199 ns/iter (+/- 54) test result: ok. 0 passed; 0 failed; 0 ignored; 7 measured; 0 filtered out; finished in 16.47s

This is not the result of extensive, thorough benchmarking, just a random snapshot at some point in development history.

The TL;DR is: OFilter performs relatively well compared to others.

The streaming version is slower but that is expected, as it uses two filters under the hood, and performs extra checks to know when to swap buffers.

It is also interesting to note that using a standard HashSet is quite efficient for small objects. The benchmark above uses isize entries. So if your set is composed if small elements and is limited in absolute number, using a simple set from the standard library may be good enough. Of course using a Bloom filter has other advantates than raw CPU usage, most importantly it ensures memory usage stays low and constant, which is a great advantage. But keep in mind the problem you're trying to solve. Bench, measure, gather numbers, use facts, not intuition.

Usage

```rust use ofilter::Bloom;

let mut filter: Bloom = Filter::new(100); assert!(!filter.check(&42)); filter.set(&42); assert!(filter.check(&42)); ```

Links

License

OFilter is licensed under the MIT license.