Skip to content

Instantly share code, notes, and snippets.

@Hexlord
Created April 10, 2023 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hexlord/3d94373ac617e53877267c838afea242 to your computer and use it in GitHub Desktop.
Save Hexlord/3d94373ac617e53877267c838afea242 to your computer and use it in GitHub Desktop.
wyhash denoised
inline constexpr u64 _wyrot(u64 x) {
return (x >> 32) | (x << 32);
}
// 128bit multiply function.
inline constexpr void _wymum(u64 *A, u64 *B) {
#if defined(__SIZEOF_INT128__)
__uint128_t r = *A;
r *= *B;
*A = (u64)r;
*B = (u64)(r >> 64);
#else
u64 ha = *A >> 32, hb = *B >> 32, la = (uint32_t)*A, lb = (uint32_t)*B, hi, lo;
u64 rh = ha * hb, rm0 = ha * lb, rm1 = hb * la, rl = la * lb, t = rl + (rm0 << 32), c = t < rl;
lo = t + (rm1 << 32);
c += lo < t;
hi = rh + (rm0 >> 32) + (rm1 >> 32) + c;
*A = lo;
*B = hi;
#endif
}
// Multiply and xor mix function.
inline constexpr u64 _wymix(u64 A, u64 B) {
_wymum(&A, &B);
return A ^ B;
}
//read functions
#if(BX_CPU_ENDIAN_LITTLE)
inline constexpr u64 _read8(const char *p) {
u64 Result = 0;
for(var Index = 0u; Index < 8u; ++Index) {
Result = Result << 8;
Result |= (byte)p[Index];
}
return Result;
}
inline constexpr u64 _read8(const byte *p) {
u64 Result = 0;
for(var Index = 0u; Index < 8u; ++Index) {
Result = Result << 8;
Result |= p[Index];
}
return Result;
}
inline constexpr u64 _read4(const char *p) {
u64 Result = 0;
for(var Index = 0u; Index < 4u; ++Index) {
Result = Result << 8;
Result |= (byte)p[Index];
}
return Result;
}
inline constexpr u64 _read4(const byte *p) {
u64 Result = 0;
for(var Index = 0u; Index < 4u; ++Index) {
Result = Result << 8;
Result |= p[Index];
}
return Result;
}
inline constexpr u64 _wyr8(const char *p) {
return _read8(p);
}
inline constexpr u64 _wyr8(const byte *p) {
return _read8(p);
}
inline constexpr u64 _wyr4(const char *p) {
return _read4(p);
}
inline constexpr u64 _wyr4(const byte *p) {
return _read4(p);
}
#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
inline constexpr u64 _wyr8(const byte *p) {
var v = _read8(p);
return __builtin_bswap64(v);
}
inline constexpr u64 _wyr8(const char *p) {
var v = _read8(p);
return __builtin_bswap64(v);
}
inline constexpr u64 _wyr4(const byte *p) {
var v = _read4(p);
return __builtin_bswap32(v);
}
inline constexpr u64 _wyr4(const char *p) {
var v = _read4(p);
return __builtin_bswap32(v);
}
#else
inline constexpr u64 _wyr8(const byte *p) {
var v = _read8(p);
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));
}
inline constexpr u64 _wyr8(const char *p) {
var v = _read8(p);
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));
}
inline constexpr u64 _wyr4(const byte *p) {
var v = _read4(p);
return (((v >> 24) & 0xff) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | ((v << 24) & 0xff000000));
}
inline constexpr u64 _wyr4(const char *p) {
var v = _read4(p);
return (((v >> 24) & 0xff) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | ((v << 24) & 0xff000000));
}
#endif
inline constexpr u64 _wyr3(const byte *p, size_t k) {
return (((u64)p[0]) << 16) | (((u64)p[k >> 1]) << 8) | (byte)p[k - 1];
}
inline constexpr u64 _wyr3(const char *p, size_t k) {
return (((u64)p[0]) << 16) | (((u64)p[k >> 1]) << 8) | (byte)p[k - 1];
}
// The default secret parameters.
inline constexpr u64 secret[4] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull};
inline constexpr hash ComputeHashWy64(const byte *p, u32 len, u64 seed) {
seed ^= _wymix(seed ^ secret[0], secret[1]);
u64 a, b;
if(Likely(len <= 16)) {
if(Likely(len >= 4)) {
a = (_wyr4(p) << 32) | _wyr4(p + ((len >> 3) << 2));
b = (_wyr4(p + len - 4) << 32) | _wyr4(p + len - 4 - ((len >> 3) << 2));
} else if(Likely(len > 0)) {
a = _wyr3(p, len);
b = 0;
} else
a = b = 0;
} else {
var i = len;
if(Unlikely(i > 48)) {
u64 see1 = seed, see2 = seed;
do {
seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
see1 = _wymix(_wyr8(p + 16) ^ secret[2], _wyr8(p + 24) ^ see1);
see2 = _wymix(_wyr8(p + 32) ^ secret[3], _wyr8(p + 40) ^ see2);
p += 48;
i -= 48;
} while(Likely(i > 48));
seed ^= see1 ^ see2;
}
while(Unlikely(i > 16)) {
seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
i -= 16;
p += 16;
}
a = _wyr8(p + i - 16);
b = _wyr8(p + i - 8);
}
a ^= secret[1];
b ^= seed;
_wymum(&a, &b);
return _wymix(a ^ secret[0] ^ len, b ^ secret[1]);
}
inline constexpr hash ComputeHashWy64(const char *p, u32 len, u64 seed) {
seed ^= _wymix(seed ^ secret[0], secret[1]);
u64 a, b;
if(Likely(len <= 16)) {
if(Likely(len >= 4)) {
a = (_wyr4(p) << 32) | _wyr4(p + ((len >> 3) << 2));
b = (_wyr4(p + len - 4) << 32) | _wyr4(p + len - 4 - ((len >> 3) << 2));
} else if(Likely(len > 0)) {
a = _wyr3(p, len);
b = 0;
} else
a = b = 0;
} else {
var i = len;
if(Unlikely(i > 48)) {
u64 see1 = seed, see2 = seed;
do {
seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
see1 = _wymix(_wyr8(p + 16) ^ secret[2], _wyr8(p + 24) ^ see1);
see2 = _wymix(_wyr8(p + 32) ^ secret[3], _wyr8(p + 40) ^ see2);
p += 48;
i -= 48;
} while(Likely(i > 48));
seed ^= see1 ^ see2;
}
while(Unlikely(i > 16)) {
seed = _wymix(_wyr8(p) ^ secret[1], _wyr8(p + 8) ^ seed);
i -= 16;
p += 16;
}
a = _wyr8(p + i - 16);
b = _wyr8(p + i - 8);
}
a ^= secret[1];
b ^= seed;
_wymum(&a, &b);
return _wymix(a ^ secret[0] ^ len, b ^ secret[1]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment