use binout::{AsIs, Serializer};
use bitm::{ArrayWithRank101111, ceiling_div};
pub use seedable_hash::{map64_to_64, map32_to_32};
pub type ArrayWithRank = ArrayWithRank101111;
pub fn read_bits<R: std::io::Read + ?Sized>(input: &mut R, number_of_bits: usize) -> std::io::Result<Box<[u64]>> {
AsIs::read_n(input, ceiling_div(number_of_bits, 64))
}
pub fn verify_partial_phf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(expected_range: usize, keys: impl IntoIterator<Item=K>, phf: G) {
use bitm::{BitVec, BitAccess};
let mut seen_values = Box::with_zeroed_bits(expected_range);
for key in keys {
if let Some(v) = phf(&key) {
assert!(v < expected_range, "f({key})={v} exceeds maximum value {}", expected_range-1);
assert!(!seen_values.get_bit(v as usize), "f returned the same value {v} for {key} and another key");
seen_values.set_bit(v);
}
}
}
pub fn verify_phf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(expected_range: usize, keys: impl IntoIterator<Item=K>, phf: G) {
verify_partial_phf(expected_range, keys, |key| {
let v = phf(key);
assert!(v.is_some(), "f does not assign the value to the key {} which is in the input", key);
v
});
}
pub fn verify_partial_kphf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(k: u8, expected_range: usize, keys: impl IntoIterator<Item=K>, kphf: G) {
if k == 1 { verify_partial_phf(expected_range, keys, kphf); return; }
let mut seen_values = vec![0; expected_range];
for key in keys {
if let Some(v) = kphf(&key) {
assert!(v < expected_range, "f({key})={v} exceeds maximum value {}", expected_range-1);
assert!(seen_values[v as usize] < k, "f returned the same value {v} for {key} and {k} another keys");
seen_values[v as usize] += 1;
}
}
}
pub fn verify_kphf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(k: u8, expected_range: usize, keys: impl IntoIterator<Item=K>, kphf: G) {
verify_partial_kphf(k, expected_range, keys, |key| {
let v = kphf(key);
assert!(v.is_some(), "f does not assign the value to the key {} which is in the input", key);
v
});
}
#[cfg(test)]
pub(crate) mod tests {
use super::verify_phf;
pub fn test_mphf<K: std::fmt::Display+Clone, G: Fn(&K)->Option<usize>>(mphf_keys: &[K], mphf: G) {
verify_phf(mphf_keys.len(), mphf_keys.iter().cloned(), mphf);
}
pub fn test_mphf_u64<K: std::fmt::Display+Clone, G: Fn(&K)->Option<u64>>(mphf_keys: &[K], mphf: G) {
test_mphf(mphf_keys, |k| mphf(k).map(|v| v as usize));
}
}