diff --git a/Cargo.toml b/Cargo.toml index 7e388c4..cba3897 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,8 +97,9 @@ fnv = "1.0.5" fxhash = "0.2.1" hex = "0.4.2" rand = "0.8.5" +pcg-mwc = "0.2.1" serde_json = "1.0.59" -hashbrown = "0.12.3" +hashbrown = "0.14.3" [package.metadata.docs.rs] rustc-args = ["-C", "target-feature=+aes"] diff --git a/src/aes_hash.rs b/src/aes_hash.rs index 0b9a1d4..7ad9af7 100644 --- a/src/aes_hash.rs +++ b/src/aes_hash.rs @@ -252,6 +252,7 @@ impl Hasher for AHasherU64 { #[inline] fn write_u64(&mut self, i: u64) { self.buffer = folded_multiply(i ^ self.buffer, MULTIPLE); + self.pad = self.pad.wrapping_add(i); } #[inline] diff --git a/src/fallback_hash.rs b/src/fallback_hash.rs index f78074d..eb55479 100644 --- a/src/fallback_hash.rs +++ b/src/fallback_hash.rs @@ -237,6 +237,7 @@ impl Hasher for AHasherU64 { #[inline] fn write_u64(&mut self, i: u64) { self.buffer = folded_multiply(i ^ self.buffer, MULTIPLE); + self.pad = self.pad.wrapping_add(i); } #[inline] @@ -341,7 +342,6 @@ impl Hasher for AHasherStr { #[cfg(test)] mod tests { - use crate::convert::Convert; use crate::fallback_hash::*; #[test] diff --git a/src/lib.rs b/src/lib.rs index 653c3bc..69fb2ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -319,7 +319,6 @@ mod test { use crate::specialize::CallHasher; use crate::*; use std::collections::HashMap; - use std::hash::Hash; #[test] fn test_ahash_alias_map_construction() { diff --git a/src/operations.rs b/src/operations.rs index 1970cbf..8395007 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -184,7 +184,6 @@ pub(crate) fn add_in_length(enc: &mut u128, len: u64) { #[cfg(test)] mod test { use super::*; - use crate::convert::Convert; // This is code to search for the shuffle constant // diff --git a/tests/map_tests.rs b/tests/map_tests.rs index bdf37d8..7849f4a 100644 --- a/tests/map_tests.rs +++ b/tests/map_tests.rs @@ -225,6 +225,56 @@ fn test_key_ref() { assert!(m.contains(&b"hello"[..])); } +#[cfg(feature = "std")] +#[test] +fn test_byte_dist() { + use rand::{SeedableRng, Rng, RngCore}; + use pcg_mwc::Mwc256XXA64; + + let mut r = Mwc256XXA64::seed_from_u64(0xe786_c22b_119c_1479); + let mut lowest = 2.541; + let mut highest = 2.541; + for _round in 0..100 { + let mut table: [bool; 256 * 8] = [false; 256 * 8]; + let hasher = RandomState::with_seeds(r.gen(), r.gen(), r.gen(), r.gen()); + for i in 0..128 { + let mut keys: [u8; 8] = hasher.hash_one(i as u64).to_ne_bytes(); + //let mut keys = r.next_u64().to_ne_bytes(); //This is a control to test assert sensitivity. + for idx in 0..8 { + while table[idx * 256 + keys[idx] as usize] { + keys[idx] = keys[idx].wrapping_add(1); + } + table[idx * 256 + keys[idx] as usize] = true; + } + } + + for idx in 0..8 { + let mut len = 0; + let mut total_len = 0; + let mut num_seq = 0; + for i in 0..256 { + if table[idx * 256 + i] { + len += 1; + } else if len != 0 { + num_seq += 1; + total_len += len; + len = 0; + } + } + let mean = total_len as f32 / num_seq as f32; + println!("Mean sequence length = {}", mean); + if mean > highest { + highest = mean; + } + if mean < lowest { + lowest = mean; + } + } + } + assert!(lowest > 1.9, "Lowest = {}", lowest); + assert!(highest < 3.9, "Highest = {}", highest); +} + fn ahash_vec(b: &Vec) -> u64 { let mut total: u64 = 0;