|
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