use emdb::Emdb;
const STRESS_KEY_COUNT: usize = 64_000;
fn stress_key(i: usize) -> String {
format!("stress-key-{i:08}")
}
#[test]
fn v0_9_6_hash_function_handles_stress_pattern_without_misses() {
let db = Emdb::open_in_memory();
for i in 0..STRESS_KEY_COUNT {
let key = stress_key(i);
let value = format!("v{i}");
db.insert(key.as_bytes(), value.as_bytes())
.expect("insert should always succeed on a healthy hash");
}
assert_eq!(db.len().expect("len"), STRESS_KEY_COUNT);
let mut missing: Vec<String> = Vec::new();
let mut wrong_value: Vec<String> = Vec::new();
for i in 0..STRESS_KEY_COUNT {
let key = stress_key(i);
let expected = format!("v{i}");
match db.get(key.as_bytes()).expect("get must not error") {
None => missing.push(key),
Some(v) if v != expected.as_bytes() => wrong_value.push(key),
Some(_) => {}
}
}
assert!(
missing.is_empty(),
"{} keys went missing post-insert (regressed hash function?). \
First few: {:?}",
missing.len(),
&missing[..missing.len().min(5)]
);
assert!(
wrong_value.is_empty(),
"{} keys returned the wrong value (hash collision unhandled?). \
First few: {:?}",
wrong_value.len(),
&wrong_value[..wrong_value.len().min(5)]
);
}
#[test]
fn v0_9_6_hash_function_distinct_offsets_for_distinct_stress_keys() {
let db = Emdb::open_in_memory();
for i in 0..STRESS_KEY_COUNT {
db.insert(stress_key(i).as_bytes(), b"v1")
.expect("insert v1");
}
assert_eq!(db.len().expect("len after v1"), STRESS_KEY_COUNT);
for i in 0..STRESS_KEY_COUNT {
db.insert(stress_key(i).as_bytes(), b"v2")
.expect("insert v2");
}
assert_eq!(
db.len().expect("len after v2"),
STRESS_KEY_COUNT,
"overwriting every stress key must keep the live count constant"
);
for i in [0_usize, 1, 100, 1_000, 32_000, 63_999] {
assert_eq!(
db.get(stress_key(i).as_bytes()).expect("get").as_deref(),
Some(b"v2".as_slice()),
"stress-key-{i:08} should be v2 after overwrite"
);
}
}