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 
rotl32(uint32_t x,int8_t r)6 uint32_t rotl32 ( uint32_t x, int8_t r )
7 {
8   return (x << r) | (x >> (32 - r));
9 }
10 
fmix32(uint32_t h)11 uint32_t fmix32 ( uint32_t h )
12 {
13   h ^= h >> 16;
14   h *= 0x85ebca6b;
15   h ^= h >> 13;
16   h *= 0xc2b2ae35;
17   h ^= h >> 16;
18 
19   return h;
20 }
21 
MurmurHash3_x86_32(const void * key,int len,uint32_t seed,void * out)22 void MurmurHash3_x86_32 ( const void * key, int len,
23                           uint32_t seed, void * out )
24 {
25   const uint8_t * data = (const uint8_t*)key;
26   const int nblocks = len / 4;
27 
28   uint32_t h1 = seed;
29 
30   const uint32_t c1 = 0xcc9e2d51;
31   const uint32_t c2 = 0x1b873593;
32 
33   //----------
34   // body
35 
36   const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
37 
38   for(int i = -nblocks; i; i++)
39   {
40     uint32_t k1 = blocks[i];
41 
42     k1 *= c1;
43     k1 = rotl32(k1,15);
44     k1 *= c2;
45 
46     h1 ^= k1;
47     h1 = rotl32(h1,13);
48     h1 = h1*5+0xe6546b64;
49   }
50 
51   //----------
52   // tail
53 
54   const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
55 
56   uint32_t k1 = 0;
57 
58   switch(len & 3)
59   {
60   case 3: k1 ^= tail[2] << 16;
61   case 2: k1 ^= tail[1] << 8;
62   case 1: k1 ^= tail[0];
63           k1 *= c1; k1 = rotl32(k1,15); k1 *= c2; h1 ^= k1;
64   };
65 
66   //----------
67   // finalization
68 
69   h1 ^= len;
70 
71   h1 = fmix32(h1);
72 
73   *(uint32_t*)out = h1;
74 }
75