diff options
Diffstat (limited to 'contrib/murmurhash3/murmurhash3.c')
-rw-r--r-- | contrib/murmurhash3/murmurhash3.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/contrib/murmurhash3/murmurhash3.c b/contrib/murmurhash3/murmurhash3.c new file mode 100644 index 0000000..995c236 --- /dev/null +++ b/contrib/murmurhash3/murmurhash3.c @@ -0,0 +1,77 @@ +/* This is MurmurHash3. The original C++ code was placed in the public domain + * by its author, Austin Appleby. + * + * SPDX-License-Identifier: CC0-1.0 + * Source: https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */ + +#include "murmurhash3.h" +#include "string.h" + +static inline uint32_t fmix(uint32_t h) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +static inline uint32_t rotl32(uint32_t x, int8_t r) +{ + return (x << r) | (x >> (32 - r)); +} + +uint32_t hash(const char* data, size_t len_) +{ + const int len = (int) len_; + const int nblocks = len / 4; + + uint32_t h1 = 0xc062fb4a; + + uint32_t c1 = 0xcc9e2d51; + uint32_t c2 = 0x1b873593; + + //---------- + // body + + int i; + for(i = -nblocks; i; i++) + { + uint32_t k1; + memcpy(&k1, data + nblocks * 4 + i * sizeof(k1), sizeof(k1)); + + k1 *= c1; + k1 = rotl32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = rotl32(h1, 13); + h1 = h1*5+0xe6546b64; + } + + //---------- + // tail + + const uint8_t * tail = (const uint8_t*)(data + nblocks*4); + + uint32_t k1 = 0; + + switch(len & 3) + { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; + k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1; + } + + //---------- + // finalization + + h1 ^= len; + + h1 = fmix(h1); + + return h1; +} |