adds an atomic variant of the bloom filter (#12422)

For crds_gossip_pull, we want to parallelize build_crds_filters, which
requires concurrent writes to bloom filters.

This commit implements a variant of the bloom filter which uses atomics
for its bits vector and so is thread-safe.
This commit is contained in:
behzad nouri
2020-09-24 18:37:19 +00:00
committed by GitHub
parent 42f1ef8acb
commit bb183938d9
3 changed files with 209 additions and 1 deletions

View File

@ -3,7 +3,8 @@
extern crate test;
use bv::BitVec;
use fnv::FnvHasher;
use solana_runtime::bloom::{Bloom, BloomHashIndex};
use rand::Rng;
use solana_runtime::bloom::{AtomicBloom, Bloom, BloomHashIndex};
use solana_sdk::{
hash::{hash, Hash},
signature::Signature,
@ -97,3 +98,48 @@ fn bench_sigs_hashmap(bencher: &mut Bencher) {
});
assert_eq!(falses, 0);
}
#[bench]
fn bench_add_hash(bencher: &mut Bencher) {
let mut rng = rand::thread_rng();
let hash_values: Vec<_> = std::iter::repeat_with(|| Hash::new_rand(&mut rng))
.take(1200)
.collect();
let mut fail = 0;
bencher.iter(|| {
let mut bloom = Bloom::random(1287, 0.1, 7424);
for hash_value in &hash_values {
bloom.add(hash_value);
}
let index = rng.gen_range(0, hash_values.len());
if !bloom.contains(&hash_values[index]) {
fail += 1;
}
});
assert_eq!(fail, 0);
}
#[bench]
fn bench_add_hash_atomic(bencher: &mut Bencher) {
let mut rng = rand::thread_rng();
let hash_values: Vec<_> = std::iter::repeat_with(|| Hash::new_rand(&mut rng))
.take(1200)
.collect();
let mut fail = 0;
bencher.iter(|| {
let bloom: AtomicBloom<_> = Bloom::random(1287, 0.1, 7424).into();
// Intentionally not using parallelism here, so that this and above
// benchmark only compare the bit-vector ops.
// For benchmarking the parallel code, change bellow for loop to:
// hash_values.par_iter().for_each(|v| bloom.add(v));
for hash_value in &hash_values {
bloom.add(hash_value);
}
let bloom: Bloom<_> = bloom.into();
let index = rng.gen_range(0, hash_values.len());
if !bloom.contains(&hash_values[index]) {
fail += 1;
}
});
assert_eq!(fail, 0);
}