diff options
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | .github/workflows/rust.yml | 192 | ||||
-rw-r--r-- | Android.bp | 6 | ||||
-rw-r--r-- | Cargo.toml | 10 | ||||
-rw-r--r-- | Cargo.toml.orig | 6 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | src/aes_hash.rs | 3 | ||||
-rw-r--r-- | src/fallback_hash.rs | 11 | ||||
-rw-r--r-- | src/hash_quality_test.rs | 42 | ||||
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/operations.rs | 6 | ||||
-rw-r--r-- | src/random_state.rs | 6 | ||||
-rw-r--r-- | tests/bench.rs | 4 | ||||
-rw-r--r-- | tests/map_tests.rs | 76 |
14 files changed, 211 insertions, 166 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 93d0a7d..5c04dfe 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "ea78b05f0d603d40fa28855ba271f47494862e9d" + "sha1": "db36e4c4f0606b786bc617eefaffbe4ae9100762" }, "path_in_vcs": "" }
\ No newline at end of file diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1d440a5..7e28cda 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -6,191 +6,151 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest stable - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: toolchain: stable components: clippy - name: check nostd - uses: actions-rs/cargo@v1 - with: - command: check - args: --no-default-features + run: cargo check --no-default-features - name: test nostd - uses: actions-rs/cargo@v1 - with: - command: test - args: --no-default-features + run: cargo test --no-default-features - name: check constrandom - uses: actions-rs/cargo@v1 - with: - command: check - args: --no-default-features --features compile-time-rng + run: cargo check --no-default-features --features compile-time-rng - name: test constrandom - uses: actions-rs/cargo@v1 - with: - command: test - args: --no-default-features --features compile-time-rng + run: cargo test --no-default-features --features compile-time-rng - name: check fixed-seed - uses: actions-rs/cargo@v1 - with: - command: check - args: --no-default-features --features std + run: cargo check --no-default-features --features std - name: check - uses: actions-rs/cargo@v1 - with: - command: check + run: cargo check - name: test - uses: actions-rs/cargo@v1 - with: - command: test + run: cargo test nightly: name: nightly runs-on: ubuntu-latest env: RUSTFLAGS: -C target-cpu=native steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install latest nightly - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true components: clippy - name: check nightly - uses: actions-rs/cargo@v1 - with: - command: check - args: -Z msrv-policy + run: cargo check -Z msrv-policy - name: test nightly - uses: actions-rs/cargo@v1 - with: - command: test + run: cargo test - name: check serde - uses: actions-rs/cargo@v1 - with: - command: check - args: --features serde + run: cargo check --features serde - name: test serde - uses: actions-rs/cargo@v1 - with: - command: test - args: --features serde + run: cargo test --features serde linux_arm7: name: Linux ARMv7 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - target: armv7-unknown-linux-gnueabihf - - uses: actions-rs/cargo@v1 - with: - command: check - args: --target armv7-unknown-linux-gnueabihf + targets: armv7-unknown-linux-gnueabihf + - run: cargo check --target armv7-unknown-linux-gnueabihf + - name: Install 1.72.0 + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.72.0 + targets: armv7-unknown-linux-gnueabihf + - run: cargo +1.72.0 check --target armv7-unknown-linux-gnueabihf aarch64-apple-darwin: name: Aarch64 Apple Darwin runs-on: macos-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - target: aarch64-apple-darwin - - uses: actions-rs/cargo@v1 - with: - command: check - args: --target aarch64-apple-darwin + targets: aarch64-apple-darwin + - run: cargo check --target aarch64-apple-darwin + - run: cargo test + - run: cargo test --no-default-features --features compile-time-rng + - name: Install 1.72.0 + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.72.0 + targets: aarch64-apple-darwin + - run: cargo +1.72.0 check --target aarch64-apple-darwin i686-unknown-linux-gnu: name: Linux i686 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - target: i686-unknown-linux-gnu + targets: i686-unknown-linux-gnu - name: Install cross compile tools run: sudo apt-get install -y gcc-multilib libc6-i386 libc6-dev-i386 - - uses: actions-rs/cargo@v1 - with: - command: check - args: --target i686-unknown-linux-gnu - - uses: actions-rs/cargo@v1 + - run: cargo check --target i686-unknown-linux-gnu + - run: cargo test --target i686-unknown-linux-gnu + - name: check constrandom + run: cargo check --no-default-features --features compile-time-rng --target i686-unknown-linux-gnu + - name: Install 1.72.0 + uses: dtolnay/rust-toolchain@master with: - command: test - args: --target i686-unknown-linux-gnu + toolchain: 1.72.0 + targets: i686-unknown-linux-gnu + - run: cargo +1.72.0 check --target i686-unknown-linux-gnu + - name: check constrandom + run: cargo +1.72.0 check --no-default-features --features compile-time-rng --target i686-unknown-linux-gnu x86_64-unknown-linux-gnu: - name: Linux x86_64 - nightly + name: Linux x86_64 runs-on: ubuntu-latest env: RUSTFLAGS: -C target-cpu=skylake -C target-feature=+aes steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - target: x86_64-unknown-linux-gnu - - uses: actions-rs/cargo@v1 - with: - command: check - args: --target x86_64-unknown-linux-gnu - - uses: actions-rs/cargo@v1 + targets: x86_64-unknown-linux-gnu + - run: cargo check --target x86_64-unknown-linux-gnu + - run: cargo test --target x86_64-unknown-linux-gnu + - name: check constrandom + run: cargo check --no-default-features --features compile-time-rng --target x86_64-unknown-linux-gnu + - name: Install 1.72.0 + uses: dtolnay/rust-toolchain@master with: - command: test - args: --target x86_64-unknown-linux-gnu + toolchain: 1.72.0 + - run: cargo +1.72.0 check --target x86_64-unknown-linux-gnu + - name: check constrandom + run: cargo +1.72.0 check --no-default-features --features compile-time-rng --target x86_64-unknown-linux-gnu thumbv6m: name: thumbv6m runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - target: thumbv6m-none-eabi - - uses: actions-rs/cargo@v1 - with: - command: check - args: --target thumbv6m-none-eabi --no-default-features + targets: thumbv6m-none-eabi + - run: cargo check --target thumbv6m-none-eabi --no-default-features wasm32-unknown-unknown: name: wasm runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - target: wasm32-unknown-unknown - - uses: actions-rs/cargo@v1 - with: - command: check - args: --target wasm32-unknown-unknown --no-default-features - msrv: - name: MSRV - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install 1.60.0 - uses: actions-rs/toolchain@v1 - with: - toolchain: 1.60.0 - - name: check - uses: actions-rs/cargo@v1 - with: - command: check + targets: wasm32-unknown-unknown + - run: cargo check --target wasm32-unknown-unknown --no-default-features no_std: name: no-std build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - - uses: actions-rs/cargo@v1 - with: - command: build - args: --manifest-path=no_std_test/Cargo.toml + - run: cargo build --manifest-path=no_std_test/Cargo.toml
\ No newline at end of file @@ -1,5 +1,7 @@ // This file is generated by cargo_embargo. -// Do not modify this file as changes will be overridden on upgrade. +// Do not modify this file after the first "rust_*" or "genrule" module +// because the changes will be overridden on upgrade. +// Content before the first "rust_*" or "genrule" module is preserved. package { default_applicable_licenses: ["external_rust_crates_ahash_license"], @@ -42,7 +44,7 @@ rust_library { host_supported: true, crate_name: "ahash", cargo_env_compat: true, - cargo_pkg_version: "0.8.7", + cargo_pkg_version: "0.8.11", srcs: ["src/lib.rs"], edition: "2018", arch: { @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.60.0" name = "ahash" -version = "0.8.7" +version = "0.8.11" authors = ["Tom Kaitchuck <Tom.Kaitchuck@gmail.com>"] build = "./build.rs" exclude = [ @@ -120,7 +120,7 @@ version = "1.0.5" version = "0.2.1" [dev-dependencies.hashbrown] -version = "0.12.3" +version = "0.14.3" [dev-dependencies.hex] version = "0.4.2" @@ -128,6 +128,9 @@ version = "0.4.2" [dev-dependencies.no-panic] version = "0.1.10" +[dev-dependencies.pcg-mwc] +version = "0.2.1" + [dev-dependencies.rand] version = "0.8.5" @@ -137,6 +140,9 @@ version = "4.0" [dev-dependencies.serde_json] version = "1.0.59" +[dev-dependencies.smallvec] +version = "1.13.1" + [build-dependencies.version_check] version = "0.9.4" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 7f2901f..a63f6d5 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "ahash" -version = "0.8.7" +version = "0.8.11" authors = ["Tom Kaitchuck <Tom.Kaitchuck@gmail.com>"] license = "MIT OR Apache-2.0" description = "A non-cryptographic hash function using AES-NI for high performance" @@ -97,8 +97,10 @@ 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" +smallvec = "1.13.1" [package.metadata.docs.rs] rustc-args = ["-C", "target-feature=+aes"] @@ -8,13 +8,13 @@ third_party { license_type: NOTICE last_upgrade_date { year: 2024 - month: 1 - day: 31 + month: 4 + day: 16 } homepage: "https://crates.io/crates/ahash" identifier { type: "Archive" - value: "https://static.crates.io/crates/ahash/ahash-0.8.7.crate" - version: "0.8.7" + value: "https://static.crates.io/crates/ahash/ahash-0.8.11.crate" + version: "0.8.11" } } diff --git a/src/aes_hash.rs b/src/aes_hash.rs index 0b9a1d4..daf3ae4 100644 --- a/src/aes_hash.rs +++ b/src/aes_hash.rs @@ -225,8 +225,7 @@ pub(crate) struct AHasherU64 { impl Hasher for AHasherU64 { #[inline] fn finish(&self) -> u64 { - let rot = (self.pad & 63) as u32; - self.buffer.rotate_left(rot) + folded_multiply(self.buffer, self.pad) } #[inline] diff --git a/src/fallback_hash.rs b/src/fallback_hash.rs index f78074d..bc5cbfe 100644 --- a/src/fallback_hash.rs +++ b/src/fallback_hash.rs @@ -56,8 +56,8 @@ impl AHasher { #[allow(dead_code)] // Is not called if non-fallback hash is used. pub(crate) fn from_random_state(rand_state: &RandomState) -> AHasher { AHasher { - buffer: rand_state.k0, - pad: rand_state.k1, + buffer: rand_state.k1, + pad: rand_state.k0, extra_keys: [rand_state.k2, rand_state.k3], } } @@ -117,7 +117,7 @@ impl AHasher { #[inline] #[cfg(feature = "specialize")] fn short_finish(&self) -> u64 { - self.buffer.wrapping_add(self.pad) + folded_multiply(self.buffer, self.pad) } } @@ -210,8 +210,8 @@ pub(crate) struct AHasherU64 { impl Hasher for AHasherU64 { #[inline] fn finish(&self) -> u64 { - let rot = (self.pad & 63) as u32; - self.buffer.rotate_left(rot) + folded_multiply(self.buffer, self.pad) + //self.buffer } #[inline] @@ -341,7 +341,6 @@ impl Hasher for AHasherStr { #[cfg(test)] mod tests { - use crate::convert::Convert; use crate::fallback_hash::*; #[test] diff --git a/src/hash_quality_test.rs b/src/hash_quality_test.rs index 4f6091a..f2fab16 100644 --- a/src/hash_quality_test.rs +++ b/src/hash_quality_test.rs @@ -108,13 +108,13 @@ fn test_keys_change_output<T: Hasher>(constructor: impl Fn(u128, u128) -> T) { fn test_input_affect_every_byte<T: Hasher>(constructor: impl Fn(u128, u128) -> T) { let base = hash_with(&0, constructor(0, 0)); for shift in 0..16 { - let mut alternitives = vec![]; + let mut alternatives = vec![]; for v in 0..256 { let input = (v as u128) << (shift * 8); let hasher = constructor(0, 0); - alternitives.push(hash_with(&input, hasher)); + alternatives.push(hash_with(&input, hasher)); } - assert_each_byte_differs(shift, base, alternitives); + assert_each_byte_differs(shift, base, alternatives); } } @@ -122,26 +122,26 @@ fn test_input_affect_every_byte<T: Hasher>(constructor: impl Fn(u128, u128) -> T fn test_keys_affect_every_byte<H: Hash, T: Hasher>(item: H, constructor: impl Fn(u128, u128) -> T) { let base = hash_with(&item, constructor(0, 0)); for shift in 0..16 { - let mut alternitives1 = vec![]; - let mut alternitives2 = vec![]; + let mut alternatives1 = vec![]; + let mut alternatives2 = vec![]; for v in 0..256 { let input = (v as u128) << (shift * 8); let hasher1 = constructor(input, 0); let hasher2 = constructor(0, input); let h1 = hash_with(&item, hasher1); let h2 = hash_with(&item, hasher2); - alternitives1.push(h1); - alternitives2.push(h2); + alternatives1.push(h1); + alternatives2.push(h2); } - assert_each_byte_differs(shift, base, alternitives1); - assert_each_byte_differs(shift, base, alternitives2); + assert_each_byte_differs(shift, base, alternatives1); + assert_each_byte_differs(shift, base, alternatives2); } } -fn assert_each_byte_differs(num: u64, base: u64, alternitives: Vec<u64>) { +fn assert_each_byte_differs(num: u64, base: u64, alternatives: Vec<u64>) { let mut changed_bits = 0_u64; - for alternitive in alternitives { - changed_bits |= base ^ alternitive + for alternative in alternatives { + changed_bits |= base ^ alternative } assert_eq!( core::u64::MAX, @@ -338,22 +338,24 @@ fn test_length_extension<T: Hasher>(hasher: impl Fn(u128, u128) -> T) { } fn test_sparse<T: Hasher>(hasher: impl Fn() -> T) { + use smallvec::SmallVec; + let mut buf = [0u8; 256]; let mut hashes = HashMap::new(); - for idx_1 in 0..256 { - for idx_2 in idx_1 + 1..256 { + for idx_1 in 0..255_u8 { + for idx_2 in idx_1 + 1..=255_u8 { for value_1 in [1, 2, 4, 8, 16, 32, 64, 128] { for value_2 in [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 16, 17, 18, 20, 24, 31, 32, 33, 48, 64, 96, 127, 128, 129, 192, 254, 255, ] { - buf[idx_1] = value_1; - buf[idx_2] = value_2; + buf[idx_1 as usize] = value_1; + buf[idx_2 as usize] = value_2; let hash_value = hash_with(&buf, &mut hasher()); - let keys = hashes.entry(hash_value).or_insert(Vec::new()); - keys.push((idx_1, value_1, idx_2, value_2)); - buf[idx_1] = 0; - buf[idx_2] = 0; + let keys = hashes.entry(hash_value).or_insert(SmallVec::<[[u8; 4]; 1]>::new()); + keys.push([idx_1, value_1, idx_2, value_2]); + buf[idx_1 as usize] = 0; + buf[idx_2 as usize] = 0; } } } @@ -77,7 +77,7 @@ use ahash::AHashMap; let mut map: AHashMap<i32, i32> = AHashMap::new(); map.insert(12, 34); ``` -This avoids the need to type "RandomState". (For convience `From`, `Into`, and `Deref` are provided). +This avoids the need to type "RandomState". (For convenience `From`, `Into`, and `Deref` are provided). # Aliases @@ -108,7 +108,7 @@ mod fallback_hash; cfg_if::cfg_if! { if #[cfg(any( all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), - all(target_arch = "aarch64", target_feature = "aes", not(miri)), + all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)), all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)), ))] { mod aes_hash; @@ -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 a420587..8395007 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -1,4 +1,5 @@ use crate::convert::*; +#[allow(unused)] use zerocopy::transmute; ///This constant comes from Kunth's prng (Empirically it works better than those from splitmix32). @@ -111,7 +112,7 @@ pub(crate) fn aesenc(value: u128, xor: u128) -> u128 { } #[cfg(any( - all(target_arch = "aarch64", target_feature = "aes", not(miri)), + all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)), all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)), ))] #[allow(unused)] @@ -141,7 +142,7 @@ pub(crate) fn aesdec(value: u128, xor: u128) -> u128 { } #[cfg(any( - all(target_arch = "aarch64", target_feature = "aes", not(miri)), + all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)), all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)), ))] #[allow(unused)] @@ -183,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/src/random_state.rs b/src/random_state.rs index 16fcc46..640d123 100644 --- a/src/random_state.rs +++ b/src/random_state.rs @@ -2,7 +2,7 @@ use core::hash::Hash; cfg_if::cfg_if! { if #[cfg(any( all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "aes", not(miri)), - all(target_arch = "aarch64", target_feature = "aes", not(miri)), + all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)), all(feature = "nightly-arm-aes", target_arch = "arm", target_feature = "aes", not(miri)), ))] { use crate::aes_hash::*; @@ -481,8 +481,8 @@ impl BuildHasherExt for RandomState { #[inline] fn hash_as_u64<T: Hash + ?Sized>(&self, value: &T) -> u64 { let mut hasher = AHasherU64 { - buffer: self.k0, - pad: self.k1, + buffer: self.k1, + pad: self.k0, }; value.hash(&mut hasher); hasher.finish() diff --git a/tests/bench.rs b/tests/bench.rs index e038ba4..2d000c0 100644 --- a/tests/bench.rs +++ b/tests/bench.rs @@ -14,7 +14,7 @@ const AHASH_IMPL: &str = if cfg!(any( target_feature = "aes", not(miri), ), - all(target_arch = "aarch64", target_feature = "aes", not(miri)), + all(feature = "nightly-arm-aes", target_arch = "aarch64", target_feature = "aes", not(miri)), all( feature = "nightly-arm-aes", target_arch = "arm", @@ -75,7 +75,7 @@ fn gen_strings() -> Vec<String> { macro_rules! bench_inputs { ($group:ident, $hash:ident) => { // Number of iterations per batch should be high enough to hide timing overhead. - let size = BatchSize::NumIterations(2_000); + let size = BatchSize::NumIterations(50_000); let mut rng = rand::thread_rng(); $group.bench_function("u8", |b| b.iter_batched(|| rng.gen::<u8>(), |v| $hash(&v), size)); diff --git a/tests/map_tests.rs b/tests/map_tests.rs index 8d798a0..97fdbee 100644 --- a/tests/map_tests.rs +++ b/tests/map_tests.rs @@ -200,6 +200,82 @@ fn test_ahash_alias_set_construction() { set.insert(1); } + +#[cfg(feature = "std")] +#[test] +fn test_key_ref() { + let mut map = ahash::HashMap::default(); + map.insert(1, "test"); + assert_eq!(Some((1, "test")), map.remove_entry(&1)); + + let mut map = ahash::HashMap::default(); + map.insert(&1, "test"); + assert_eq!(Some((&1, "test")), map.remove_entry(&&1)); + + let mut m = ahash::HashSet::<Box<String>>::default(); + m.insert(Box::from("hello".to_string())); + assert!(m.contains(&"hello".to_string())); + + let mut m = ahash::HashSet::<String>::default(); + m.insert("hello".to_string()); + assert!(m.contains("hello")); + + let mut m = ahash::HashSet::<Box<[u8]>>::default(); + m.insert(Box::from(&b"hello"[..])); + 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) << 30).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<H: Hash>(b: &Vec<H>) -> u64 { let mut total: u64 = 0; for item in b { |