diff --git a/.gitignore b/.gitignore index 53eaa21..84c47ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target **/*.rs.bk +/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 0c64114..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "rustc-hash" -version = "0.1.0" - diff --git a/Cargo.toml b/Cargo.toml index 8b24709..9eb26f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustc-hash" -version = "1.0.0" +version = "1.0.1" authors = ["The Rust Project Developers"] description = "speed, non-cryptographic hash used in rustc" license = "Apache-2.0/MIT" @@ -9,3 +9,4 @@ keywords = ["hash", "fxhash", "rustc"] repository = "https://github.com/rust-lang-nursery/rustc-hash" [dependencies] +byteorder = "1.1" diff --git a/src/lib.rs b/src/lib.rs index ec592f9..b3875cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,10 +18,15 @@ //! map.insert(22, 44); //! ``` +extern crate byteorder; + use std::collections::{HashMap, HashSet}; use std::default::Default; use std::hash::{Hasher, BuildHasherDefault}; use std::ops::BitXor; +use std::mem::size_of; + +use byteorder::{ByteOrder, NativeEndian}; /// Type alias for a hashmap using the `fx` hash algorithm. pub type FxHashMap = HashMap>; @@ -65,11 +70,30 @@ impl FxHasher { impl Hasher for FxHasher { #[inline] - fn write(&mut self, bytes: &[u8]) { - for byte in bytes { - let i = *byte; - self.add_to_hash(i as usize); + fn write(&mut self, mut bytes: &[u8]) { + #[cfg(target_pointer_width = "32")] + let read_usize = |bytes| NativeEndian::read_u32(bytes); + #[cfg(target_pointer_width = "64")] + let read_usize = |bytes| NativeEndian::read_u64(bytes); + + let mut hash = FxHasher { hash: self.hash }; + assert!(size_of::() <= 8); + while bytes.len() >= size_of::() { + hash.add_to_hash(read_usize(bytes) as usize); + bytes = &bytes[size_of::()..]; + } + if (size_of::() > 4) && (bytes.len() >= 4) { + hash.add_to_hash(NativeEndian::read_u32(bytes) as usize); + bytes = &bytes[4..]; + } + if (size_of::() > 2) && bytes.len() >= 2 { + hash.add_to_hash(NativeEndian::read_u16(bytes) as usize); + bytes = &bytes[2..]; + } + if (size_of::() > 1) && bytes.len() >= 1 { + hash.add_to_hash(bytes[0] as usize); } + self.hash = hash.hash; } #[inline]