blob: fa2dafc08d1ee4438ca54b32d380030d84825fb1 [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#include "MurmurHash3.h"
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00002
tanjent@gmail.combabb5532011-02-28 06:03:12 +00003// Note - The x86 and x64 versions do _not_ produce the same results, as the
4// algorithms are optimized for their respective platforms. You can still
5// compile and run any of them on any platform, but your performance with the
6// non-native version will be less than optimal.
7
8
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00009//-----------------------------------------------------------------------------
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000010// Block read - if your platform needs to do endian-swapping or can only
11// handle aligned reads, do the conversion here
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000012
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000013FORCE_INLINE uint32_t getblock ( const uint32_t * p, int i )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000014{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000015 return p[i];
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000016}
17
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000018//----------
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000019
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000020FORCE_INLINE void bmix32 ( uint32_t & h1, uint32_t & k1,
21 uint32_t & c1, uint32_t & c2 )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000022{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000023 c1 = c1*5+0x7b7d159c;
24 c2 = c2*5+0x6bce6396;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000025
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000026 k1 *= c1;
27 k1 = ROTL32(k1,11);
28 k1 *= c2;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000029
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000030 h1 = ROTL32(h1,13);
31 h1 = h1*5+0x52dce729;
32 h1 ^= k1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000033}
34
35//----------
36
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000037void MurmurHash3_x86_32 ( const void * key, int len,
38 uint32_t seed, void * out )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000039{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000040 const uint8_t * data = (const uint8_t*)key;
41 const int nblocks = len / 4;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000042
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000043 uint32_t h1 = 0x971e137b ^ seed;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000044
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000045 uint32_t c1 = 0x95543787;
46 uint32_t c2 = 0x2ad7eb25;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000047
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000048 //----------
49 // body
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000050
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000051 const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000052
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000053 for(int i = -nblocks; i; i++)
54 {
55 uint32_t k1 = getblock(blocks,i);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000056
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000057 bmix32(h1,k1,c1,c2);
58 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000059
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000060 //----------
61 // tail
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000062
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000063 const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000064
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000065 uint32_t k1 = 0;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000066
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000067 switch(len & 3)
68 {
69 case 3: k1 ^= tail[2] << 16;
70 case 2: k1 ^= tail[1] << 8;
71 case 1: k1 ^= tail[0];
72 bmix32(h1,k1,c1,c2);
73 };
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000074
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000075 //----------
76 // finalization
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000077
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000078 h1 ^= len;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000079
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000080 h1 *= 0x85ebca6b;
81 h1 ^= h1 >> 13;
82 h1 *= 0xc2b2ae35;
83 h1 ^= h1 >> 16;
tanjent@gmail.combabb5532011-02-28 06:03:12 +000084
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000085 h1 ^= seed;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000086
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000087 *(uint32_t*)out = h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000088}
89
90//-----------------------------------------------------------------------------
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000091// This mix is large enough that VC++ refuses to inline it unless we use
92// __forceinline. It's also not all that fast due to register spillage.
93
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000094FORCE_INLINE void bmix32 ( uint32_t & h1, uint32_t & h2,
95 uint32_t & h3, uint32_t & h4,
96 uint32_t & k1, uint32_t & k2,
97 uint32_t & k3, uint32_t & k4,
98 uint32_t & c1, uint32_t & c2 )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000099{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000100 k1 *= c1;
101 k1 = ROTL32(k1,11);
102 k1 *= c2;
103 h1 ^= k1;
104 h1 += h2;
105 h1 += h3;
106 h1 += h4;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000107
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000108 h1 = ROTL32(h1,17);
tanjent@gmail.com31a9e8e2010-11-09 20:29:19 +0000109
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000110 k2 *= c2;
111 k2 = ROTL32(k2,11);
112 k2 *= c1;
113 h2 ^= k2;
114 h2 += h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000115
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000116 h1 = h1*3+0x52dce729;
117 h2 = h2*3+0x38495ab5;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000118
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000119 c1 = c1*5+0x7b7d159c;
120 c2 = c2*5+0x6bce6396;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000121
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000122 k3 *= c1;
123 k3 = ROTL32(k3,11);
124 k3 *= c2;
125 h3 ^= k3;
126 h3 += h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000127
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000128 k4 *= c2;
129 k4 = ROTL32(k4,11);
130 k4 *= c1;
131 h4 ^= k4;
132 h4 += h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000133
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000134 h3 = h3*3+0x52dce729;
135 h4 = h4*3+0x38495ab5;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000136
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000137 c1 = c1*5+0x7b7d159c;
138 c2 = c2*5+0x6bce6396;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000139}
140
141//----------
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000142// Finalization mix - force all bits of a hash block to avalanche
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000143
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000144// avalanches all bits to within 0.25% bias
145
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000146FORCE_INLINE uint32_t fmix32 ( uint32_t h )
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000147{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000148 h ^= h >> 16;
149 h *= 0x85ebca6b;
150 h ^= h >> 13;
151 h *= 0xc2b2ae35;
152 h ^= h >> 16;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000153
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000154 return h;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000155}
156
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000157void MurmurHash3_x86_128 ( const void * key, const int len,
158 uint32_t seed, void * out )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000159{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000160 const uint8_t * data = (const uint8_t*)key;
161 const int nblocks = len / 16;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000162
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000163 uint32_t h1 = 0x8de1c3ac ^ seed;
164 uint32_t h2 = 0xbab98226 ^ seed;
165 uint32_t h3 = 0xfcba5b2d ^ seed;
166 uint32_t h4 = 0x32452e3e ^ seed;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000167
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000168 uint32_t c1 = 0x95543787;
169 uint32_t c2 = 0x2ad7eb25;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000170
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000171 //----------
172 // body
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000173
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000174 const uint32_t * blocks = (const uint32_t *)(data);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000175
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000176 for(int i = 0; i < nblocks; i++)
177 {
178 uint32_t k1 = getblock(blocks,i*4+0);
179 uint32_t k2 = getblock(blocks,i*4+1);
180 uint32_t k3 = getblock(blocks,i*4+2);
181 uint32_t k4 = getblock(blocks,i*4+3);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000182
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000183 bmix32(h1,h2,h3,h4, k1,k2,k3,k4, c1,c2);
184 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000185
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000186 //----------
187 // tail
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000188
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000189 const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000190
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000191 uint32_t k1 = 0;
192 uint32_t k2 = 0;
193 uint32_t k3 = 0;
194 uint32_t k4 = 0;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000195
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000196 switch(len & 15)
197 {
198 case 15: k4 ^= tail[14] << 16;
199 case 14: k4 ^= tail[13] << 8;
200 case 13: k4 ^= tail[12] << 0;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000201
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000202 case 12: k3 ^= tail[11] << 24;
203 case 11: k3 ^= tail[10] << 16;
204 case 10: k3 ^= tail[ 9] << 8;
205 case 9: k3 ^= tail[ 8] << 0;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000206
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000207 case 8: k2 ^= tail[ 7] << 24;
208 case 7: k2 ^= tail[ 6] << 16;
209 case 6: k2 ^= tail[ 5] << 8;
210 case 5: k2 ^= tail[ 4] << 0;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000211
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000212 case 4: k1 ^= tail[ 3] << 24;
213 case 3: k1 ^= tail[ 2] << 16;
214 case 2: k1 ^= tail[ 1] << 8;
215 case 1: k1 ^= tail[ 0] << 0;
216 bmix32(h1,h2,h3,h4, k1,k2,k3,k4, c1,c2);
217 };
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000218
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000219 //----------
220 // finalization
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000221
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000222 h4 ^= len;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000223
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000224 h1 += h2; h1 += h3; h1 += h4;
225 h2 += h1; h3 += h1; h4 += h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000226
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000227 h1 = fmix32(h1);
228 h2 = fmix32(h2);
229 h3 = fmix32(h3);
230 h4 = fmix32(h4);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000231
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000232 h1 += h2; h1 += h3; h1 += h4;
233 h2 += h1; h3 += h1; h4 += h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000234
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000235 ((uint32_t*)out)[0] = h1;
236 ((uint32_t*)out)[1] = h2;
237 ((uint32_t*)out)[2] = h3;
238 ((uint32_t*)out)[3] = h4;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000239}
240
241//-----------------------------------------------------------------------------
242// Block read - if your platform needs to do endian-swapping or can only
243// handle aligned reads, do the conversion here
244
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000245FORCE_INLINE uint64_t getblock ( const uint64_t * p, int i )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000246{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000247 return p[i];
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000248}
249
250//----------
251// Block mix - combine the key bits with the hash bits and scramble everything
252
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000253FORCE_INLINE void bmix64 ( uint64_t & h1, uint64_t & h2,
254 uint64_t & k1, uint64_t & k2,
255 uint64_t & c1, uint64_t & c2 )
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000256{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000257 k1 *= c1;
258 k1 = ROTL64(k1,23);
259 k1 *= c2;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000260
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000261 k2 *= c2;
262 k2 = ROTL64(k2,23);
263 k2 *= c1;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000264
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000265 h1 = ROTL64(h1,17);
266 h1 += h2;
267 h1 ^= k1;
tanjent@gmail.combabb5532011-02-28 06:03:12 +0000268
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000269 h2 = ROTL64(h2,41);
270 h2 += h1;
271 h2 ^= k2;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000272
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000273 h1 = h1*3+0x52dce729;
274 h2 = h2*3+0x38495ab5;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000275
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000276 c1 = c1*5+0x7b7d159c;
277 c2 = c2*5+0x6bce6396;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000278}
279
280//----------
281// Finalization mix - avalanches all bits to within 0.05% bias
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000282
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000283FORCE_INLINE uint64_t fmix64 ( uint64_t k )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000284{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000285 k ^= k >> 33;
286 k *= BIG_CONSTANT(0xff51afd7ed558ccd);
287 k ^= k >> 33;
288 k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
289 k ^= k >> 33;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000290
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000291 return k;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000292}
293
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000294//----------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000295
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000296void MurmurHash3_x64_128 ( const void * key, const int len,
297 const uint32_t seed, void * out )
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000298{
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000299 const uint8_t * data = (const uint8_t*)key;
300 const int nblocks = len / 16;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000301
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000302 uint64_t h1 = BIG_CONSTANT(0x9368e53c2f6af274) ^ seed;
303 uint64_t h2 = BIG_CONSTANT(0x586dcd208f7cd3fd) ^ seed;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000304
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000305 uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
306 uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000307
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000308 //----------
309 // body
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000310
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000311 const uint64_t * blocks = (const uint64_t *)(data);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000312
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000313 for(int i = 0; i < nblocks; i++)
314 {
315 uint64_t k1 = getblock(blocks,i*2+0);
316 uint64_t k2 = getblock(blocks,i*2+1);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000317
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000318 bmix64(h1,h2,k1,k2,c1,c2);
319 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000320
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000321 //----------
322 // tail
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000323
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000324 const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000325
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000326 uint64_t k1 = 0;
327 uint64_t k2 = 0;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000328
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000329 switch(len & 15)
330 {
331 case 15: k2 ^= uint64_t(tail[14]) << 48;
332 case 14: k2 ^= uint64_t(tail[13]) << 40;
333 case 13: k2 ^= uint64_t(tail[12]) << 32;
334 case 12: k2 ^= uint64_t(tail[11]) << 24;
335 case 11: k2 ^= uint64_t(tail[10]) << 16;
336 case 10: k2 ^= uint64_t(tail[ 9]) << 8;
337 case 9: k2 ^= uint64_t(tail[ 8]) << 0;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000338
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000339 case 8: k1 ^= uint64_t(tail[ 7]) << 56;
340 case 7: k1 ^= uint64_t(tail[ 6]) << 48;
341 case 6: k1 ^= uint64_t(tail[ 5]) << 40;
342 case 5: k1 ^= uint64_t(tail[ 4]) << 32;
343 case 4: k1 ^= uint64_t(tail[ 3]) << 24;
344 case 3: k1 ^= uint64_t(tail[ 2]) << 16;
345 case 2: k1 ^= uint64_t(tail[ 1]) << 8;
346 case 1: k1 ^= uint64_t(tail[ 0]) << 0;
347 bmix64(h1,h2,k1,k2,c1,c2);
348 };
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000349
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000350 //----------
351 // finalization
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000352
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000353 h2 ^= len;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000354
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000355 h1 += h2;
356 h2 += h1;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000357
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000358 h1 = fmix64(h1);
359 h2 = fmix64(h2);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000360
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000361 h1 += h2;
362 h2 += h1;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000363
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000364 ((uint64_t*)out)[0] = h1;
365 ((uint64_t*)out)[1] = h2;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000366}
367
368//-----------------------------------------------------------------------------
tanjent@gmail.comf67ce942011-03-14 09:11:18 +0000369// Quick copy-pasted test code for GCC build
370
371// This should print -
372
373// "The quick brown fox jumps over the lazy dog" => { 0x38585ecf, 0x5f6d752a, 0x0157c98a, 0x8c686b9b, }
374// "The quick brown fox jumps over the lazy cog" => { 0x6d3fd6f0, 0xc86a98a0, 0x4d6fac1c, 0x8f3e52b4, }
375
376#ifndef _MSC_VER
377
378/*
379#include <assert.h>
380#include <stdio.h>
381#include <string.h>
382
383typedef void (*pfHash) ( const void * blob, const int len, const uint32_t seed, void * out );
384
385void printhex32 ( void * blob, int len )
386{
387 assert((len & 3) == 0);
388
389 uint32_t * d = (uint32_t*)blob;
390
391 printf("{ ");
392
393 for(int i = 0; i < len/4; i++)
394 {
395 printf("0x%08x, ",d[i]);
396 }
397
398 printf("}");
399}
400
401void QuickBrownFox ( pfHash hash, const int hashbits )
402{
403 const int hashbytes = hashbits / 8;
404
405 const char * text1 = "The quick brown fox jumps over the lazy dog";
406 const char * text2 = "The quick brown fox jumps over the lazy cog";
407
408 uint8_t h1[128];
409 uint8_t h2[128];
410
411 hash(text1,(int)strlen(text1),0,h1);
412 hash(text2,(int)strlen(text2),0,h2);
413
414 printf("\"%s\" => ",text1);
415 printhex32(h1,hashbytes);
416 printf("\n");
417
418 printf("\"%s\" => ",text2);
419 printhex32(h2,hashbytes);
420 printf("\n");
421
422 printf("\n");
423}
424
425int main ( int argc, char** argv )
426{
427 QuickBrownFox(&MurmurHash3_x64_128,128);
428}
429*/
430
431#endif