1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::convert::TryInto;
use super::fld::FldMix;
use crate::prelude::*;
use std::mem::transmute;
#[derive(PartialEq, Eq, Hash, Clone)]
pub struct FastStableHasher {
mixer: FldMix,
count: u64,
}
impl StableHasher for FastStableHasher {
type Out = u128;
type Addr = u128;
type Bytes = [u8; 32];
fn new() -> Self {
Self {
mixer: FldMix::new(),
count: 0,
}
}
fn mixin(&mut self, other: &Self) {
self.mixer.mixin(&other.mixer);
self.count += other.count;
}
fn to_bytes(&self) -> Self::Bytes {
unsafe { transmute((self.mixer.to_bytes(), self.count.to_le_bytes())) }
}
fn from_bytes(bytes: Self::Bytes) -> Self {
Self {
mixer: FldMix::from_bytes(bytes[0..24].try_into().unwrap()),
count: u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
}
}
fn write(&mut self, field_address: Self::Addr, bytes: &[u8]) {
profile_method!(write);
let hash = xxhash_rust::xxh3::xxh3_128_with_seed(bytes, field_address as u64);
self.mixer.mix(hash, (field_address >> 64) as u64);
self.count += 1;
}
fn finish(&self) -> u128 {
profile_method!(finish);
xxhash_rust::xxh3::xxh3_128_with_seed(&self.mixer.to_bytes(), self.count)
}
}