Store hashes in special types so they aren't accidentally encoded as numbers
This commit is contained in:
parent
de96f3d873
commit
0445fbdd83
38 changed files with 274 additions and 138 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::stable_hasher;
|
||||
use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult};
|
||||
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
|
@ -9,32 +9,47 @@ mod tests;
|
|||
#[repr(C)]
|
||||
pub struct Fingerprint(u64, u64);
|
||||
|
||||
pub trait FingerprintComponent {
|
||||
fn as_u64(&self) -> u64;
|
||||
}
|
||||
|
||||
impl FingerprintComponent for Hash64 {
|
||||
fn as_u64(&self) -> u64 {
|
||||
Hash64::as_u64(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl FingerprintComponent for u64 {
|
||||
fn as_u64(&self) -> u64 {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl Fingerprint {
|
||||
pub const ZERO: Fingerprint = Fingerprint(0, 0);
|
||||
|
||||
#[inline]
|
||||
pub fn new(_0: u64, _1: u64) -> Fingerprint {
|
||||
Fingerprint(_0, _1)
|
||||
pub fn new<A, B>(_0: A, _1: B) -> Fingerprint
|
||||
where
|
||||
A: FingerprintComponent,
|
||||
B: FingerprintComponent,
|
||||
{
|
||||
Fingerprint(_0.as_u64(), _1.as_u64())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_smaller_hash(hash: u64) -> Fingerprint {
|
||||
Fingerprint(hash, hash)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_smaller_hash(&self) -> u64 {
|
||||
pub fn to_smaller_hash(&self) -> Hash64 {
|
||||
// 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 halves makes sure we get a good quality hash in such cases too.
|
||||
self.0.wrapping_mul(3).wrapping_add(self.1)
|
||||
Hash64::new(self.0.wrapping_mul(3).wrapping_add(self.1))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_value(&self) -> (u64, u64) {
|
||||
(self.0, self.1)
|
||||
pub fn split(&self) -> (Hash64, Hash64) {
|
||||
(Hash64::new(self.0), Hash64::new(self.1))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -131,9 +146,9 @@ impl FingerprintHasher for crate::unhash::Unhasher {
|
|||
}
|
||||
}
|
||||
|
||||
impl stable_hasher::StableHasherResult for Fingerprint {
|
||||
impl StableHasherResult for Fingerprint {
|
||||
#[inline]
|
||||
fn finish(hasher: stable_hasher::StableHasher) -> Self {
|
||||
fn finish(hasher: StableHasher) -> Self {
|
||||
let (_0, _1) = hasher.finalize();
|
||||
Fingerprint(_0, _1)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue