Created
May 27, 2020 09:26
-
-
Save kevinmoran/471480b1e20a19b0687d81b75fd801c8 to your computer and use it in GitHub Desktop.
Simple MurmurHash3 Implementation (from Demetri Spanos)
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
// Minimal Murmur3 implementation shared by Demetri Spanos on Handmade Network Discord | |
// | |
// Code is deliberately terse and simplistic | |
// Intended to be the first hash function you reach for e.g. a simple hash table | |
// *** NB THIS IS NOT A CRYPTOGRAPHIC HASH *** | |
// | |
// @demetrispanos: | |
// "yes let me reiterate the moral of this story | |
// there is never any reason to use a dumb made up hash function | |
// use murmur3 or jenkins-one-at-a-time for a 0-effort version | |
// both are quite good, though not quite as good as modern state of the art | |
// but modern state of the art ones aren't as simple (i.e. not 20 lines long) | |
// banish "TODO: better hash function" from your life | |
// just use my 20 line murmur3" | |
static inline uint32_t rotl32 (uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); } | |
static inline uint32_t fmix (uint32_t h ) { | |
h ^= h >> 16; h *= 0x85ebca6b; | |
h ^= h >> 13; h *= 0xc2b2ae35; | |
return h ^= h >> 16; | |
} | |
uint32_t m32 (const void *key, uint32_t len, uint32_t h1) { | |
const uint8_t *tail = (const uint8_t*)key + (len/4)*4; // handle this separately | |
uint32_t c1 = 0xcc9e2d51, c2 = 0x1b873593; | |
// body (full 32-bit blocks) handled uniformly | |
for (uint32_t *p = (uint32_t*) key; p < (const uint32_t*) tail; p++) { | |
uint32_t k1 = *p; k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; // MUR1 | |
h1 ^= k1; h1 = rotl32(h1,13); h1 = h1*5+0xe6546b64; // MUR2 | |
} | |
uint32_t t = 0; // handle up to 3 tail bytes | |
switch(len & 3) { | |
case 3: t ^= tail[2] << 16; | |
case 2: t ^= tail[1] << 8; | |
case 1: {t ^= tail[0]; t *= c1; t = rotl32(t,15); t *= c2; h1 ^= t;}; | |
} | |
return fmix(h1 ^ len); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment