about summary refs log tree commit diff
path: root/src/librustc_data_structures
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-08-18 17:56:55 -0400
committerNiko Matsakis <niko@alum.mit.edu>2015-09-06 07:27:22 -0400
commit714f2a8921b1e686ae2ba02965fcd3b3e733e4c3 (patch)
tree939dec652aa3eadf2721108843ded790d854b539 /src/librustc_data_structures
parent4f5267dba31fdc49e436c50009fe33a80f21d477 (diff)
move fnv hashing support into librustc_data_structures
Diffstat (limited to 'src/librustc_data_structures')
-rw-r--r--src/librustc_data_structures/fnv.rs52
-rw-r--r--src/librustc_data_structures/lib.rs3
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)]