blob: 4322bb852d60f1765d27d21089c64755488a8292 [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#include "MurmurHash1.h"
2
3//-----------------------------------------------------------------------------
4// MurmurHash1, by Austin Appleby
5
6// Note - This code makes a few assumptions about how your machine behaves -
7
8// 1. We can read a 4-byte value from any address without crashing
9// 2. sizeof(int) == 4
10
11// And it has a few limitations -
12
13// 1. It will not work incrementally.
14// 2. It will not produce the same results on little-endian and big-endian
15// machines.
16
17uint32_t MurmurHash1 ( const void * key, int len, uint32_t seed )
18{
19 const unsigned int m = 0xc6a4a793;
20
21 const int r = 16;
22
23 unsigned int h = seed ^ (len * m);
24
25 //----------
26
27 const unsigned char * data = (const unsigned char *)key;
28
29 while(len >= 4)
30 {
31 unsigned int k = *(unsigned int *)data;
32
33 h += k;
34 h *= m;
35 h ^= h >> 16;
36
37 data += 4;
38 len -= 4;
39 }
40
41 //----------
42
43 switch(len)
44 {
45 case 3:
46 h += data[2] << 16;
47 case 2:
48 h += data[1] << 8;
49 case 1:
50 h += data[0];
51 h *= m;
52 h ^= h >> r;
53 };
54
55 //----------
56
57 h *= m;
58 h ^= h >> 10;
59 h *= m;
60 h ^= h >> 17;
61
62 return h;
63}
64
65//-----------------------------------------------------------------------------
66// MurmurHash1Aligned, by Austin Appleby
67
68// Same algorithm as MurmurHash1, but only does aligned reads - should be safer
69// on certain platforms.
70
71// Performance should be equal to or better than the simple version.
72
73unsigned int MurmurHash1Aligned ( const void * key, int len, unsigned int seed )
74{
75 const unsigned int m = 0xc6a4a793;
76 const int r = 16;
77
78 const unsigned char * data = (const unsigned char *)key;
79
80 unsigned int h = seed ^ (len * m);
81
82 int align = (int)data & 3;
83
84 if(align && (len >= 4))
85 {
86 // Pre-load the temp registers
87
88 unsigned int t = 0, d = 0;
89
90 switch(align)
91 {
92 case 1: t |= data[2] << 16;
93 case 2: t |= data[1] << 8;
94 case 3: t |= data[0];
95 }
96
97 t <<= (8 * align);
98
99 data += 4-align;
100 len -= 4-align;
101
102 int sl = 8 * (4-align);
103 int sr = 8 * align;
104
105 // Mix
106
107 while(len >= 4)
108 {
109 d = *(unsigned int *)data;
110 t = (t >> sr) | (d << sl);
111 h += t;
112 h *= m;
113 h ^= h >> r;
114 t = d;
115
116 data += 4;
117 len -= 4;
118 }
119
120 // Handle leftover data in temp registers
121
122 int pack = len < align ? len : align;
123
124 d = 0;
125
126 switch(pack)
127 {
128 case 3: d |= data[2] << 16;
129 case 2: d |= data[1] << 8;
130 case 1: d |= data[0];
131 case 0: h += (t >> sr) | (d << sl);
132 h *= m;
133 h ^= h >> r;
134 }
135
136 data += pack;
137 len -= pack;
138 }
139 else
140 {
141 while(len >= 4)
142 {
143 h += *(unsigned int *)data;
144 h *= m;
145 h ^= h >> r;
146
147 data += 4;
148 len -= 4;
149 }
150 }
151
152 //----------
153 // Handle tail bytes
154
155 switch(len)
156 {
157 case 3: h += data[2] << 16;
158 case 2: h += data[1] << 8;
159 case 1: h += data[0];
160 h *= m;
161 h ^= h >> r;
162 };
163
164 h *= m;
165 h ^= h >> 10;
166 h *= m;
167 h ^= h >> 17;
168
169 return h;
170}
171