Skip to content

Instantly share code, notes, and snippets.

@EddieIvan01
Created December 31, 2020 08:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EddieIvan01/17939c44b52a7572f4c4bf21a615f2a6 to your computer and use it in GitHub Desktop.
Save EddieIvan01/17939c44b52a7572f4c4bf21a615f2a6 to your computer and use it in GitHub Desktop.
They all used unsafe raw pointer operations, so they are more fast then existing Rust implementations (2020.12.31)
fn fmix32(mut h: u32) -> u32 {
h ^= h >> 16;
h = h.wrapping_mul(0x85ebca6b);
h ^= h >> 13;
h = h.wrapping_mul(0xc2b2ae35);
h ^= h >> 16;
h
}
fn get_32_block(ptr: *const u8) -> u32 {
unsafe { *mem::transmute::<*const u8, *const u32>(ptr) }
}
fn murmurhash3_x86_32(bs: &[u8]) -> u32 {
let len = bs.len() as u32;
let rem = len & 3;
let mut ptr = bs.as_ptr();
let mut h = 0xf1f2f3f4;
let _: Vec<_> = (0..(len >> 2))
.map(|_| unsafe {
let mut k = get_32_block(ptr);
k = k.wrapping_mul(0xcc9e2d51);
k = k.rotate_left(15);
k = k.wrapping_mul(0x1b873593);
h ^= k;
h = h.rotate_left(13);
h = h.wrapping_mul(5);
h = h.wrapping_add(0xe6546b64);
ptr = ptr.offset(4);
})
.collect();
let mut k = 0u32;
if rem == 3 {
k ^= unsafe { (*ptr.offset(2) as u32) << 16 };
}
if rem >= 2 {
k ^= unsafe { (*ptr.offset(1) as u32) << 8 };
}
if rem >= 1 {
k ^= unsafe { *ptr.offset(0) as u32 };
k = k.wrapping_mul(0xcc9e2d51);
k = k.rotate_left(15);
k = k.wrapping_mul(0x1b873593);
h ^= k;
}
h ^= bs.len() as u32;
h = fmix32(h);
return h;
}
fn get16bits(ptr: *const u8) -> Wrapping<u32> {
unsafe { Wrapping(*mem::transmute::<*const u8, *const u16>(ptr) as u32) }
}
fn super_fast_hash(s: &str) -> u32 {
let len = s.len() as u32;
if len == 0 {
return 0;
}
let rem = len & 3;
let mut hsh = Wrapping(len);
let mut tmp = Wrapping(0_u32);
let mut ptr = s.as_ptr();
let _: Vec<_> = (0..(len >> 2))
.map(|_| unsafe {
hsh += get16bits(ptr);
tmp = (get16bits(ptr.offset(2)) << 11) ^ hsh;
hsh = (hsh << 16) ^ tmp;
ptr = ptr.offset(4);
hsh += hsh >> 11;
})
.collect();
match rem {
1 => unsafe {
hsh += Wrapping(*ptr as u32);
hsh ^= hsh << 10;
hsh += hsh >> 1;
},
2 => {
hsh += get16bits(ptr);
hsh ^= hsh << 11;
hsh += hsh >> 17;
}
3 => unsafe {
hsh += get16bits(ptr);
hsh ^= hsh << 16;
hsh ^= Wrapping(*ptr.offset(2) as u32) << 18;
hsh += hsh >> 11;
},
_ => (),
}
hsh ^= hsh << 3;
hsh += hsh >> 5;
hsh ^= hsh << 4;
hsh += hsh >> 17;
hsh ^= hsh << 25;
hsh += hsh >> 6;
hsh.0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment