Let a portion of DefPathHash uniquely identify the DefPath's crate.
This allows to directly map from a DefPathHash to the crate it originates from, without constructing side tables to do that mapping. It also allows to reliably and cheaply check for DefPathHash collisions.
This commit is contained in:
parent
a3ed564c13
commit
22d489be76
12 changed files with 181 additions and 27 deletions
|
@ -7,11 +7,17 @@ use std::hash::{Hash, Hasher};
|
|||
use std::mem::{self, MaybeUninit};
|
||||
|
||||
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Fingerprint(u64, u64);
|
||||
|
||||
impl Fingerprint {
|
||||
pub const ZERO: Fingerprint = Fingerprint(0, 0);
|
||||
|
||||
#[inline]
|
||||
pub fn new(_0: u64, _1: u64) -> Fingerprint {
|
||||
Fingerprint(_0, _1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_smaller_hash(hash: u64) -> Fingerprint {
|
||||
Fingerprint(hash, hash)
|
||||
|
@ -19,7 +25,12 @@ impl Fingerprint {
|
|||
|
||||
#[inline]
|
||||
pub fn to_smaller_hash(&self) -> u64 {
|
||||
self.0
|
||||
// Even though both halves of the fingerprint are expected to be good
|
||||
// quality hash values, let's still combine the two values because the
|
||||
// Fingerprints in DefPathHash have the StableCrateId portion which is
|
||||
// the same for all DefPathHashes from the same crate. Combining the
|
||||
// two halfs makes sure we get a good quality hash in such cases too.
|
||||
self.0.wrapping_mul(3).wrapping_add(self.1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -93,7 +104,7 @@ impl FingerprintHasher for crate::unhash::Unhasher {
|
|||
#[inline]
|
||||
fn write_fingerprint(&mut self, fingerprint: &Fingerprint) {
|
||||
// `Unhasher` only wants a single `u64`
|
||||
self.write_u64(fingerprint.0);
|
||||
self.write_u64(fingerprint.0.wrapping_add(fingerprint.1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue