|  | 
| 10 | 10 | 
 | 
| 11 | 11 | use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; | 
| 12 | 12 | use rustc_data_structures::stable_hasher; | 
| 13 |  | -use rustc_data_structures::ToHex; | 
| 14 |  | - | 
| 15 |  | -const FINGERPRINT_LENGTH: usize = 16; | 
|  | 13 | +use std::mem; | 
|  | 14 | +use std::slice; | 
| 16 | 15 | 
 | 
| 17 | 16 | #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] | 
| 18 |  | -pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]); | 
|  | 17 | +pub struct Fingerprint(u64, u64); | 
| 19 | 18 | 
 | 
| 20 | 19 | impl Fingerprint { | 
| 21 | 20 |     #[inline] | 
| 22 | 21 |     pub fn zero() -> Fingerprint { | 
| 23 |  | -        Fingerprint([0; FINGERPRINT_LENGTH]) | 
|  | 22 | +        Fingerprint(0, 0) | 
| 24 | 23 |     } | 
| 25 | 24 | 
 | 
|  | 25 | +    #[inline] | 
| 26 | 26 |     pub fn from_smaller_hash(hash: u64) -> Fingerprint { | 
| 27 |  | -        let mut result = Fingerprint::zero(); | 
| 28 |  | -        result.0[0] = (hash >>  0) as u8; | 
| 29 |  | -        result.0[1] = (hash >>  8) as u8; | 
| 30 |  | -        result.0[2] = (hash >> 16) as u8; | 
| 31 |  | -        result.0[3] = (hash >> 24) as u8; | 
| 32 |  | -        result.0[4] = (hash >> 32) as u8; | 
| 33 |  | -        result.0[5] = (hash >> 40) as u8; | 
| 34 |  | -        result.0[6] = (hash >> 48) as u8; | 
| 35 |  | -        result.0[7] = (hash >> 56) as u8; | 
| 36 |  | -        result | 
|  | 27 | +        Fingerprint(hash, hash) | 
| 37 | 28 |     } | 
| 38 | 29 | 
 | 
|  | 30 | +    #[inline] | 
| 39 | 31 |     pub fn to_smaller_hash(&self) -> u64 { | 
| 40 |  | -        ((self.0[0] as u64) <<  0) | | 
| 41 |  | -        ((self.0[1] as u64) <<  8) | | 
| 42 |  | -        ((self.0[2] as u64) << 16) | | 
| 43 |  | -        ((self.0[3] as u64) << 24) | | 
| 44 |  | -        ((self.0[4] as u64) << 32) | | 
| 45 |  | -        ((self.0[5] as u64) << 40) | | 
| 46 |  | -        ((self.0[6] as u64) << 48) | | 
| 47 |  | -        ((self.0[7] as u64) << 56) | 
|  | 32 | +        self.0 | 
| 48 | 33 |     } | 
| 49 | 34 | 
 | 
| 50 | 35 |     pub fn to_hex(&self) -> String { | 
| 51 |  | -        self.0.to_hex() | 
|  | 36 | +        format!("{:x}{:x}", self.0, self.1) | 
| 52 | 37 |     } | 
| 53 | 38 | } | 
| 54 | 39 | 
 | 
| 55 | 40 | impl Encodable for Fingerprint { | 
| 56 | 41 |     #[inline] | 
| 57 | 42 |     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | 
| 58 |  | -        for &byte in &self.0 { | 
| 59 |  | -            s.emit_u8(byte)?; | 
| 60 |  | -        } | 
| 61 |  | -        Ok(()) | 
|  | 43 | +        s.emit_u64(self.0.to_le())?; | 
|  | 44 | +        s.emit_u64(self.1.to_le()) | 
| 62 | 45 |     } | 
| 63 | 46 | } | 
| 64 | 47 | 
 | 
| 65 | 48 | impl Decodable for Fingerprint { | 
| 66 | 49 |     #[inline] | 
| 67 | 50 |     fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> { | 
| 68 |  | -        let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]); | 
| 69 |  | -        for byte in &mut result.0 { | 
| 70 |  | -            *byte = d.read_u8()?; | 
| 71 |  | -        } | 
| 72 |  | -        Ok(result) | 
|  | 51 | +        let _0 = u64::from_le(d.read_u64()?); | 
|  | 52 | +        let _1 = u64::from_le(d.read_u64()?); | 
|  | 53 | +        Ok(Fingerprint(_0, _1)) | 
| 73 | 54 |     } | 
| 74 | 55 | } | 
| 75 | 56 | 
 | 
| 76 | 57 | impl ::std::fmt::Display for Fingerprint { | 
| 77 | 58 |     fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { | 
| 78 |  | -        for i in 0 .. self.0.len() { | 
| 79 |  | -            if i > 0 { | 
| 80 |  | -                write!(formatter, "::")?; | 
| 81 |  | -            } | 
| 82 |  | - | 
| 83 |  | -            write!(formatter, "{}", self.0[i])?; | 
| 84 |  | -        } | 
| 85 |  | -        Ok(()) | 
|  | 59 | +        write!(formatter, "{:x}-{:x}", self.0, self.1) | 
| 86 | 60 |     } | 
| 87 | 61 | } | 
| 88 | 62 | 
 | 
| 89 |  | - | 
| 90 | 63 | impl stable_hasher::StableHasherResult for Fingerprint { | 
| 91 | 64 |     fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self { | 
| 92 |  | -        let mut fingerprint = Fingerprint::zero(); | 
| 93 |  | -        fingerprint.0.copy_from_slice(hasher.finalize()); | 
| 94 |  | -        fingerprint | 
|  | 65 | +        let hash_bytes: &[u8] = hasher.finalize(); | 
|  | 66 | + | 
|  | 67 | +        assert!(hash_bytes.len() >= mem::size_of::<u64>() * 2); | 
|  | 68 | +        let hash_bytes: &[u64] = unsafe { | 
|  | 69 | +            slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2) | 
|  | 70 | +        }; | 
|  | 71 | + | 
|  | 72 | +        // The bytes returned bytes the Blake2B hasher are always little-endian. | 
|  | 73 | +        Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1])) | 
| 95 | 74 |     } | 
| 96 | 75 | } | 
| 97 | 76 | 
 | 
| 98 | 77 | impl<CTX> stable_hasher::HashStable<CTX> for Fingerprint { | 
|  | 78 | +    #[inline] | 
| 99 | 79 |     fn hash_stable<W: stable_hasher::StableHasherResult>(&self, | 
| 100 | 80 |                                           _: &mut CTX, | 
| 101 | 81 |                                           hasher: &mut stable_hasher::StableHasher<W>) { | 
| 102 |  | -        ::std::hash::Hash::hash(&self.0, hasher); | 
|  | 82 | +        ::std::hash::Hash::hash(self, hasher); | 
| 103 | 83 |     } | 
| 104 | 84 | } | 
0 commit comments