@@ -12,6 +12,8 @@ use std::collections::{HashMap, HashSet};
1212use std:: default:: Default ;
1313use std:: hash:: { Hasher , Hash , BuildHasherDefault } ;
1414use std:: ops:: BitXor ;
15+ use std:: mem:: size_of;
16+ use byteorder:: { ByteOrder , NativeEndian } ;
1517
1618pub type FxHashMap < K , V > = HashMap < K , V , BuildHasherDefault < FxHasher > > ;
1719pub type FxHashSet < V > = HashSet < V , BuildHasherDefault < FxHasher > > ;
@@ -37,6 +39,7 @@ pub fn FxHashSet<V: Hash + Eq>() -> FxHashSet<V> {
3739/// out-performs an FNV-based hash within rustc itself -- the collision rate is
3840/// similar or slightly worse than FNV, but the speed of the hash function
3941/// itself is much higher because it works on up to 8 bytes at a time.
42+ #[ derive( Copy , Clone ) ]
4043pub struct FxHasher {
4144 hash : usize
4245}
@@ -62,11 +65,30 @@ impl FxHasher {
6265
6366impl Hasher for FxHasher {
6467 #[ inline]
65- fn write ( & mut self , bytes : & [ u8 ] ) {
66- for byte in bytes {
67- let i = * byte;
68- self . add_to_hash ( i as usize ) ;
68+ fn write ( & mut self , mut bytes : & [ u8 ] ) {
69+ #[ cfg( target_pointer_width = "32" ) ]
70+ let read_usize = |bytes| NativeEndian :: read_u32 ( bytes) ;
71+ #[ cfg( target_pointer_width = "64" ) ]
72+ let read_usize = |bytes| NativeEndian :: read_u64 ( bytes) ;
73+
74+ let mut hash = * self ;
75+ assert ! ( size_of:: <usize >( ) <= 8 ) ;
76+ while bytes. len ( ) >= size_of :: < usize > ( ) {
77+ hash. add_to_hash ( read_usize ( bytes) as usize ) ;
78+ bytes = & bytes[ size_of :: < usize > ( ) ..] ;
6979 }
80+ if ( size_of :: < usize > ( ) > 4 ) && ( bytes. len ( ) >= 4 ) {
81+ hash. add_to_hash ( NativeEndian :: read_u32 ( bytes) as usize ) ;
82+ bytes = & bytes[ 4 ..] ;
83+ }
84+ if ( size_of :: < usize > ( ) > 2 ) && bytes. len ( ) >= 2 {
85+ hash. add_to_hash ( NativeEndian :: read_u16 ( bytes) as usize ) ;
86+ bytes = & bytes[ 2 ..] ;
87+ }
88+ if ( size_of :: < usize > ( ) > 1 ) && bytes. len ( ) >= 1 {
89+ hash. add_to_hash ( bytes[ 0 ] as usize ) ;
90+ }
91+ * self = hash;
7092 }
7193
7294 #[ inline]
0 commit comments