|
18 | 18 | //! map.insert(22, 44);
|
19 | 19 | //! ```
|
20 | 20 |
|
| 21 | +extern crate byteorder; |
| 22 | + |
21 | 23 | use std::collections::{HashMap, HashSet};
|
22 | 24 | use std::default::Default;
|
23 | 25 | use std::hash::{Hasher, BuildHasherDefault};
|
24 | 26 | use std::ops::BitXor;
|
| 27 | +use std::mem::size_of; |
| 28 | + |
| 29 | +use byteorder::{ByteOrder, NativeEndian}; |
25 | 30 |
|
26 | 31 | /// Type alias for a hashmap using the `fx` hash algorithm.
|
27 | 32 | pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
|
@@ -65,11 +70,30 @@ impl FxHasher {
|
65 | 70 |
|
66 | 71 | impl Hasher for FxHasher {
|
67 | 72 | #[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); |
72 | 95 | }
|
| 96 | + self.hash = hash.hash; |
73 | 97 | }
|
74 | 98 |
|
75 | 99 | #[inline]
|
|
0 commit comments