1 use crate::stable_hasher
;
2 use rustc_serialize
::opaque
::{Decoder, EncodeResult, Encoder}
;
5 #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
6 pub struct Fingerprint(u64, u64);
9 pub const ZERO
: Fingerprint
= Fingerprint(0, 0);
12 pub fn from_smaller_hash(hash
: u64) -> Fingerprint
{
13 Fingerprint(hash
, hash
)
17 pub fn to_smaller_hash(&self) -> u64 {
22 pub fn as_value(&self) -> (u64, u64) {
27 pub fn combine(self, other
: Fingerprint
) -> Fingerprint
{
28 // See https://stackoverflow.com/a/27952689 on why this function is
29 // implemented this way.
31 self.0.wrapping_mul(3).wrapping_add(other
.0),
32 self.1.wrapping_mul(3).wrapping_add(other
.1),
36 // Combines two hashes in an order independent way. Make sure this is what
39 pub fn combine_commutative(self, other
: Fingerprint
) -> Fingerprint
{
40 let a
= u128
::from(self.1) << 64 | u128
::from(self.0);
41 let b
= u128
::from(other
.1) << 64 | u128
::from(other
.0);
43 let c
= a
.wrapping_add(b
);
45 Fingerprint((c
>> 64) as u64, c
as u64)
48 pub fn to_hex(&self) -> String
{
49 format
!("{:x}{:x}", self.0, self.1)
52 pub fn encode_opaque(&self, encoder
: &mut Encoder
) -> EncodeResult
{
53 let bytes
: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) }
;
55 encoder
.emit_raw_bytes(&bytes
);
59 pub fn decode_opaque(decoder
: &mut Decoder
<'_
>) -> Result
<Fingerprint
, String
> {
60 let mut bytes
= [0; 16];
62 decoder
.read_raw_bytes(&mut bytes
)?
;
64 let [l
, r
]: [u64; 2] = unsafe { mem::transmute(bytes) }
;
66 Ok(Fingerprint(u64::from_le(l
), u64::from_le(r
)))
70 impl ::std
::fmt
::Display
for Fingerprint
{
71 fn fmt(&self, formatter
: &mut ::std
::fmt
::Formatter
<'_
>) -> ::std
::fmt
::Result
{
72 write
!(formatter
, "{:x}-{:x}", self.0, self.1)
76 impl stable_hasher
::StableHasherResult
for Fingerprint
{
78 fn finish(hasher
: stable_hasher
::StableHasher
) -> Self {
79 let (_0
, _1
) = hasher
.finalize();
84 impl_stable_hash_via_hash
!(Fingerprint
);
86 impl rustc_serialize
::UseSpecializedEncodable
for Fingerprint {}
88 impl rustc_serialize
::UseSpecializedDecodable
for Fingerprint {}
90 impl rustc_serialize
::SpecializedEncoder
<Fingerprint
> for Encoder
{
91 fn specialized_encode(&mut self, f
: &Fingerprint
) -> Result
<(), Self::Error
> {
96 impl<'a
> rustc_serialize
::SpecializedDecoder
<Fingerprint
> for Decoder
<'a
> {
97 fn specialized_decode(&mut self) -> Result
<Fingerprint
, Self::Error
> {
98 Fingerprint
::decode_opaque(self)