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