blob: a6ed4dce815044dea189e3008845fcd4dc6672a3 [file] [log] [blame]
Jon Ashburnfc1031e2015-11-17 15:31:02 -07001
2/**
3 * `murmurhash.h' - murmurhash
4 *
5 * copyright (c) 2014 joseph werle <joseph.werle@gmail.com>
6 */
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <stdint.h>
11#include "murmurhash.h"
12
13uint32_t
Courtney Goeltzenleuchter0ef13a02015-12-16 16:19:46 -070014murmurhash (const char *key, size_t len, uint32_t seed) {
Jon Ashburnfc1031e2015-11-17 15:31:02 -070015 uint32_t c1 = 0xcc9e2d51;
16 uint32_t c2 = 0x1b873593;
17 uint32_t r1 = 15;
18 uint32_t r2 = 13;
19 uint32_t m = 5;
20 uint32_t n = 0xe6546b64;
21 uint32_t h = 0;
22 uint32_t k = 0;
23 uint8_t *d = (uint8_t *) key; // 32 bit extract from `key'
24 const uint32_t *chunks = NULL;
25 const uint8_t *tail = NULL; // tail - last 8 bytes
26 int i = 0;
Courtney Goeltzenleuchter0ef13a02015-12-16 16:19:46 -070027 int l = (int) len / 4; // chunk length
Jon Ashburnfc1031e2015-11-17 15:31:02 -070028
29 h = seed;
30
31 chunks = (const uint32_t *) (d + l * 4); // body
32 tail = (const uint8_t *) (d + l * 4); // last 8 byte chunk of `key'
33
34 // for each 4 byte chunk of `key'
35 for (i = -l; i != 0; ++i) {
36 // next 4 byte chunk of `key'
37 k = chunks[i];
38
39 // encode next 4 byte chunk of `key'
40 k *= c1;
41 k = (k << r1) | (k >> (32 - r1));
42 k *= c2;
43
44 // append to hash
45 h ^= k;
46 h = (h << r2) | (h >> (32 - r2));
47 h = h * m + n;
48 }
49
50 k = 0;
51
52 // remainder
53 switch (len & 3) { // `len % 4'
54 case 3: k ^= (tail[2] << 16);
55 case 2: k ^= (tail[1] << 8);
56
57 case 1:
58 k ^= tail[0];
59 k *= c1;
60 k = (k << r1) | (k >> (32 - r1));
61 k *= c2;
62 h ^= k;
63 }
64
65 h ^= len;
66
67 h ^= (h >> 16);
68 h *= 0x85ebca6b;
69 h ^= (h >> 13);
70 h *= 0xc2b2ae35;
71 h ^= (h >> 16);
72
73 return h;
74}