diff options
Diffstat (limited to 'components/util/fnv.rs')
-rw-r--r-- | components/util/fnv.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/components/util/fnv.rs b/components/util/fnv.rs new file mode 100644 index 00000000000..a14f3ea2bec --- /dev/null +++ b/components/util/fnv.rs @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! This file stolen wholesale from rustc/src/librustc/util/nodemap.rs + +pub use std::hash::{Hash, Hasher, Writer}; + +/// A speedy hash algorithm for node ids and def ids. The hashmap in +/// libcollections by default uses SipHash which isn't quite as speedy as we +/// want. In the compiler we're not really worried about DOS attempts, so we +/// just default to a non-cryptographic hash. +/// +/// This uses FNV hashing, as described here: +/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function +#[deriving(Clone)] +pub struct FnvHasher; + +pub struct FnvState(u64); + +impl Hasher<FnvState> for FnvHasher { + fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 { + let mut state = FnvState(0xcbf29ce484222325); + t.hash(&mut state); + let FnvState(ret) = state; + return ret; + } +} + +impl Writer for FnvState { + fn write(&mut self, bytes: &[u8]) { + let FnvState(mut hash) = *self; + for byte in bytes.iter() { + hash = hash ^ (*byte as u64); + hash = hash * 0x100000001b3; + } + *self = FnvState(hash); + } +} + +#[inline(always)] +pub fn hash<T: Hash<FnvState>>(t: &T) -> u64 { + let s = FnvHasher; + s.hash(t) +} |