use super::DummyMetrics;
use commonware_cryptography::{Hasher, Sha256};
use commonware_storage::{
index::{partitioned, Unordered},
translator::Cap,
};
use criterion::{criterion_group, Criterion};
use std::{
hint::black_box,
time::{Duration, Instant},
};
#[cfg(not(full_bench))]
const N_ITEMS: [usize; 2] = [10_000, 50_000];
#[cfg(full_bench)]
const N_ITEMS: [usize; 3] = [10_000, 50_000, 200_000];
fn keys(items: usize, grinding: bool) -> Vec<[u8; 8]> {
(0..items as u64)
.map(|i| {
if grinding {
i.to_be_bytes()
} else {
Sha256::hash(&i.to_be_bytes()).as_ref()[..8]
.try_into()
.unwrap()
}
})
.collect()
}
fn new_index() -> partitioned::ordered::Index<Cap<6>, u64, 2> {
partitioned::ordered::Index::new(DummyMetrics, Cap::<6>::new())
}
fn run_insert(keys: &[[u8; 8]]) -> Duration {
let mut index = new_index();
let start = Instant::now();
for (i, k) in keys.iter().enumerate() {
index.insert(k, i as u64);
}
start.elapsed()
}
fn bench_grinding(c: &mut Criterion) {
for items in N_ITEMS {
for grinding in [false, true] {
let dist = if grinding { "grinding" } else { "uniform" };
let ks = keys(items, grinding);
c.bench_function(
&format!("{}/op=insert dist={dist} items={items}", module_path!()),
|b| {
b.iter_custom(|iters| {
let mut total = Duration::ZERO;
for _ in 0..iters {
total += run_insert(&ks);
}
total
});
},
);
let mut index = new_index();
for (i, k) in ks.iter().enumerate() {
index.insert(k, i as u64);
}
c.bench_function(
&format!("{}/op=lookup dist={dist} items={items}", module_path!()),
|b| {
b.iter_custom(|iters| {
let mut total = Duration::ZERO;
for _ in 0..iters {
let start = Instant::now();
for k in &ks {
for v in index.get(k) {
black_box(v);
}
}
total += start.elapsed();
}
total
});
},
);
}
}
}
criterion_group! {
name = benches;
config = Criterion::default().sample_size(10);
targets = bench_grinding
}