It's easy to see that FxHasher { hash: 0 }.add_to_hash(0) is a fixed point (i.e. does not result in any change to the internal state self.hash):
|
impl FxHasher { |
|
#[inline] |
|
fn add_to_hash(&mut self, i: usize) { |
|
self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K); |
|
} |
|
} |
In particular 0.rotate_left(5).bitxor(0).wrapping_mul(K) == 0.
Therefore initialising FxHasher with a hash value of 0 is a bit undesirable, as sequences of 0s (written to the hash before any non-zero value) cannot be distinguished by their hashes.
|
impl Default for FxHasher { |
|
#[inline] |
|
fn default() -> FxHasher { |
|
FxHasher { hash: 0 } |
|
} |
|
} |
Of course, there's always the possibility that a value of self.hash.rotate_left(5) could be written to the hasher, which will result in the internal state reaching 0—but in practice writing values of 0 can arise quite often, and choosing some other initial value would be quite beneficial? Perhaps even K?
It's easy to see that
FxHasher { hash: 0 }.add_to_hash(0)is a fixed point (i.e. does not result in any change to the internal stateself.hash):rustc-hash/src/lib.rs
Lines 76 to 81 in 5e09ea0
In particular
0.rotate_left(5).bitxor(0).wrapping_mul(K) == 0.Therefore initialising
FxHasherwith ahashvalue of0is a bit undesirable, as sequences of0s (written to the hash before any non-zero value) cannot be distinguished by their hashes.rustc-hash/src/lib.rs
Lines 69 to 74 in 5e09ea0
Of course, there's always the possibility that a value of
self.hash.rotate_left(5)could be written to the hasher, which will result in the internal state reaching0—but in practice writing values of0can arise quite often, and choosing some other initial value would be quite beneficial? Perhaps evenK?