alt_std/
hash.rs

1pub trait Hash {
2    fn hash(&self) -> usize;
3}
4
5impl Hash for &[u8] {
6    fn hash(&self) -> usize {
7        murmurHash64A(self, 0xcae4f57) as usize
8    }
9}
10
11// from: https://github.com/antirez/redis/blob/unstable/src/hyperloglog.c
12// Copyright 2014 (c) Salvatore Sanfilippo <antirez at gmail dot com> - 3-Clause BSD license
13/* Our hash function is MurmurHash2, 64 bit version.
14 * It was modified for Redis in order to provide the same result in
15 * big and little endian archs (endian neutral). */
16pub fn murmurHash64A (key: &[u8], seed: u64) -> u64 {
17    let m = 0xc6a4a7935bd1e995;
18    let r = 47;
19    let mut h = seed ^ ((key.len() as u64).wrapping_mul(m));
20    let mut i = 0;
21    let len = key.len() & 7;
22
23    let end = key.len() - len;
24
25    while i < end {
26        let mut k = key[i + 0] as u64;
27        k |= (key[i + 1] as u64) << 8;
28        k |= (key[i + 2] as u64) << 16;
29        k |= (key[i + 3] as u64) << 24;
30        k |= (key[i + 4] as u64) << 32;
31        k |= (key[i + 5] as u64) << 40;
32        k |= (key[i + 6] as u64) << 48;
33        k |= (key[i + 7] as u64) << 56;
34
35        k = k.wrapping_mul(m);
36        k ^= k >> r;
37        k = k.wrapping_mul(m);
38        h ^= k;
39        h = h.wrapping_mul(m);
40        i += 8;
41    }
42
43    let shifts  = [0, 8, 16, 24, 32, 40, 48];
44    let offsets = [0, 1, 2, 3, 4, 5, 6];
45    if len != 0 {
46        for i in 0..len {
47            let idx = len - i - 1;
48            h ^= (key[end + offsets[idx]] as u64) << shifts[idx];
49        }
50        h = h.wrapping_mul(m);
51    }
52
53    h ^= h >> r;
54    h = h.wrapping_mul(m);
55    h ^= h >> r;
56    h
57}