Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ jobs:
- run: cargo test --no-default-features
- run: cargo test --all-features

cross-platform-test:
name: Cross-platform tests
runs-on: ubuntu-latest
strategy:
matrix:
target:
- powerpc-unknown-linux-gnu # 32-bit big-endian
- i686-unknown-linux-gnu # 32-bit little-endian
- aarch64-unknown-linux-gnu # 64-bit little-endian (ARM)
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: taiki-e/install-action@v2
with:
tool: cross
- run: cross test --features serde --target ${{ matrix.target }} --lib

fuzz-tests:
name: Fuzz tests
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jsonschema = ["schemars"]
serde = ["dep:serde", "dep:serde_bytes"]

[dependencies]
xxhash-rust = { version = "0.8.12", features = ["xxh3"] }
foldhash-portable = { version = "0.2.0", features = ["portable"] }
serde = { optional = true, version = "1", features = ["derive"] }
serde_bytes = { optional = true, version = "0.11" }
schemars = { optional = true, version = "1" }
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ for i in 0..1000 {

### Hasher

The hashing algorithm used is [xxhash3](https://crates.io/crates/xxhash-rust) which offers both high performance and stability across platforms.
Methods accepting `T: Hash` are provided for convenience using [foldhash-portable](https://crates.io/crates/foldhash-portable), which offers high performance and stability across platforms. Note that a fixed seed is used (no DoS resistance) and `#[derive(Hash)]` output is [not guaranteed stable](https://github.com/hoxxep/portable-hash#whats-wrong-with-the-stdhash-traits) across Rust compiler versions.

`Filter` supports a custom `BuildHasher` via its `S` type parameter (similar to `HashMap`). Use `Filter::new_with_hasher()` and related constructors. The hasher is not serialized; on deserialization it is reconstructed via `S::default()`. If that doesn't produce the correct hasher, use `Filter::with_hasher()` to restore it. Filters being merged must use the same hasher.

### Filter size

Expand Down
8 changes: 5 additions & 3 deletions benches/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,17 @@ fn bench_fingerprints(c: &mut Criterion) {
}

fn bench_sorted_insert(c: &mut Criterion) {
let inserter = Builder::new(10000, 0.01).unwrap();
let inserter = Builder::new(Filter::new(10000, 0.01).unwrap());
let fp_size = inserter.fingerprint_size();
let cap = inserter.capacity();
let mut fingerprints: Vec<u64> = (0..cap).map(|i| compute_fingerprint(i, fp_size)).collect();
let mut fingerprints: Vec<u64> = (0..cap)
.map(|i| compute_fingerprint_with_hasher(&StableBuildHasher, i, fp_size))
.collect();
fingerprints.sort_unstable();

c.bench_function("sorted_insert", |b| {
b.iter(|| {
let mut inserter = Builder::new(10000, 0.01).unwrap();
let mut inserter = Builder::new(Filter::new(10000, 0.01).unwrap());
for &h in &fingerprints {
inserter.insert_fingerprint(true, h).unwrap();
}
Expand Down
9 changes: 5 additions & 4 deletions fuzz/fuzz_targets/fuzz_sorted_insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ fuzz_target!(|input: Input| {
let Ok(mut regular) = regular_filter else {
return;
};
let builder = if resizable {
qfilter::Builder::new_resizeable(cap as u64, max_cap, 0.01)
let builder_filter = if resizable {
qfilter::Filter::new_resizeable(cap as u64, max_cap, 0.01)
} else {
qfilter::Builder::with_fingerprint_size(cap as u64, fp_size)
qfilter::Filter::with_fingerprint_size(cap as u64, fp_size)
};
let Ok(mut inserter) = builder else {
let Ok(builder_filter) = builder_filter else {
return;
};
let mut inserter = qfilter::Builder::new(builder_filter);

// Use the actual fingerprint size from the constructed filter
let actual_fp_size = regular.fingerprint_size();
Expand Down
Loading
Loading