Skip to content

Instantly share code, notes, and snippets.

@AlexApps99
Created Sep 21, 2021
Embed
What would you like to do?
#[inline]
const fn add_to_hash(hash: u64, i: u64) -> u64 {
(hash.rotate_left(5) ^ i).wrapping_mul(0x517cc1b727220a95)
}
/// A const implementation of [`rustc_hash::FxHasher`]
pub const fn fxhash(v: &str) -> u64 {
let mut hash: u64 = 0;
let bytes = v.as_bytes();
let l = bytes.len();
let mut i = 0;
while l - i >= 8 {
hash = add_to_hash(
hash,
u64::from_ne_bytes([
bytes[i],
bytes[i + 1],
bytes[i + 2],
bytes[i + 3],
bytes[i + 4],
bytes[i + 5],
bytes[i + 6],
bytes[i + 7],
]),
);
i += 8;
}
if l - i >= 4 {
hash = add_to_hash(
hash,
u32::from_ne_bytes([bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3]]) as u64,
);
i += 4;
}
if l - i >= 2 {
hash = add_to_hash(hash, u16::from_ne_bytes([bytes[i], bytes[i + 1]]) as u64);
i += 2;
}
if l - i >= 1 {
hash = add_to_hash(hash, bytes[i] as u64);
}
add_to_hash(hash, 0xff)
}
#[cfg(test)]
fn fxhash_test(name: &str) {
use std::hash::{Hash, Hasher};
let mut hasher = rustc_hash::FxHasher::default();
name.hash(&mut hasher);
assert_eq!(hasher.finish(), fxhash(name));
}
#[test]
fn test_const_fxhash() {
fxhash_test("");
fxhash_test("0");
fxhash_test("01");
fxhash_test("012");
fxhash_test("0123");
fxhash_test("01234");
fxhash_test("012345");
fxhash_test("0123456");
fxhash_test("01234567");
fxhash_test("012345678");
fxhash_test("0123456789");
fxhash_test("01234567890");
fxhash_test("012345678901");
fxhash_test("0123456789012");
fxhash_test("01234567890123");
fxhash_test("012345678901234");
fxhash_test("0123456789012345");
fxhash_test("01234567890123456");
fxhash_test("012345678901234567");
fxhash_test("0123456789012345678");
fxhash_test("01234567890123456789");
fxhash_test("012345678901234567890");
fxhash_test("0123456789012345678901");
fxhash_test("01234567890123456789012");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment