Skip to content

Commit

Permalink
Use in-memory representation for Fingerprint that is more amenable to…
Browse files Browse the repository at this point in the history
… hashing.
  • Loading branch information
michaelwoerister committed May 18, 2017
1 parent 6af8c6c commit 474cc91
Showing 1 changed file with 26 additions and 46 deletions.
72 changes: 26 additions & 46 deletions src/librustc/ich/fingerprint.rs
Expand Up @@ -10,95 +10,75 @@

use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
use rustc_data_structures::stable_hasher;
use rustc_data_structures::ToHex;

const FINGERPRINT_LENGTH: usize = 16;
use std::mem;
use std::slice;

#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]);
pub struct Fingerprint(u64, u64);

impl Fingerprint {
#[inline]
pub fn zero() -> Fingerprint {
Fingerprint([0; FINGERPRINT_LENGTH])
Fingerprint(0, 0)
}

#[inline]
pub fn from_smaller_hash(hash: u64) -> Fingerprint {
let mut result = Fingerprint::zero();
result.0[0] = (hash >> 0) as u8;
result.0[1] = (hash >> 8) as u8;
result.0[2] = (hash >> 16) as u8;
result.0[3] = (hash >> 24) as u8;
result.0[4] = (hash >> 32) as u8;
result.0[5] = (hash >> 40) as u8;
result.0[6] = (hash >> 48) as u8;
result.0[7] = (hash >> 56) as u8;
result
Fingerprint(hash, hash)
}

#[inline]
pub fn to_smaller_hash(&self) -> u64 {
((self.0[0] as u64) << 0) |
((self.0[1] as u64) << 8) |
((self.0[2] as u64) << 16) |
((self.0[3] as u64) << 24) |
((self.0[4] as u64) << 32) |
((self.0[5] as u64) << 40) |
((self.0[6] as u64) << 48) |
((self.0[7] as u64) << 56)
self.0
}

pub fn to_hex(&self) -> String {
self.0.to_hex()
format!("{:x}{:x}", self.0, self.1)
}
}

impl Encodable for Fingerprint {
#[inline]
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
for &byte in &self.0 {
s.emit_u8(byte)?;
}
Ok(())
s.emit_u64(self.0.to_le())?;
s.emit_u64(self.1.to_le())
}
}

impl Decodable for Fingerprint {
#[inline]
fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]);
for byte in &mut result.0 {
*byte = d.read_u8()?;
}
Ok(result)
let _0 = u64::from_le(d.read_u64()?);
let _1 = u64::from_le(d.read_u64()?);
Ok(Fingerprint(_0, _1))
}
}

impl ::std::fmt::Display for Fingerprint {
fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
for i in 0 .. self.0.len() {
if i > 0 {
write!(formatter, "::")?;
}

write!(formatter, "{}", self.0[i])?;
}
Ok(())
write!(formatter, "{:x}-{:x}", self.0, self.1)
}
}


impl stable_hasher::StableHasherResult for Fingerprint {
fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
let mut fingerprint = Fingerprint::zero();
fingerprint.0.copy_from_slice(hasher.finalize());
fingerprint
let hash_bytes: &[u8] = hasher.finalize();

assert!(hash_bytes.len() >= mem::size_of::<u64>() * 2);
let hash_bytes: &[u64] = unsafe {
slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2)
};

// The bytes returned bytes the Blake2B hasher are always little-endian.
Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1]))
}
}

impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint {
#[inline]
fn hash_stable<W: stable_hasher::StableHasherResult>(&self,
_: &mut CTX,
hasher: &mut stable_hasher::StableHasher<W>) {
::std::hash::Hash::hash(&self.0, hasher);
::std::hash::Hash::hash(self, hasher);
}
}

0 comments on commit 474cc91

Please sign in to comment.