1#ifndef DICE_HASH_WYHASH_H
2#define DICE_HASH_WYHASH_H
13#ifndef wyhash_final_version_3
14#define wyhash_final_version_3
20#define WYHASH_CONDOM 2
23#ifndef WYHASH_32BIT_MUM
26#define WYHASH_32BIT_MUM 0
32#if defined(_MSC_VER) && defined(_M_X64)
34#pragma intrinsic(_umul128)
38#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
39#define _likely_(x) __builtin_expect(x, 1)
40#define _unlikely_(x) __builtin_expect(x, 0)
42#define _likely_(x) (x)
43#define _unlikely_(x) (x)
45namespace dice::hash::wyhash {
47 static inline uint64_t _wyrot(uint64_t x) {
return (x >> 32) | (x << 32); }
48 static inline void _wymum(uint64_t *A, uint64_t *B) {
50 uint64_t hh = (*A >> 32) * (*B >> 32), hl = (*A >> 32) * (uint32_t) *B, lh = (uint32_t) *A * (*B >> 32), ll = (uint64_t) (uint32_t) *A * (uint32_t) *B;
51#if (WYHASH_CONDOM > 1)
52 *A ^= _wyrot(hl) ^ hh;
53 *B ^= _wyrot(lh) ^ ll;
58#elif defined(__SIZEOF_INT128__)
61#if (WYHASH_CONDOM > 1)
63 *B ^= (uint64_t) (r >> 64);
66 *B = (uint64_t) (r >> 64);
68#elif defined(_MSC_VER) && defined(_M_X64)
69#if (WYHASH_CONDOM > 1)
71 a = _umul128(*A, *B, &b);
75 *A = _umul128(*A, *B, B);
78 uint64_t ha = *A >> 32, hb = *B >> 32, la = (uint32_t) *A, lb = (uint32_t) *B, hi, lo;
79 uint64_t rh = ha * hb, rm0 = ha * lb, rm1 = hb * la, rl = la * lb, t = rl + (rm0 << 32), c = t < rl;
82 hi = rh + (rm0 >> 32) + (rm1 >> 32) + c;
83#if (WYHASH_CONDOM > 1)
94 static inline uint64_t _wymix(uint64_t A, uint64_t B) {
100#ifndef WYHASH_LITTLE_ENDIAN
101#if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
102#define WYHASH_LITTLE_ENDIAN 1
103#elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
104#define WYHASH_LITTLE_ENDIAN 0
106#warning could not determine endianness! Falling back to little endian.
107#define WYHASH_LITTLE_ENDIAN 1
112#if (WYHASH_LITTLE_ENDIAN)
113 static inline uint64_t _wyr8(
const uint8_t *p) {
118 static inline uint64_t _wyr4(
const uint8_t *p) {
123#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
124 static inline uint64_t _wyr8(
const uint8_t *p) {
127 return __builtin_bswap64(v);
129 static inline uint64_t _wyr4(
const uint8_t *p) {
132 return __builtin_bswap32(v);
134#elif defined(_MSC_VER)
135 static inline uint64_t _wyr8(
const uint8_t *p) {
138 return _byteswap_uint64(v);
140 static inline uint64_t _wyr4(
const uint8_t *p) {
143 return _byteswap_ulong(v);
146 static inline uint64_t _wyr8(
const uint8_t *p) {
149 return (((v >> 56) & 0xff) | ((v >> 40) & 0xff00) | ((v >> 24) & 0xff0000) | ((v >> 8) & 0xff000000) | ((v << 8) & 0xff00000000) | ((v << 24) & 0xff0000000000) | ((v << 40) & 0xff000000000000) | ((v << 56) & 0xff00000000000000));
151 static inline uint64_t _wyr4(
const uint8_t *p) {
154 return (((v >> 24) & 0xff) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | ((v << 24) & 0xff000000));
157 static inline uint64_t _wyr3(
const uint8_t *p,
size_t k) {
return (((uint64_t) p[0]) << 16) | (((uint64_t) p[k >> 1]) << 8) | p[k - 1]; }
159 static inline uint64_t wyhash(
const void *key,
size_t len, uint64_t seed,
const uint64_t *secret) {
160 const uint8_t *p = (
const uint8_t *) key;
163 if (_likely_(len <= 16)) {
164 if (_likely_(len >= 4)) {
165 a = (_wyr4(p) << 32) | _wyr4(p + ((len >> 3) << 2));
166 b = (_wyr4(p + len - 4) << 32) | _wyr4(p + len - 4 - ((len >> 3) << 2));
167 }
else if (_likely_(len > 0)) {
174 if (_unlikely_(i > 48)) {
175 uint64_t see1 = seed, see2 = seed;
177 seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
178 see1 = _wymix(_wyr8(p + 16) ^ secret[2], _wyr8(p + 24) ^ see1);
179 see2 = _wymix(_wyr8(p + 32) ^ secret[3], _wyr8(p + 40) ^ see2);
182 }
while (_likely_(i > 48));
185 while (_unlikely_(i > 16)) {
186 seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
190 a = _wyr8(p + i - 16);
191 b = _wyr8(p + i - 8);
193 return _wymix(secret[1] ^ len, _wymix(a ^ secret[1], b ^ seed));
197 static constexpr const uint64_t _wyp[4] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull};
200 static inline uint64_t wyhash64(uint64_t A, uint64_t B) {
201 A ^= 0xa0761d6478bd642full;
202 B ^= 0xe7037ed1a0b428dbull;
204 return _wymix(A ^ 0xa0761d6478bd642full, B ^ 0xe7037ed1a0b428dbull);
208 static inline uint64_t wyrand(uint64_t *seed) {
209 *seed += 0xa0761d6478bd642full;
210 return _wymix(*seed, *seed ^ 0xe7037ed1a0b428dbull);
214 static inline double wy2u01(uint64_t r) {
215 const double _wynorm = 1.0 / (1ull << 52);
216 return (r >> 12) * _wynorm;
220 static inline double wy2gau(uint64_t r) {
221 const double _wynorm = 1.0 / (1ull << 20);
222 return ((r & 0x1fffff) + ((r >> 21) & 0x1fffff) + ((r >> 42) & 0x1fffff)) * _wynorm - 3.0;
225#if (!WYHASH_32BIT_MUM)
227 static inline uint64_t wy2u0k(uint64_t r, uint64_t k) {
234 static inline void make_secret(uint64_t seed, uint64_t *secret) {
235 uint8_t c[] = {15, 23, 27, 29, 30, 39, 43, 45, 46, 51, 53, 54, 57, 58, 60, 71, 75, 77, 78, 83, 85, 86, 89, 90, 92, 99, 101, 102, 105, 106, 108, 113, 114, 116, 120, 135, 139, 141, 142, 147, 149, 150, 153, 154, 156, 163, 165, 166, 169, 170, 172, 177, 178, 180, 184, 195, 197, 198, 201, 202, 204, 209, 210, 212, 216, 225, 226, 228, 232, 240};
236 for (
size_t i = 0; i < 4; i++) {
241 for (
size_t j = 0; j < 64; j += 8) secret[i] |= ((uint64_t) c[wyrand(&seed) %
sizeof(c)]) << j;
242 if (secret[i] % 2 == 0) {
246 for (
size_t j = 0; j < i; j++) {
247#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
248 if (__builtin_popcountll(secret[j] ^ secret[i]) != 32) {
252#elif defined(_MSC_VER) && defined(_M_X64)
253 if (_mm_popcnt_u64(secret[j] ^ secret[i]) != 32) {
259 uint64_t x = secret[j] ^ secret[i];
260 x -= (x >> 1) & 0x5555555555555555;
261 x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
262 x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f;
263 x = (x * 0x0101010101010101) >> 56;