Skip to content

Commit 970081f

Browse files
Zoxcmichaelwoerister
authored andcommitted
Hash up to 8 bytes at once with FxHasher
1 parent abd3d05 commit 970081f

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

Cargo.lock

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ keywords = ["hash", "fxhash", "rustc"]
99
repository = "https://github.com/rust-lang-nursery/rustc-hash"
1010

1111
[dependencies]
12+
byteorder = "1.1"

src/lib.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818
//! map.insert(22, 44);
1919
//! ```
2020
21+
extern crate byteorder;
22+
2123
use std::collections::{HashMap, HashSet};
2224
use std::default::Default;
2325
use std::hash::{Hasher, BuildHasherDefault};
2426
use std::ops::BitXor;
27+
use std::mem::size_of;
28+
29+
use byteorder::{ByteOrder, NativeEndian};
2530

2631
/// Type alias for a hashmap using the `fx` hash algorithm.
2732
pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
@@ -65,11 +70,30 @@ impl FxHasher {
6570

6671
impl Hasher for FxHasher {
6772
#[inline]
68-
fn write(&mut self, bytes: &[u8]) {
69-
for byte in bytes {
70-
let i = *byte;
71-
self.add_to_hash(i as usize);
73+
fn write(&mut self, mut bytes: &[u8]) {
74+
#[cfg(target_pointer_width = "32")]
75+
let read_usize = |bytes| NativeEndian::read_u32(bytes);
76+
#[cfg(target_pointer_width = "64")]
77+
let read_usize = |bytes| NativeEndian::read_u64(bytes);
78+
79+
let mut hash = FxHasher { hash: self.hash };
80+
assert!(size_of::<usize>() <= 8);
81+
while bytes.len() >= size_of::<usize>() {
82+
hash.add_to_hash(read_usize(bytes) as usize);
83+
bytes = &bytes[size_of::<usize>()..];
84+
}
85+
if (size_of::<usize>() > 4) && (bytes.len() >= 4) {
86+
hash.add_to_hash(NativeEndian::read_u32(bytes) as usize);
87+
bytes = &bytes[4..];
88+
}
89+
if (size_of::<usize>() > 2) && bytes.len() >= 2 {
90+
hash.add_to_hash(NativeEndian::read_u16(bytes) as usize);
91+
bytes = &bytes[2..];
92+
}
93+
if (size_of::<usize>() > 1) && bytes.len() >= 1 {
94+
hash.add_to_hash(bytes[0] as usize);
7295
}
96+
self.hash = hash.hash;
7397
}
7498

7599
#[inline]

0 commit comments

Comments
 (0)