Skip to content

Instantly share code, notes, and snippets.

@badboy
Created October 28, 2014 13:26
Show Gist options
  • Save badboy/f5841a7963dd2fde0fce to your computer and use it in GitHub Desktop.
Save badboy/f5841a7963dd2fde0fce to your computer and use it in GitHub Desktop.
Port of the MurmurHash64A function from Redis.
// Port of the MurmurHash64A function from Redis.
// Original here: https://github.com/antirez/redis/blob/93eed9ae0163e328c33b16ab9ea3c4fbe0f98674/src/hyperloglog.c#L390-L439
extern crate test;
use std::os;
use test::Bencher;
fn murmur_hash64a(key: &[u8], seed: u64) -> u64 {
let m : u64 = 0xc6a4a7935bd1e995;
let r : uint = 47;
let len = key.len();
let mut h : u64 = seed ^ (len as u64 * m);
let endpos = len-(len&7);
let mut i = 0u;
while i != endpos {
let mut k : u64;
k = key[i+0] as u64;
k |= key[i+1] as u64 << 8;
k |= key[i+2] as u64 << 16;
k |= key[i+3] as u64 << 24;
k |= key[i+4] as u64 << 32;
k |= key[i+5] as u64 << 40;
k |= key[i+6] as u64 << 48;
k |= key[i+7] as u64 << 56;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
i += 8;
};
let over = len & 7;
if over == 7 { h ^= key[i+6] as u64 << 48; }
if over >= 6 { h ^= key[i+5] as u64 << 40; }
if over >= 5 { h ^= key[i+4] as u64 << 32; }
if over >= 4 { h ^= key[i+3] as u64 << 24; }
if over >= 3 { h ^= key[i+2] as u64 << 16; }
if over >= 2 { h ^= key[i+1] as u64 << 8; }
if over >= 1 { h ^= key[i+0] as u64; }
if over > 0 { h *= m; }
h ^= h >> r;
h *= m;
h ^= h >> r;
h
}
fn main() {
let args = os::args();
if args.len() != 3 {
println!("Usage: {} key seed", args[0]);
return
}
let key = args[1].clone();
let seed : u64 = from_str(args[2].as_slice()).unwrap();
println!("{:x}", murmur_hash64a(key.as_bytes(), seed));
}
#[bench]
fn benchmark_murmur(b: &mut Bencher) {
let key = "lorem ipsum dolor sit amet".as_bytes();
let seed = 0xadc83b19;
b.iter(|| {
murmur_hash64a(key, seed);
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment