From e81df915da4cc953b4507d748e3201cff7b17338 Mon Sep 17 00:00:00 2001 From: SymmetricChaos <42520289+SymmetricChaos@users.noreply.github.com> Date: Sun, 27 Oct 2024 23:36:43 -0400 Subject: [PATCH] cityhash32 final helper --- hashers/src/cityhash.rs | 114 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 9 deletions(-) diff --git a/hashers/src/cityhash.rs b/hashers/src/cityhash.rs index 432ceb95..0cd7bd93 100644 --- a/hashers/src/cityhash.rs +++ b/hashers/src/cityhash.rs @@ -14,7 +14,7 @@ const C2: u32 = 0xe6546b64; const C3: u32 = 0x85ebca6b; const C4: u32 = 0xc2b2ae35; -// Functions taken from Murmur3 +// Function taken from Murmur3 fn final_mix(mut x: u32) -> u32 { x ^= x >> 16; x = x.wrapping_mul(C3); @@ -33,13 +33,6 @@ fn compress(mut x: u32, mut y: u32) -> u32 { y.wrapping_mul(5).wrapping_add(C2) } -macro_rules! permute3 { - ($a: ident, $b: ident, $c: ident) => { - std::mem::swap(&mut $a, &mut $b); - std::mem::swap(&mut $a, &mut $c); - }; -} - fn fetch_u32(bytes: &[u8], p: usize) -> u32 { u32::from_le_bytes(bytes[p..p + 4].try_into().unwrap()) } @@ -83,7 +76,110 @@ fn hash32_13_to_24(bytes: &[u8]) -> u32 { } fn hash32_25(bytes: &[u8]) -> u32 { - todo!() + let l = bytes.len(); + let mut h = l as u32; + let mut g = C0.wrapping_mul(h); + let mut f = g; + let a0 = fetch_u32(bytes, l - 4) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a1 = fetch_u32(bytes, l - 8) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a2 = fetch_u32(bytes, l - 16) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a3 = fetch_u32(bytes, l - 12) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a4 = fetch_u32(bytes, l - 20) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + h ^= a0; + h = h.rotate_left(19).wrapping_mul(5).wrapping_add(C2); + h ^= a2; + h = h.rotate_left(19).wrapping_mul(5).wrapping_add(C2); + g ^= a1; + g = g.rotate_left(19).wrapping_mul(5).wrapping_add(C2); + g ^= a3; + g = g.rotate_left(19).wrapping_mul(5).wrapping_add(C2); + f ^= a4; + f = f.rotate_left(19).wrapping_mul(5).wrapping_add(C2); + + let mut offset = 0; + + for _ in 0..((l - 1) / 20) { + let a0 = fetch_u32(bytes, offset) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a1 = fetch_u32(bytes, offset + 4); + let a2 = fetch_u32(bytes, 8) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a3 = fetch_u32(bytes, offset + 12) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C1); + let a4 = fetch_u32(bytes, offset + 16); + + h ^= a0; + h = h.rotate_left(18).wrapping_mul(5).wrapping_add(C2); + + f = f.wrapping_add(a1).rotate_left(19).wrapping_mul(C0); + + g = g + .wrapping_add(a2) + .rotate_left(18) + .wrapping_mul(5) + .wrapping_add(C2); + + h ^= a3.wrapping_add(a1); + h = h.rotate_left(19).wrapping_mul(5).wrapping_add(C2); + + g ^= a4; + g = g.swap_bytes().wrapping_mul(5); + + h = h.wrapping_add(a4.wrapping_mul(5)); + h = h.swap_bytes(); + + f = f.wrapping_add(a0); + + std::mem::swap(&mut f, &mut h); + std::mem::swap(&mut f, &mut g); + + offset += 20 + } + + g = g + .rotate_left(11) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C0); + f = f + .rotate_left(11) + .wrapping_mul(C0) + .rotate_left(17) + .wrapping_mul(C0); + + h.wrapping_add(g) + .rotate_left(19) + .wrapping_mul(5) + .wrapping_add(C2) + .rotate_left(17) + .wrapping_mul(C0) + .wrapping_add(f) + .rotate_left(19) + .wrapping_mul(5) + .wrapping_add(C2) + .rotate_left(17) + .wrapping_mul(C0) } pub struct CityHash32 {