1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::io::{Read, Result};
const C1: u32 = 0x85eb_ca6b;
const C2: u32 = 0xc2b2_ae35;
const R1: u32 = 16;
const R2: u32 = 13;
const M: u32 = 5;
const N: u32 = 0xe654_6b64;
pub fn murmur3_32<T: Read>(source: &mut T, seed: u32) -> Result<u32> {
let mut buffer: [u8; 4] = [0; 4];
let mut processed = 0;
let mut state = seed;
loop {
match source.read(&mut buffer)? {
4 => {
processed += 4;
let k = u32::from_le_bytes(buffer);
state ^= calc_k(k);
state = state.rotate_left(R2);
state = (state.wrapping_mul(M)).wrapping_add(N);
}
3 => {
processed += 3;
let k: u32 = ((buffer[2] as u32) << 16) | ((buffer[1] as u32) << 8) | (buffer[0] as u32);
state ^= calc_k(k);
}
2 => {
processed += 2;
let k: u32 = ((buffer[1] as u32) << 8) | (buffer[0] as u32);
state ^= calc_k(k);
}
1 => {
processed += 1;
let k: u32 = buffer[0] as u32;
state ^= calc_k(k);
}
0 => return Ok(finish(state, processed)),
_ => panic!("Internal buffer state failure"),
}
}
}
fn finish(state: u32, processed: u32) -> u32 {
let mut hash = state;
hash ^= processed as u32;
hash ^= hash.wrapping_shr(R1);
hash = hash.wrapping_mul(C1);
hash ^= hash.wrapping_shr(R2);
hash = hash.wrapping_mul(C2);
hash ^= hash.wrapping_shr(R1);
hash
}
fn calc_k(k: u32) -> u32 {
const C1: u32 = 0xcc9e_2d51;
const C2: u32 = 0x1b87_3593;
const R1: u32 = 15;
k.wrapping_mul(C1).rotate_left(R1).wrapping_mul(C2)
}