]> git.lizzy.rs Git - rust.git/blob - src/librustc/util/nodemap.rs
Auto merge of #22541 - Manishearth:rollup, r=Gankro
[rust.git] / src / librustc / util / nodemap.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! An efficient hash map for node IDs
12
13 #![allow(non_snake_case)]
14
15 use std::collections::hash_state::{DefaultState};
16 use std::collections::{HashMap, HashSet};
17 use std::default::Default;
18 use std::hash::{Hasher, Hash};
19 #[cfg(stage0)] use std::hash::Writer;
20 use syntax::ast;
21
22 pub type FnvHashMap<K, V> = HashMap<K, V, DefaultState<FnvHasher>>;
23 pub type FnvHashSet<V> = HashSet<V, DefaultState<FnvHasher>>;
24
25 pub type NodeMap<T> = FnvHashMap<ast::NodeId, T>;
26 pub type DefIdMap<T> = FnvHashMap<ast::DefId, T>;
27
28 pub type NodeSet = FnvHashSet<ast::NodeId>;
29 pub type DefIdSet = FnvHashSet<ast::DefId>;
30
31 #[cfg(stage0)]
32 pub fn FnvHashMap<K: Hash<FnvHasher> + Eq, V>() -> FnvHashMap<K, V> {
33     Default::default()
34 }
35 #[cfg(stage0)]
36 pub fn FnvHashSet<V: Hash<FnvHasher> + Eq>() -> FnvHashSet<V> {
37     Default::default()
38 }
39 #[cfg(not(stage0))]
40 pub fn FnvHashMap<K: Hash + Eq, V>() -> FnvHashMap<K, V> {
41     Default::default()
42 }
43 #[cfg(not(stage0))]
44 pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> {
45     Default::default()
46 }
47
48 pub fn NodeMap<T>() -> NodeMap<T> { FnvHashMap() }
49 pub fn DefIdMap<T>() -> DefIdMap<T> { FnvHashMap() }
50 pub fn NodeSet() -> NodeSet { FnvHashSet() }
51 pub fn DefIdSet() -> DefIdSet { FnvHashSet() }
52
53 /// A speedy hash algorithm for node ids and def ids. The hashmap in
54 /// libcollections by default uses SipHash which isn't quite as speedy as we
55 /// want. In the compiler we're not really worried about DOS attempts, so we
56 /// just default to a non-cryptographic hash.
57 ///
58 /// This uses FNV hashing, as described here:
59 /// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
60 pub struct FnvHasher(u64);
61
62 impl Default for FnvHasher {
63     fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
64 }
65
66 #[cfg(stage0)]
67 impl Hasher for FnvHasher {
68     type Output = u64;
69     fn reset(&mut self) { *self = Default::default(); }
70     fn finish(&self) -> u64 { self.0 }
71 }
72
73 #[cfg(stage0)]
74 impl Writer for FnvHasher {
75     fn write(&mut self, bytes: &[u8]) {
76         let FnvHasher(mut hash) = *self;
77         for byte in bytes {
78             hash = hash ^ (*byte as u64);
79             hash = hash * 0x100000001b3;
80         }
81         *self = FnvHasher(hash);
82     }
83 }
84
85 #[cfg(not(stage0))]
86 impl Hasher for FnvHasher {
87     fn write(&mut self, bytes: &[u8]) {
88         let FnvHasher(mut hash) = *self;
89         for byte in bytes {
90             hash = hash ^ (*byte as u64);
91             hash = hash * 0x100000001b3;
92         }
93         *self = FnvHasher(hash);
94     }
95     fn finish(&self) -> u64 { self.0 }
96 }