blob: 581d1d3c839add245adb4db9453e69b4fd8f0c2c [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#include "MurmurHash3.h"
2
3#include <stdlib.h> // for _rotl
4
5#pragma warning(disable:4100)
6
7//-----------------------------------------------------------------------------
8// need to replace this
9
10inline uint32_t kmix ( uint32_t k, uint32_t c1, uint32_t c2 )
11{
12 k *= c1;
13 k = _rotl(k,11);
14 k *= c2;
15
16 return k;
17}
18
19// block mix
20
21inline void bmix1 ( uint32_t & h, uint32_t k, uint32_t c1, uint32_t c2 )
22{
23 k = kmix(k,c1,c2);
24
25 h = h*5+0xa6b84e31;
26 h ^= k;
27}
28
29// xor before mul is faster on x64
30
31inline void bmix2 ( uint32_t & h, uint32_t k, uint32_t c1, uint32_t c2 )
32{
33 k = kmix(k,c1,c2);
34
35 h ^= k;
36 h = h*3+0xa6b84e31;
37}
38
39// block constant mix
40
41inline void cmix ( uint32_t & c1, uint32_t & c2 )
42{
43 c1 = c1*9+0x273581d8;
44 c2 = c2*5+0xee700bac;
45}
46
47// finalizer mix - avalanches all bits to within 0.25% bias
48
49inline uint32_t fmix32 ( uint32_t h )
50{
51 h ^= h >> 16;
52 h *= 0x85ebca6b;
53 h ^= h >> 13;
54 h *= 0xc2b2ae35;
55 h ^= h >> 16;
56
57 return h;
58}
59
60// 64-bit finalizer mix - avalanches all bits to within 0.05% bias
61
62inline uint64_t fmix64 ( uint64_t k )
63{
64 k ^= k >> 33;
65 k *= 0xff51afd7ed558ccd;
66 k ^= k >> 33;
67 k *= 0xc4ceb9fe1a85ec53;
68 k ^= k >> 33;
69
70 return k;
71}
72
73//-----------------------------------------------------------------------------
74
75void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out )
76{
77 uint32_t h = 0x971e137b ^ seed;
78
79 const uint8_t * tail = (const uint8_t*)(key) + (len & ~3);
80
81 //----------
82 // body
83
84 const uint32_t * block = (const uint32_t *)tail;
85
86 uint32_t c1 = 0x95543787;
87 uint32_t c2 = 0x2ad7eb25;
88
89 for(int l = -(len/4); l; l++)
90 {
91 bmix1(h,block[l],c1,c2);
92 cmix(c1,c2);
93 }
94
95 //----------
96 // tail
97
98 uint32_t k = 0;
99
100 switch(len & 3)
101 {
102 case 3: k ^= tail[2] << 16;
103 case 2: k ^= tail[1] << 8;
104 case 1: k ^= tail[0];
105 bmix1(h,k,c1,c2);
106 };
107
108 //----------
109 // finalization
110
111 h ^= len;
112
113 h = fmix32(h);
114
115 *(uint32_t*)out = h;
116}
117
118//-----------------------------------------------------------------------------
119
120void merge64 ( uint32_t h[2], const uint32_t * blocks, uint32_t c1, uint32_t c2 )
121{
122 h[0] = _rotl(h[0],9);
123 h[1] = _rotl(h[1],24);
124
125 h[0] += h[1];
126 h[1] += h[0];
127
128 bmix1(h[0],blocks[0],c1,c2);
129 bmix1(h[1],blocks[1],c1,c2);
130}
131
132//----------
133
134void MurmurHash3_x86_64 ( const void * data, int len, uint32_t seed, void * out )
135{
136 uint32_t h[2];
137
138 h[0] = 0x8de1c3ac ^ seed;
139 h[1] = 0xbab98226 ^ seed;
140
141 //----------
142 // body
143
144 const uint32_t * blocks = (const uint32_t *)data;
145
146 uint32_t c1 = 0x95543787;
147 uint32_t c2 = 0x2ad7eb25;
148
149 while(len >= 8)
150 {
151 merge64(h,blocks,c1,c2);
152 cmix(c1,c2);
153
154 blocks += 2;
155 len -= 8;
156 }
157
158 //----------
159 // tail
160
161 uint32_t k[2] = { 0, 0 };
162
163 const uint8_t * tail = (const uint8_t*)blocks;
164
165 switch(len)
166 {
167 case 7: k[1] ^= tail[6] << 16;
168 case 6: k[1] ^= tail[5] << 8;
169 case 5: k[1] ^= tail[4] << 0;
170 case 4: k[0] ^= tail[3] << 24;
171 case 3: k[0] ^= tail[2] << 16;
172 case 2: k[0] ^= tail[1] << 8;
173 case 1: k[0] ^= tail[0] << 0;
174 merge64(h,k,c1,c2);
175 };
176
177 //----------
178 // finalization
179
180 h[1] ^= len;
181
182 h[0] = fmix32(h[0]);
183 h[1] ^= kmix(h[0],c1,c2);
184 h[0] ^= fmix32(h[1]);
185 h[1] ^= kmix(h[0],c1,c2);
186
187 ((uint32_t*)out)[0] = h[0];
188 ((uint32_t*)out)[1] = h[1];
189}
190
191//-----------------------------------------------------------------------------
192
193void merge128 ( uint32_t h[4], const uint32_t * blocks, uint32_t c1, uint32_t c2 )
194{
195 h[0] = _rotl(h[0],3);
196 h[1] = _rotl(h[1],10);
197 h[2] = _rotl(h[2],19);
198 h[3] = _rotl(h[3],26);
199
200 h[0] += h[1];
201 h[0] += h[2];
202 h[0] += h[3];
203
204 h[1] += h[0];
205 h[2] += h[0];
206 h[3] += h[0];
207
208 bmix1(h[0],blocks[0],c1,c2);
209 bmix1(h[1],blocks[1],c1,c2);
210 bmix1(h[2],blocks[2],c1,c2);
211 bmix1(h[3],blocks[3],c1,c2);
212}
213
214//----------
215
216void MurmurHash3_x86_128 ( const void * data, int len, uint32_t seed, uint32_t * out )
217{
218 uint32_t h[4] =
219 {
220 0x8de1c3ac ^ seed,
221 0xbab98226 ^ seed,
222 0xfcba5b2d ^ seed,
223 0x32452e3e ^ seed
224 };
225
226 //----------
227 // body
228
229 const uint32_t * blocks = (const uint32_t *)data;
230
231 uint32_t c1 = 0x95543787;
232 uint32_t c2 = 0x2ad7eb25;
233
234 while(len >= 16)
235 {
236 merge128(h,blocks,c1,c2);
237 cmix(c1,c2);
238
239 blocks += 4;
240 len -= 16;
241 }
242
243 //----------
244 // tail
245
246 uint32_t k[4] = { 0, 0, 0, 0 };
247
248 const uint8_t * tail = (const uint8_t*)blocks;
249
250 switch(len)
251 {
252 case 15: k[3] ^= tail[14] << 16;
253 case 14: k[3] ^= tail[13] << 8;
254 case 13: k[3] ^= tail[12] << 0;
255 case 12: k[2] ^= tail[11] << 24;
256 case 11: k[2] ^= tail[10] << 16;
257 case 10: k[2] ^= tail[ 9] << 8;
258 case 9: k[2] ^= tail[ 8] << 0;
259 case 8: k[1] ^= tail[ 7] << 24;
260 case 7: k[1] ^= tail[ 6] << 16;
261 case 6: k[1] ^= tail[ 5] << 8;
262 case 5: k[1] ^= tail[ 4] << 0;
263 case 4: k[0] ^= tail[ 3] << 24;
264 case 3: k[0] ^= tail[ 2] << 16;
265 case 2: k[0] ^= tail[ 1] << 8;
266 case 1: k[0] ^= tail[ 0] << 0;
267 merge128(h,k,c1,c2);
268 };
269
270 //----------
271 // finalization
272
273 h[3] ^= len;
274
275 h[0] ^= fmix32(h[1]); h[2] ^= fmix32(h[3]);
276 h[1] ^= kmix(h[0],c1,c2); h[3] ^= kmix(h[2],c1,c2);
277 h[3] ^= fmix32(h[0]); h[1] ^= fmix32(h[2]);
278 h[0] ^= kmix(h[3],c1,c2); h[2] ^= kmix(h[1],c1,c2);
279 h[1] ^= fmix32(h[0]); h[3] ^= fmix32(h[2]);
280
281 out[0] = h[0];
282 out[1] = h[1];
283 out[2] = h[2];
284 out[3] = h[3];
285}
286
287//-----------------------------------------------------------------------------
288