1//----------------------------------------------------------------------------- 2// MurmurHash3 was written by Austin Appleby, and is placed in the public 3// domain. The author hereby disclaims copyright to this source code. 4 5// Note - The x86 and x64 versions do _not_ produce the same results, as the 6// algorithms are optimized for their respective platforms. You can still 7// compile and run any of them on any platform, but your performance with the 8// non-native version will be less than optimal. 9 10#include "murmurhash3.h" 11 12//----------------------------------------------------------------------------- 13// Platform-specific functions and macros 14 15// Microsoft Visual Studio 16 17#if defined(_MSC_VER) 18 19#define FORCE_INLINE __forceinline 20 21#include <stdlib.h> 22 23#define ROTL32(x,y) _rotl(x,y) 24#define ROTL64(x,y) _rotl64(x,y) 25 26#define BIG_CONSTANT(x) (x) 27 28// Other compilers 29 30#else // defined(_MSC_VER) 31 32#define FORCE_INLINE __attribute__((always_inline)) 33 34static inline uint32_t rotl32 ( uint32_t x, int8_t r ) 35{ 36 return (x << r) | (x >> (32 - r)); 37} 38 39static inline uint64_t rotl64 ( uint64_t x, int8_t r ) 40{ 41 return (x << r) | (x >> (64 - r)); 42} 43 44#define ROTL32(x,y) rotl32(x,y) 45#define ROTL64(x,y) rotl64(x,y) 46 47#define BIG_CONSTANT(x) (x##LLU) 48 49#endif // !defined(_MSC_VER) 50 51//----------------------------------------------------------------------------- 52// Block read - if your platform needs to do endian-swapping or can only 53// handle aligned reads, do the conversion here 54 55inline static FORCE_INLINE uint32_t getblock_32 ( const uint32_t * p, int i ) 56{ 57 return p[i]; 58} 59 60inline static FORCE_INLINE uint64_t getblock_64 ( const uint64_t * p, int i ) 61{ 62 return p[i]; 63} 64 65//----------------------------------------------------------------------------- 66// Finalization mix - force all bits of a hash block to avalanche 67 68inline static FORCE_INLINE uint32_t fmix_32 ( uint32_t h ) 69{ 70 h ^= h >> 16; 71 h *= 0x85ebca6b; 72 h ^= h >> 13; 73 h *= 0xc2b2ae35; 74 h ^= h >> 16; 75 76 return h; 77} 78 79//---------- 80 81inline static FORCE_INLINE uint64_t fmix_64 ( uint64_t k ) 82{ 83 k ^= k >> 33; 84 k *= BIG_CONSTANT(0xff51afd7ed558ccd); 85 k ^= k >> 33; 86 k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); 87 k ^= k >> 33; 88 89 return k; 90} 91 92//----------------------------------------------------------------------------- 93 94void MurmurHash3_x86_32 ( const void * key, int len, 95 uint32_t seed, void * out ) 96{ 97 const uint8_t * data = (const uint8_t*)key; 98 const int nblocks = len / 4; 99 100 uint32_t h1 = seed; 101 102 uint32_t c1 = 0xcc9e2d51; 103 uint32_t c2 = 0x1b873593; 104 105 const uint32_t * blocks; 106 const uint8_t * tail; 107 108 uint32_t k1; 109 110 int i; 111 //---------- 112 // body 113 114 blocks = (const uint32_t *)(data + nblocks*4); 115 116 for(i = -nblocks; i; i++) 117 { 118 k1 = getblock_32(blocks,i); 119 120 k1 *= c1; 121 k1 = ROTL32(k1,15); 122 k1 *= c2; 123 124 h1 ^= k1; 125 h1 = ROTL32(h1,13); 126 h1 = h1*5+0xe6546b64; 127 } 128 129 //---------- 130 // tail 131 132 tail = (const uint8_t*)(data + nblocks*4); 133 134 k1 = 0; 135 136 switch(len & 3) 137 { 138 case 3: k1 ^= tail[2] << 16; 139 case 2: k1 ^= tail[1] << 8; 140 case 1: k1 ^= tail[0]; 141 k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; 142 }; 143 144 //---------- 145 // finalization 146 147 h1 ^= len; 148 149 h1 = fmix_32(h1); 150 151 *(uint32_t*)out = h1; 152} 153 154//----------------------------------------------------------------------------- 155 156void MurmurHash3_x86_128 ( const void * key, const int len, 157 uint32_t seed, void * out ) 158{ 159 const uint8_t * data = (const uint8_t*)key; 160 const int nblocks = len / 16; 161 162 uint32_t h1 = seed; 163 uint32_t h2 = seed; 164 uint32_t h3 = seed; 165 uint32_t h4 = seed; 166 167 uint32_t c1 = 0x239b961b; 168 uint32_t c2 = 0xab0e9789; 169 uint32_t c3 = 0x38b34ae5; 170 uint32_t c4 = 0xa1e38b93; 171 172 uint32_t k1; 173 uint32_t k2; 174 uint32_t k3; 175 uint32_t k4; 176 177 const uint32_t * blocks; 178 const uint8_t * tail; 179 180 int i; 181 182 //---------- 183 // body 184 185 blocks = (const uint32_t *)(data + nblocks*16); 186 187 for(i = -nblocks; i; i++) 188 { 189 k1 = getblock_32(blocks,i*4+0); 190 k2 = getblock_32(blocks,i*4+1); 191 k3 = getblock_32(blocks,i*4+2); 192 k4 = getblock_32(blocks,i*4+3); 193 194 k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; 195 196 h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; 197 198 k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; 199 200 h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; 201 202 k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; 203 204 h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; 205 206 k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; 207 208 h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; 209 } 210 211 //---------- 212 // tail 213 214 tail = (const uint8_t*)(data + nblocks*16); 215 216 k1 = 0; 217 k2 = 0; 218 k3 = 0; 219 k4 = 0; 220 221 switch(len & 15) 222 { 223 case 15: k4 ^= tail[14] << 16; 224 case 14: k4 ^= tail[13] << 8; 225 case 13: k4 ^= tail[12] << 0; 226 k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; 227 228 case 12: k3 ^= tail[11] << 24; 229 case 11: k3 ^= tail[10] << 16; 230 case 10: k3 ^= tail[ 9] << 8; 231 case 9: k3 ^= tail[ 8] << 0; 232 k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; 233 234 case 8: k2 ^= tail[ 7] << 24; 235 case 7: k2 ^= tail[ 6] << 16; 236 case 6: k2 ^= tail[ 5] << 8; 237 case 5: k2 ^= tail[ 4] << 0; 238 k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; 239 240 case 4: k1 ^= tail[ 3] << 24; 241 case 3: k1 ^= tail[ 2] << 16; 242 case 2: k1 ^= tail[ 1] << 8; 243 case 1: k1 ^= tail[ 0] << 0; 244 k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; 245 }; 246 247 //---------- 248 // finalization 249 250 h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; 251 252 h1 += h2; h1 += h3; h1 += h4; 253 h2 += h1; h3 += h1; h4 += h1; 254 255 h1 = fmix_32(h1); 256 h2 = fmix_32(h2); 257 h3 = fmix_32(h3); 258 h4 = fmix_32(h4); 259 260 h1 += h2; h1 += h3; h1 += h4; 261 h2 += h1; h3 += h1; h4 += h1; 262 263 ((uint32_t*)out)[0] = h1; 264 ((uint32_t*)out)[1] = h2; 265 ((uint32_t*)out)[2] = h3; 266 ((uint32_t*)out)[3] = h4; 267} 268 269//----------------------------------------------------------------------------- 270 271void MurmurHash3_x64_128 ( const void * key, const int len, 272 const uint32_t seed, void * out ) 273{ 274 const uint8_t * data = (const uint8_t*)key; 275 const int nblocks = len / 16; 276 277 uint64_t h1 = seed; 278 uint64_t h2 = seed; 279 280 uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); 281 uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); 282 283 const uint64_t * blocks; 284 const uint8_t * tail; 285 286 uint64_t k1; 287 uint64_t k2; 288 289 int i; 290 //---------- 291 // body 292 293 blocks = (const uint64_t *)(data); 294 295 for(i = 0; i < nblocks; i++) 296 { 297 k1 = getblock_64(blocks,i*2+0); 298 k2 = getblock_64(blocks,i*2+1); 299 300 k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; 301 302 h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; 303 304 k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; 305 306 h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; 307 } 308 309 //---------- 310 // tail 311 312 tail = (const uint8_t*)(data + nblocks*16); 313 314 k1 = 0; 315 k2 = 0; 316 317 switch(len & 15) 318 { 319 case 15: k2 ^= ((uint64_t)tail[14]) << 48; 320 case 14: k2 ^= ((uint64_t)tail[13]) << 40; 321 case 13: k2 ^= ((uint64_t)tail[12]) << 32; 322 case 12: k2 ^= ((uint64_t)tail[11]) << 24; 323 case 11: k2 ^= ((uint64_t)tail[10]) << 16; 324 case 10: k2 ^= ((uint64_t)tail[ 9]) << 8; 325 case 9: k2 ^= ((uint64_t)tail[ 8]) << 0; 326 k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; 327 328 case 8: k1 ^= ((uint64_t)tail[ 7]) << 56; 329 case 7: k1 ^= ((uint64_t)tail[ 6]) << 48; 330 case 6: k1 ^= ((uint64_t)tail[ 5]) << 40; 331 case 5: k1 ^= ((uint64_t)tail[ 4]) << 32; 332 case 4: k1 ^= ((uint64_t)tail[ 3]) << 24; 333 case 3: k1 ^= ((uint64_t)tail[ 2]) << 16; 334 case 2: k1 ^= ((uint64_t)tail[ 1]) << 8; 335 case 1: k1 ^= ((uint64_t)tail[ 0]) << 0; 336 k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; 337 }; 338 339 //---------- 340 // finalization 341 342 h1 ^= len; h2 ^= len; 343 344 h1 += h2; 345 h2 += h1; 346 347 h1 = fmix_64(h1); 348 h2 = fmix_64(h2); 349 350 h1 += h2; 351 h2 += h1; 352 353 ((uint64_t*)out)[0] = h1; 354 ((uint64_t*)out)[1] = h2; 355} 356 357//----------------------------------------------------------------------------- 358