Created
October 4, 2019 12:09
-
-
Save elw00d/3c07e5985ec6a097d68ae6e87ce5695b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace | |
{ | |
inline std::size_t | |
unaligned_load(const char* p) | |
{ | |
std::size_t result; | |
__builtin_memcpy(&result, p, sizeof(result)); | |
return result; | |
} | |
#if __SIZEOF_SIZE_T__ == 8 | |
// Loads n bytes, where 1 <= n < 8. | |
inline std::size_t | |
load_bytes(const char* p, int n) | |
{ | |
std::size_t result = 0; | |
--n; | |
do | |
result = (result << 8) + static_cast<unsigned char>(p[n]); | |
while (--n >= 0); | |
return result; | |
} | |
inline std::size_t | |
shift_mix(std::size_t v) | |
{ return v ^ (v >> 47);} | |
#endif | |
} | |
size_t | |
my_Hash_bytes(const void* ptr, size_t len, size_t seed) | |
{ | |
static const size_t mul = (((size_t) 0xc6a4a793UL) << 32UL) | |
+ (size_t) 0x5bd1e995UL; | |
const char* const buf = static_cast<const char*>(ptr); | |
// Remove the bytes not divisible by the sizeof(size_t). This | |
// allows the main loop to process the data as 64-bit integers. | |
const int len_aligned = len & ~0x7; | |
const char* const end = buf + len_aligned; | |
size_t hash = seed ^ (len * mul); | |
for (const char* p = buf; p != end; p += 8) | |
{ | |
const size_t data = shift_mix(unaligned_load(p) * mul) * mul; | |
hash ^= data; | |
hash *= mul; | |
} | |
if ((len & 0x7) != 0) | |
{ | |
const size_t data = load_bytes(end, len & 0x7); | |
hash ^= data; | |
hash *= mul; | |
} | |
hash = shift_mix(hash) * mul; | |
hash = shift_mix(hash); | |
return hash; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment