Skip to content

Commit 956e011

Browse files
[Storage] Fix UintIdentity hasher defeating hashbrown's SIMD filter (#3480)
Co-authored-by: Patrick O'Grady <me@patrickogrady.xyz>
1 parent 7723a4f commit 956e011

9 files changed

Lines changed: 278 additions & 197 deletions

File tree

storage/fuzz/Cargo.toml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,6 @@ test = false
152152
doc = false
153153
bench = false
154154

155-
[[bin]]
156-
name = "translator_operations"
157-
path = "fuzz_targets/translator_operations.rs"
158-
test = false
159-
doc = false
160-
bench = false
161-
162155
[[bin]]
163156
name = "mmr_journaled"
164157
path = "fuzz_targets/mmr_journaled.rs"

storage/fuzz/fuzz_targets/translator_operations.rs

Lines changed: 0 additions & 144 deletions
This file was deleted.

storage/src/index/benches/bench.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,49 @@
1+
use commonware_cryptography::{Hasher, Sha256};
2+
use commonware_runtime::Metrics;
13
use criterion::criterion_main;
4+
use prometheus_client::registry::Metric;
25

36
mod hashmap_insert;
47
mod hashmap_insert_fixed;
58
mod hashmap_iteration;
69
mod insert;
10+
mod lookup;
11+
mod lookup_miss;
12+
13+
pub(crate) type Digest = <Sha256 as Hasher>::Digest;
14+
15+
#[derive(Clone)]
16+
pub(crate) struct DummyMetrics;
17+
18+
impl Metrics for DummyMetrics {
19+
fn label(&self) -> String {
20+
"".into()
21+
}
22+
23+
fn with_label(&self, _: &str) -> Self {
24+
Self
25+
}
26+
27+
fn encode(&self) -> String {
28+
"".into()
29+
}
30+
31+
fn register<N: Into<String>, H: Into<String>>(&self, _: N, _: H, _: impl Metric) {}
32+
33+
fn with_attribute(&self, _: &str, _: impl std::fmt::Display) -> Self {
34+
Self
35+
}
36+
37+
fn with_scope(&self) -> Self {
38+
Self
39+
}
40+
}
741

842
criterion_main!(
943
hashmap_iteration::benches,
1044
hashmap_insert_fixed::benches,
1145
hashmap_insert::benches,
1246
insert::benches,
47+
lookup::benches,
48+
lookup_miss::benches,
1349
);

storage/src/index/benches/insert.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
use super::DummyMetrics;
12
use commonware_cryptography::{Hasher, Sha256};
2-
use commonware_runtime::Metrics;
33
use commonware_storage::{
44
index::{ordered, partitioned, unordered, Unordered},
55
translator::{Cap, FourCap, Hashed, TwoCap},
66
};
77
use criterion::{criterion_group, Criterion};
8-
use prometheus_client::registry::Metric;
98
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
109
use std::time::{Duration, Instant};
1110

@@ -55,33 +54,6 @@ const VARIANTS: [Variant; 9] = [
5554
Variant::HashedPartitionedUnordered2,
5655
];
5756

58-
#[derive(Clone)]
59-
struct DummyMetrics;
60-
61-
impl Metrics for DummyMetrics {
62-
fn label(&self) -> String {
63-
"".into()
64-
}
65-
66-
fn with_label(&self, _: &str) -> Self {
67-
Self
68-
}
69-
70-
fn encode(&self) -> String {
71-
"".into()
72-
}
73-
74-
fn register<N: Into<String>, H: Into<String>>(&self, _: N, _: H, _: impl Metric) {}
75-
76-
fn with_attribute(&self, _: &str, _: impl std::fmt::Display) -> Self {
77-
Self
78-
}
79-
80-
fn with_scope(&self) -> Self {
81-
Self
82-
}
83-
}
84-
8557
fn bench_insert(c: &mut Criterion) {
8658
for items in N_ITEMS {
8759
// Setup items
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use super::{Digest, DummyMetrics};
2+
use commonware_cryptography::{Hasher, Sha256};
3+
use commonware_storage::{
4+
index::{unordered, Unordered},
5+
translator::{EightCap, FourCap, OneCap, Translator, TwoCap},
6+
};
7+
use criterion::{criterion_group, Criterion};
8+
use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng};
9+
use std::{
10+
hint::black_box,
11+
time::{Duration, Instant},
12+
};
13+
14+
#[cfg(not(full_bench))]
15+
const N_ITEMS: [usize; 2] = [10_000, 50_000];
16+
#[cfg(full_bench)]
17+
const N_ITEMS: [usize; 5] = [10_000, 50_000, 100_000, 500_000, 1_000_000];
18+
19+
fn run_lookup<T: Translator>(
20+
c: &mut Criterion,
21+
translator: T,
22+
name: &str,
23+
items: usize,
24+
keys: &[Digest],
25+
) {
26+
// Populate the index
27+
let mut index = unordered::Index::new(DummyMetrics, translator);
28+
for (i, key) in keys.iter().enumerate().take(items) {
29+
index.insert(key, i as u64);
30+
}
31+
32+
// Shuffle lookup order
33+
let mut rng = StdRng::seed_from_u64(1);
34+
let mut lookup_keys: Vec<_> = keys.iter().take(items).cloned().collect();
35+
lookup_keys.shuffle(&mut rng);
36+
37+
let label = format!("{}/translator={name} items={items}", module_path!());
38+
c.bench_function(&label, |b| {
39+
b.iter_custom(|iters| {
40+
let mut total = Duration::ZERO;
41+
for _ in 0..iters {
42+
let start = Instant::now();
43+
for key in &lookup_keys {
44+
black_box(index.get(key).next().is_some());
45+
}
46+
total += start.elapsed();
47+
}
48+
total
49+
});
50+
});
51+
}
52+
53+
fn bench_lookup(c: &mut Criterion) {
54+
let max_items = *N_ITEMS.last().unwrap();
55+
let keys: Vec<_> = (0..max_items)
56+
.map(|i| Sha256::hash(&i.to_be_bytes()))
57+
.collect();
58+
59+
for items in N_ITEMS {
60+
run_lookup(c, OneCap, "one_cap", items, &keys);
61+
run_lookup(c, TwoCap, "two_cap", items, &keys);
62+
run_lookup(c, FourCap, "four_cap", items, &keys);
63+
run_lookup(c, EightCap, "eight_cap", items, &keys);
64+
}
65+
}
66+
67+
criterion_group! {
68+
name = benches;
69+
config = Criterion::default().sample_size(10);
70+
targets = bench_lookup,
71+
}

0 commit comments

Comments
 (0)