]> git.lizzy.rs Git - rust.git/blob - src/librustc/util/nodemap.rs
auto merge of #13049 : alexcrichton/rust/io-fill, r=huonw
[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 use collections::{HashMap, HashSet};
14 use std::hash::{Hasher, Hash};
15 use std::io;
16 use syntax::ast;
17
18 pub type FnvHashMap<K, V> = HashMap<K, V, FnvHasher>;
19
20 pub type NodeMap<T> = FnvHashMap<ast::NodeId, T>;
21 pub type DefIdMap<T> = FnvHashMap<ast::DefId, T>;
22
23 pub type NodeSet = HashSet<ast::NodeId, FnvHasher>;
24 pub type DefIdSet = HashSet<ast::DefId, FnvHasher>;
25
26 // Hacks to get good names
27 pub mod FnvHashMap {
28     use std::hash::Hash;
29     use collections::HashMap;
30     pub fn new<K: Hash<super::FnvState> + TotalEq, V>() -> super::FnvHashMap<K, V> {
31         HashMap::with_hasher(super::FnvHasher)
32     }
33 }
34 pub mod NodeMap {
35     pub fn new<T>() -> super::NodeMap<T> {
36         super::FnvHashMap::new()
37     }
38 }
39 pub mod DefIdMap {
40     pub fn new<T>() -> super::DefIdMap<T> {
41         super::FnvHashMap::new()
42     }
43 }
44 pub mod NodeSet {
45     use collections::HashSet;
46     pub fn new() -> super::NodeSet {
47         HashSet::with_hasher(super::FnvHasher)
48     }
49 }
50 pub mod DefIdSet {
51     use collections::HashSet;
52     pub fn new() -> super::DefIdSet {
53         HashSet::with_hasher(super::FnvHasher)
54     }
55 }
56
57 /// A speedy hash algorithm for node ids and def ids. The hashmap in
58 /// libcollections by default uses SipHash which isn't quite as speedy as we
59 /// want. In the compiler we're not really worried about DOS attempts, so we
60 /// just default to a non-cryptographic hash.
61 ///
62 /// This uses FNV hashing, as described here:
63 /// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
64 #[deriving(Clone)]
65 pub struct FnvHasher;
66
67 pub struct FnvState(u64);
68
69 impl Hasher<FnvState> for FnvHasher {
70     fn hash<T: Hash<FnvState>>(&self, t: &T) -> u64 {
71         let mut state = FnvState(0xcbf29ce484222325);
72         t.hash(&mut state);
73         let FnvState(ret) = state;
74         return ret;
75     }
76 }
77
78 impl Writer for FnvState {
79     fn write(&mut self, bytes: &[u8]) -> io::IoResult<()> {
80         let FnvState(mut hash) = *self;
81         for byte in bytes.iter() {
82             hash = hash ^ (*byte as u64);
83             hash = hash * 0x100000001b3;
84         }
85         *self = FnvState(hash);
86         Ok(())
87     }
88 }