@@ -6,6 +6,28 @@ use std::ops::Deref;
66
77use siphasher:: sip128:: { Hasher128 , SipHasher13 } ;
88
9+ /// Produce a 128-bit hash of a value.
10+ #[ inline]
11+ pub fn hash < T : Hash > ( value : & T ) -> u128 {
12+ let mut state = SipHasher13 :: new ( ) ;
13+ value. hash ( & mut state) ;
14+ state. finish128 ( ) . as_u128 ( )
15+ }
16+
17+ /// Produce a 128-bit hash of a value's type and the value.
18+ ///
19+ /// Prefer this over `hash` if the resulting hash is used for the same purpose
20+ /// as hashes of other types.
21+ #[ inline]
22+ pub fn hash_any < T : Hash + ' static > ( item : & T ) -> u128 {
23+ // Also hash the TypeId because the type might be converted
24+ // through an unsized coercion.
25+ let mut state = SipHasher13 :: new ( ) ;
26+ item. type_id ( ) . hash ( & mut state) ;
27+ item. hash ( & mut state) ;
28+ state. finish128 ( ) . as_u128 ( )
29+ }
30+
931/// A wrapper type with precomputed hash.
1032///
1133/// This is useful if you want to pass large values of `T` to memoized
@@ -37,7 +59,7 @@ impl<T: Hash + 'static> Prehashed<T> {
3759 /// Compute an item's hash and wrap it.
3860 #[ inline]
3961 pub fn new ( item : T ) -> Self {
40- Self { hash : hash ( & item) , item }
62+ Self { hash : hash_any ( & item) , item }
4163 }
4264
4365 /// Return the wrapped value.
@@ -53,21 +75,11 @@ impl<T: Hash + 'static> Prehashed<T> {
5375 F : FnOnce ( & mut T ) -> U ,
5476 {
5577 let output = f ( & mut self . item ) ;
56- self . hash = hash ( & self . item ) ;
78+ self . hash = hash_any ( & self . item ) ;
5779 output
5880 }
5981}
6082
61- /// Hash the item.
62- fn hash < T : Hash + ' static > ( item : & T ) -> u128 {
63- // Also hash the TypeId because the type might be converted
64- // through an unsized coercion.
65- let mut state = SipHasher13 :: new ( ) ;
66- item. type_id ( ) . hash ( & mut state) ;
67- item. hash ( & mut state) ;
68- state. finish128 ( ) . as_u128 ( )
69- }
70-
7183impl < T : ?Sized > Deref for Prehashed < T > {
7284 type Target = T ;
7385
0 commit comments