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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::{collections::{hash_map::RandomState, HashMap, HashSet}, time::Instant, cell::Cell, hash::{BuildHasher, Hash, Hasher}};
fn generate_seed() -> u64 {
let state = RandomState::new();
let mut hasher = state.build_hasher();
Instant::now().hash(&mut hasher);
hasher.finish()
}
#[derive(Debug, Clone)]
struct Rng {
state: Cell<[u64; 4]>
}
impl Rng {
fn from_seed(s0: u64, s1: u64) -> Self {
let res = Self { state: Cell::new([s0, s1, 0xcafef00dd15ea5e5, 0x14057B7EF767814F]) };
for _ in 0..6 { res.gen_64(); }
res
}
fn new() -> Self { Self::from_seed(generate_seed(), generate_seed()) }
fn gen_64(&self) -> u64 {
let [x1, x2, x3, c] = self.state.get();
let t = (x3 as u128).wrapping_mul(0xfeb3_4465_7c0a_f413);
let (low, hi) = (t as u64, (t >> 64) as u64);
let res = (x3 ^ x2).wrapping_add(x1 ^ hi);
let (x0, b) = low.overflowing_add(c);
self.state.set([x0, x1, x2, hi.wrapping_add(b as u64)]);
res
}
}
#[derive(Debug, Clone, Copy)]
pub struct SHash(u64, u128);
impl SHash {
pub fn new() -> Self {
thread_local! {
static RNG: Rng = Rng::new();
}
RNG.with(|rng| {
Self::from_seed(rng.gen_64(), rng.gen_64(), rng.gen_64())
})
}
pub fn from_seed(k: u64, m: u64, m2: u64) -> Self {
Self(k, m as u128 | (m2 as u128) << 64 | 1)
}
}
impl BuildHasher for SHash {
type Hasher = Self;
fn build_hasher(&self) -> Self::Hasher {
*self
}
}
impl Hasher for SHash {
fn write(&mut self, mut bytes: &[u8]) {
while bytes.len() >= 8 {
let x = bytes.as_ptr() as *const u64;
let x = unsafe { x.read_unaligned() };
self.write_u64(x);
bytes = &bytes[8..];
}
if bytes.len() > 0 {
let mut x = [!0u8; 8];
unsafe { std::ptr::copy_nonoverlapping(bytes.as_ptr(), x.as_mut_ptr(), bytes.len()) }
let x = u64::from_ne_bytes(x);
self.write_u64(x);
}
}
fn write_u8(&mut self, i: u8) { self.write_u64(i as _) }
fn write_u16(&mut self, i: u16) { self.write_u64(i as _) }
fn write_u32(&mut self, i: u32) { self.write_u64(i as _) }
fn write_usize(&mut self, i: usize) { self.write_u64(i as _) }
#[inline] fn write_u64(&mut self, i: u64) {
let mut z = i.wrapping_add((self.1 >> 64) as u64);
z ^= z.rotate_right(25) ^ z.rotate_right(47);
z = z.wrapping_mul(0x9E6C63D0676A9A99).wrapping_add(self.0);
z ^= z >> 23 ^ z >> 51;
z = z.wrapping_mul(0x9E6D62D06F6A9A9B);
z ^= z >> 23 ^ z >> 51;
self.0 = z;
self.1 = self.1.wrapping_mul(0xda942042e4dd58b5);
}
fn write_u128(&mut self, i: u128) { self.write_u64(i as _); self.write_u64((i >> 64) as _); }
fn finish(&self) -> u64 {
self.0
}
}
impl Default for SHash { fn default() -> Self { Self::new() } }
pub type SHashMap<K, V> = HashMap<K, V, SHash>;
pub type SHashSet<K> = HashSet<K, SHash>;
#[cfg(test)]
mod tests {
use crate::SHashMap;
#[test]
fn simple_hashmap_test() {
let mut map = SHashMap::default();
map.insert("Adventures of Huckleberry Finn".to_string(), "My favorite book.".to_string());
assert_eq!(map.get("Adventures of Huckleberry Finn"), Some(&"My favorite book.".to_string()));
}
}