1use crate::hlp::*;
2
3const M_64: u64 = 0xc6a4a7935bd1e995;
5const M_32: u32 = M_64 as u32;
6
7pub fn murmur2(data: &[u8], seed: u32, load: impl Fn([u8; 4]) -> u32) -> u32 {
8 let h = seed ^ (data.len() as u32);
9
10 let mut chunks = data.chunks_exact(4);
11 let h = (&mut chunks).fold(h, |h, k| round!(M_32, h, load(k.try_into().unwrap())));
12 let h = short_round!(M_32, h, chunks.remainder(), u32);
13
14 h.slack(13).wrapping_mul(M_32).slack(15)
15}
16
17pub fn murmur64a(data: &[u8], seed: u64, load: impl Fn([u8; 8]) -> u64) -> u64 {
18 let h = seed ^ (data.len() as u64).wrapping_mul(M_64); let mut chunks = data.chunks_exact(8);
21 let h = (&mut chunks).fold(h, |h, k| {
22 (h ^ load(k.try_into().unwrap())
24 .wrapping_mul(M_64)
25 .slack(47)
26 .wrapping_mul(M_64))
27 .wrapping_mul(M_64)
28 });
29 let h = short_round!(M_64, h, chunks.remainder(), u64);
30
31 h.slack(47).wrapping_mul(M_64).slack(47)
32}
33
34pub fn murmur64b(data: &[u8], seed: u64, load: impl Fn([u8; 4]) -> u32) -> u64 {
35 let h1 = (seed as u32) ^ (data.len() as u32);
36 let h2 = (seed >> 32) as u32;
37
38 let mut chunks = data.chunks_exact(4);
39 let (h1, h2) = (&mut chunks).fold((h1, h2), |(h1, h2), k| {
40 (h2, round!(M_32, h1, load(k.try_into().unwrap())))
41 });
42 let (h1, h2) = match data.len() % 8 > 3 {
43 true => (h2, h1),
44 false => (h1, h2),
45 };
46 let h2 = short_round!(M_32, h2, chunks.remainder(), u32);
47
48 let h1 = (h1 ^ h2 >> 18).wrapping_mul(M_32);
49 let h2 = (h2 ^ h1 >> 22).wrapping_mul(M_32);
50 let h1 = (h1 ^ h2 >> 17).wrapping_mul(M_32);
51 let h2 = (h2 ^ h1 >> 19).wrapping_mul(M_32);
52
53 ((h1 as u64) << 32) | h2 as u64
54}
55
56pub fn murmur2a(data: &[u8], seed: u32, load: impl Fn([u8; 4]) -> u32) -> u32 {
57 let mut chunks = data.chunks_exact(4);
58 let h = (&mut chunks).fold(seed, |h, k| round!(M_32, h, load(k.try_into().unwrap())));
59 let t = rest!(chunks.remainder(), u32);
60
61 round!(M_32, round!(M_32, h, t), data.len() as u32)
62 .slack(13)
63 .wrapping_mul(M_32)
64 .slack(15)
65}