00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifdef _WIN32
00011 #include <stddef.h>
00012 typedef __int8 int8_t;
00013 typedef unsigned __int8 uint8_t;
00014 typedef unsigned __int16 uint16_t;
00015 typedef unsigned __int32 uint32_t;
00016 typedef unsigned __int64 uint64_t;
00017 #elif (defined(SOLARIS) || defined(sun) || defined(HAVE_INTTYPES_H) \
00018 || defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD_kernel__))
00019 #include <inttypes.h>
00020 #else
00021 #include <stdint.h>
00022 #endif
00023
00024 static uint32_t rotl32 ( uint32_t x, int8_t r )
00025 {
00026 return (x << r) | (x >> (32 - r));
00027 }
00028 #define ROTL32(x,y) rotl32(x,y)
00029 static uint32_t getblock32 ( const uint32_t * p, int i )
00030 {
00031 return p[i];
00032 }
00033 static uint32_t fmix32 ( uint32_t h )
00034 {
00035 h ^= h >> 16;
00036 h *= 0x85ebca6b;
00037 h ^= h >> 13;
00038 h *= 0xc2b2ae35;
00039 h ^= h >> 16;
00040
00041 return h;
00042 }
00043 #define BIG_CONSTANT(x) (x##LLU)
00044 static void MurmurHash3_x86_128 ( const void * key, const int len,
00045 uint32_t seed, void * out ) {
00046 const uint8_t * data = (const uint8_t*)key;
00047 const int nblocks = len / 16;
00048
00049 uint32_t h1 = seed;
00050 uint32_t h2 = seed;
00051 uint32_t h3 = seed;
00052 uint32_t h4 = seed;
00053
00054 const uint32_t c1 = 0x239b961b;
00055 const uint32_t c2 = 0xab0e9789;
00056 const uint32_t c3 = 0x38b34ae5;
00057 const uint32_t c4 = 0xa1e38b93;
00058
00059 const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
00060 int i;
00061
00062 for(i = -nblocks; i; i++)
00063 {
00064 uint32_t k1 = getblock32(blocks,i*4+0);
00065 uint32_t k2 = getblock32(blocks,i*4+1);
00066 uint32_t k3 = getblock32(blocks,i*4+2);
00067 uint32_t k4 = getblock32(blocks,i*4+3);
00068
00069 k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
00070
00071 h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
00072
00073 k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
00074
00075 h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
00076
00077 k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
00078
00079 h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
00080
00081 k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
00082
00083 h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
00084 }
00085
00086 {
00087 const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
00088
00089 uint32_t k1 = 0;
00090 uint32_t k2 = 0;
00091 uint32_t k3 = 0;
00092 uint32_t k4 = 0;
00093
00094 switch(len & 15)
00095 {
00096 case 15: k4 ^= tail[14] << 16;
00097 case 14: k4 ^= tail[13] << 8;
00098 case 13: k4 ^= tail[12] << 0;
00099 k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
00100
00101 case 12: k3 ^= tail[11] << 24;
00102 case 11: k3 ^= tail[10] << 16;
00103 case 10: k3 ^= tail[ 9] << 8;
00104 case 9: k3 ^= tail[ 8] << 0;
00105 k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
00106
00107 case 8: k2 ^= tail[ 7] << 24;
00108 case 7: k2 ^= tail[ 6] << 16;
00109 case 6: k2 ^= tail[ 5] << 8;
00110 case 5: k2 ^= tail[ 4] << 0;
00111 k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
00112
00113 case 4: k1 ^= tail[ 3] << 24;
00114 case 3: k1 ^= tail[ 2] << 16;
00115 case 2: k1 ^= tail[ 1] << 8;
00116 case 1: k1 ^= tail[ 0] << 0;
00117 k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
00118 };
00119
00120
00121 h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
00122
00123 h1 += h2; h1 += h3; h1 += h4;
00124 h2 += h1; h3 += h1; h4 += h1;
00125
00126 h1 = fmix32(h1);
00127 h2 = fmix32(h2);
00128 h3 = fmix32(h3);
00129 h4 = fmix32(h4);
00130
00131 h1 += h2; h1 += h3; h1 += h4;
00132 h2 += h1; h3 += h1; h4 += h1;
00133
00134 ((uint32_t*)out)[0] = h1;
00135 ((uint32_t*)out)[1] = h2;
00136 ((uint32_t*)out)[2] = h3;
00137 ((uint32_t*)out)[3] = h4;
00138 }
00139 }