1
Fork 0

Store hashes in special types so they aren't accidentally encoded as numbers

This commit is contained in:
Ben Kimock 2023-04-07 23:11:20 -04:00
parent de96f3d873
commit 0445fbdd83
38 changed files with 274 additions and 138 deletions

View file

@ -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)
}