diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-08-18 17:56:55 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-09-06 07:27:22 -0400 |
| commit | 714f2a8921b1e686ae2ba02965fcd3b3e733e4c3 (patch) | |
| tree | 939dec652aa3eadf2721108843ded790d854b539 /src/librustc_data_structures | |
| parent | 4f5267dba31fdc49e436c50009fe33a80f21d477 (diff) | |
move fnv hashing support into librustc_data_structures
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/fnv.rs | 52 | ||||
| -rw-r--r-- | src/librustc_data_structures/lib.rs | 3 |
2 files changed, 55 insertions, 0 deletions
diff --git a/src/librustc_data_structures/fnv.rs b/src/librustc_data_structures/fnv.rs new file mode 100644 index 00000000000..77baa84c023 --- /dev/null +++ b/src/librustc_data_structures/fnv.rs @@ -0,0 +1,52 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::collections::{HashMap, HashSet}; +use std::collections::hash_state::DefaultState; +use std::default::Default; +use std::hash::{Hasher, Hash}; + +pub type FnvHashMap<K, V> = HashMap<K, V, DefaultState<FnvHasher>>; +pub type FnvHashSet<V> = HashSet<V, DefaultState<FnvHasher>>; + +#[allow(non_snake_case)] +pub fn FnvHashMap<K: Hash + Eq, V>() -> FnvHashMap<K, V> { + Default::default() +} + +#[allow(non_snake_case)] +pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> { + Default::default() +} + +/// 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 +pub struct FnvHasher(u64); + +impl Default for FnvHasher { + fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) } +} + +impl Hasher for FnvHasher { + fn write(&mut self, bytes: &[u8]) { + let FnvHasher(mut hash) = *self; + for byte in bytes { + hash = hash ^ (*byte as u64); + hash = hash.wrapping_mul(0x100000001b3); + } + *self = FnvHasher(hash); + } + fn finish(&self) -> u64 { self.0 } +} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 78edae76253..4688742a4ab 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -28,6 +28,8 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(rustc_private, staged_api)] +#![feature(hashmap_hasher)] + #![cfg_attr(test, feature(test))] #[macro_use] extern crate log; @@ -39,6 +41,7 @@ pub mod ivar; pub mod snapshot_vec; pub mod transitive_relation; pub mod unify; +pub mod fnv; // See comments in src/librustc/lib.rs #[doc(hidden)] |
