1use binout::{AsIs, Serializer};
4use bitm::{ArrayWithRank101111, ceiling_div};
5pub use seedable_hash::{map64_to_64, map32_to_32};
6
7pub type ArrayWithRank = ArrayWithRank101111;
8
9pub fn read_bits<R: std::io::Read + ?Sized>(input: &mut R, number_of_bits: usize) -> std::io::Result<Box<[u64]>> {
11 AsIs::read_n(input, ceiling_div(number_of_bits, 64))
12}
13
14pub fn verify_partial_phf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(expected_range: usize, keys: impl IntoIterator<Item=K>, phf: G) {
16 use bitm::{BitVec, BitAccess};
17 let mut seen_values = Box::with_zeroed_bits(expected_range);
18 for key in keys {
19 if let Some(v) = phf(&key) {
20 assert!(v < expected_range, "f({key})={v} exceeds maximum value {}", expected_range-1);
21 assert!(!seen_values.get_bit(v as usize), "f returned the same value {v} for {key} and another key");
22 seen_values.set_bit(v);
23 }
24 }
25}
26
27pub fn verify_phf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(expected_range: usize, keys: impl IntoIterator<Item=K>, phf: G) {
29 verify_partial_phf(expected_range, keys, |key| {
30 let v = phf(key);
31 assert!(v.is_some(), "f does not assign the value to the key {} which is in the input", key);
32 v
33 });
34}
35
36pub 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) {
38 if k == 1 { verify_partial_phf(expected_range, keys, kphf); return; }
39 let mut seen_values = vec![0; expected_range];
40 for key in keys {
41 if let Some(v) = kphf(&key) {
42 assert!(v < expected_range, "f({key})={v} exceeds maximum value {}", expected_range-1);
43 assert!(seen_values[v as usize] < k, "f returned the same value {v} for {key} and {k} another keys");
44 seen_values[v as usize] += 1;
45 }
46 }
47}
48
49pub fn verify_kphf<K: std::fmt::Display, G: Fn(&K)->Option<usize>>(k: u8, expected_range: usize, keys: impl IntoIterator<Item=K>, kphf: G) {
51 verify_partial_kphf(k, expected_range, keys, |key| {
52 let v = kphf(key);
53 assert!(v.is_some(), "f does not assign the value to the key {} which is in the input", key);
54 v
55 });
56}
57
58
59#[cfg(test)]
60pub(crate) mod tests {
61 use super::verify_phf;
62
63 pub fn test_mphf<K: std::fmt::Display+Clone, G: Fn(&K)->Option<usize>>(mphf_keys: &[K], mphf: G) {
64 verify_phf(mphf_keys.len(), mphf_keys.iter().cloned(), mphf);
65 }
66
67 pub fn test_mphf_u64<K: std::fmt::Display+Clone, G: Fn(&K)->Option<u64>>(mphf_keys: &[K], mphf: G) {
68 test_mphf(mphf_keys, |k| mphf(k).map(|v| v as usize));
69 }
70}