automotive-dlt
city_c.c
Go to the documentation of this file.
1 // Copyright (c) 2011 Google, Inc.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 //
21 // CityHash, by Geoff Pike and Jyrki Alakuijala
22 //
23 // This file provides CityHash64() and related functions.
24 //
25 // It's probably possible to create even faster hash functions by
26 // writing a program that systematically explores some of the space of
27 // possible hash functions, by using SIMD instructions, or by
28 // compromising on hash quality.
29 
30 #include "city_c.h"
31 #include <string.h>
32 
33 #if defined(__sparc) || defined(__sparc__) \
34  || defined(_POWER) || defined(__powerpc__) \
35 || defined(__ppc__) || defined(__hpux) || defined(__hppa) \
36 || defined(_MIPSEB) || defined(_POWER) \
37 || defined(__s390__)
38 # define WORDS_BIGENDIAN
39 #elif defined(__i386__) || defined(__alpha__) \
40  || defined(__ia64) || defined(__ia64__) \
41 || defined(_M_IX86) || defined(_M_IA64) \
42 || defined(_M_ALPHA) || defined(__amd64) \
43 || defined(__amd64__) || defined(_M_AMD64) \
44 || defined(__x86_64) || defined(__x86_64__) \
45 || defined(_M_X64) || defined(__bfin__)
46 # define WORDS_LITTLEENDIAN
47 #endif
48 
49 #if !defined(WORDS_BIGENDIAN)
50 # define uint32_in_expected_order(x) (x)
51 # define uint64_in_expected_order(x) (x)
52 #else
53 # if defined _MSC_VER
54 # include <stdlib.h>
55 # define bswap_32(x) _byteswap_ulong(x)
56 # define bswap_64(x) _byteswap_uint64(x)
57 # elif defined(__APPLE__)
58 // Mac OS X / Darwin features
59 # include <libkern/OSByteOrder.h>
60 # define bswap_32(x) OSSwapInt32(x)
61 # define bswap_64(x) OSSwapInt64(x)
62 # else
63 # include <byteswap.h>
64 # endif
65 # define uint32_in_expected_order(x) (bswap_32(x))
66 # define uint64_in_expected_order(x) (bswap_64(x))
67 #endif // WORDS_BIGENDIAN
68 
69 #if !defined inline
70 # ifdef _MSC_VER
71 # define inline __inline
72 # endif
73 #endif
74 
75 #if !defined LIKELY
76 # if defined __GNUC__ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))//GCC 2.96 above
77 # define LIKELY(x) (__builtin_expect(!!(x), 1))
78 # else
79 # define LIKELY(x) (x)
80 # endif
81 #endif
82 
83 #define UNSAFE_SWAP(type, a, b) do {type tmp;tmp=(a);(a)=(b);(b)=tmp;} while (0)
84 
85 static inline uint128 UInt128(uint64 low, uint64 high) {
86  uint128 val;
87  val.first = low;
88  val.second = high;
89  return val;
90 }
91 
92 static inline uint64 UNALIGNED_LOAD64(const char *p) {
93  uint64 result;
94  memcpy(&result, p, sizeof(result));
95  return result;
96 }
97 
98 static inline uint32 UNALIGNED_LOAD32(const char *p) {
99  uint32 result;
100  memcpy(&result, p, sizeof(result));
101  return result;
102 }
103 
105  // Murmur-inspired hashing.
106  static const uint64 kMul = 0x9ddfea08eb382d69ULL;
107  uint64 a, b;
108  a = (u ^ v) * kMul;
109  a ^= (a >> 47);
110  b = (v ^ a) * kMul;
111  b ^= (b >> 47);
112  b *= kMul;
113  return b;
114 }
115 
116 static inline uint64 Fetch64(const char *p) {
118 }
119 
120 static inline uint32 Fetch32(const char *p) {
122 }
123 
124 // Some primes between 2^63 and 2^64 for various uses.
125 static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
126 static const uint64 k1 = 0xb492b66fbe98f273ULL;
127 static const uint64 k2 = 0x9ae16a3b2f90404fULL;
128 static const uint64 k3 = 0xc949d7c7509e6557ULL;
129 
130 // Bitwise right rotate. Normally this will compile to a single
131 // instruction, especially if the shift is a manifest constant.
132 static inline uint64 Rotate(uint64 val, int shift) {
133  // Avoid shifting by 64: doing so yields an undefined result.
134  return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
135 }
136 
137 // Equivalent to Rotate(), but requires the second arg to be non-zero.
138 // On x86-64, and probably others, it's possible for this to compile
139 // to a single instruction if both args are already in registers.
140 static inline uint64 RotateByAtLeast1(uint64 val, int shift) {
141  return (val >> shift) | (val << (64 - shift));
142 }
143 
144 static inline uint64 ShiftMix(uint64 val) {
145  return val ^ (val >> 47);
146 }
147 
148 static inline uint64 HashLen16(uint64 u, uint64 v) {
149  //return Hash128to64(uint128(u, v));
150  return Hash64Pairto64(u, v);
151 }
152 
153 static uint64 HashLen0to16(const char *s, size_t len) {
154  if (len > 8) {
155  uint64 a = Fetch64(s);
156  uint64 b = Fetch64(s + len - 8);
157  return HashLen16(a, RotateByAtLeast1(b + len, len)) ^ b;
158  }
159  if (len >= 4) {
160  uint64 a = Fetch32(s);
161  return HashLen16(len + (a << 3), Fetch32(s + len - 4));
162  }
163  if (len > 0) {
164  uint8 a = s[0];
165  uint8 b = s[len >> 1];
166  uint8 c = s[len - 1];
167  uint32 y = (uint32)a + ((uint32)b << 8);
168  uint32 z = len + ((uint32)c << 2);
169  return ShiftMix(y * k2 ^ z * k3) * k2;
170  }
171  return k2;
172 }
173 
174 // This probably works well for 16-byte strings as well, but it may be overkill
175 // in that case.
176 static uint64 HashLen17to32(const char *s, size_t len) {
177  uint64 a = Fetch64(s) * k1;
178  uint64 b = Fetch64(s + 8);
179  uint64 c = Fetch64(s + len - 8) * k2;
180  uint64 d = Fetch64(s + len - 16) * k0;
181  return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d,
182  a + Rotate(b ^ k3, 20) - c + len);
183 }
184 
185 // Return a 16-byte hash for 48 bytes. Quick and dirty.
186 // Callers do best to use "random-looking" values for a and b.
188  uint64 c;
189  a += w;
190  b = Rotate(b + a + z, 21);
191  c = a;
192  a += x;
193  a += y;
194  b += Rotate(a, 44);
195  return UInt128(a + z, b + c);
196 }
197 
198 // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
199 static uint128 WeakHashLen32WithSeeds3(const char* s, uint64 a, uint64 b) {
201  Fetch64(s + 8),
202  Fetch64(s + 16),
203  Fetch64(s + 24),
204  a,
205  b);
206 }
207 
208 // Return an 8-byte hash for 33 to 64 bytes.
209 static uint64 HashLen33to64(const char *s, size_t len) {
210  uint64 z = Fetch64(s + 24);
211  uint64 a = Fetch64(s) + (len + Fetch64(s + len - 16)) * k0;
212  uint64 b = Rotate(a + z, 52);
213  uint64 c = Rotate(a, 37);
214  uint64 vf, vs, wf, ws, r;
215  a += Fetch64(s + 8);
216  c += Rotate(a, 7);
217  a += Fetch64(s + 16);
218  vf = a + z;
219  vs = b + Rotate(a, 31) + c;
220  a = Fetch64(s + 16) + Fetch64(s + len - 32);
221  z = Fetch64(s + len - 8);
222  b = Rotate(a + z, 52);
223  c = Rotate(a, 37);
224  a += Fetch64(s + len - 24);
225  c += Rotate(a, 7);
226  a += Fetch64(s + len - 16);
227  wf = a + z;
228  ws = b + Rotate(a, 31) + c;
229  r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0);
230  return ShiftMix(r * k0 + vs) * k2;
231 }
232 
233 uint64 CityHash64(const char *s, size_t len) {
234  if (len <= 32) {
235  if (len <= 16) {
236  return HashLen0to16(s, len);
237  } else {
238  return HashLen17to32(s, len);
239  }
240  } else if (len <= 64) {
241  return HashLen33to64(s, len);
242  }
243 
244  do {
245  // For strings over 64 bytes we hash the end first, and then as we
246  // loop we keep 56 bytes of state: v, w, x, y, and z.
247  uint64 x = Fetch64(s + len - 40);
248  uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56);
249  uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24));
250  uint128 v = WeakHashLen32WithSeeds3(s + len - 64, len, z);
251  uint128 w = WeakHashLen32WithSeeds3(s + len - 32, y + k1, x);
252  x = x * k1 + Fetch64(s);
253 
254  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
255  len = (len - 1) & ~(size_t)63;
256  do {
257  x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
258  y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
259  x ^= w.second;
260  y += v.first + Fetch64(s + 40);
261  z = Rotate(z + w.first, 33) * k1;
262  v = WeakHashLen32WithSeeds3(s, v.second * k1, x + w.first);
263  w = WeakHashLen32WithSeeds3(s + 32, z + w.second, y + Fetch64(s + 16));
264  UNSAFE_SWAP(uint64, z, x);
265  s += 64;
266  len -= 64;
267  } while (len != 0);
268  return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
269  HashLen16(v.second, w.second) + x);
270  } while(0);
271 }
272 
273 uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) {
274  return CityHash64WithSeeds(s, len, k2, seed);
275 }
276 
277 uint64 CityHash64WithSeeds(const char *s, size_t len, uint64 seed0, uint64 seed1) {
278  return HashLen16(CityHash64(s, len) - seed0, seed1);
279 }
280 
281 // A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
282 // of any length representable in signed long. Based on City and Murmur.
283 static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
284  uint64 a = Uint128Low64(seed);
285  uint64 b = Uint128High64(seed);
286  uint64 c = 0;
287  uint64 d = 0;
288  signed long l = len - 16;
289  if (l <= 0) { // len <= 16
290  a = ShiftMix(a * k1) * k1;
291  c = b * k1 + HashLen0to16(s, len);
292  d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c));
293  } else { // len > 16
294  c = HashLen16(Fetch64(s + len - 8) + k1, a);
295  d = HashLen16(b + len, c + Fetch64(s + len - 16));
296  a += d;
297  do {
298  a ^= ShiftMix(Fetch64(s) * k1) * k1;
299  a *= k1;
300  b ^= a;
301  c ^= ShiftMix(Fetch64(s + 8) * k1) * k1;
302  c *= k1;
303  d ^= c;
304  s += 16;
305  l -= 16;
306  } while (l > 0);
307  }
308  a = HashLen16(a, c);
309  b = HashLen16(d, b);
310  return UInt128(a ^ b, HashLen16(b, a));
311 }
312 
313 uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
314  if (len < 128) {
315  return CityMurmur(s, len, seed);
316  }
317 
318  do {
319  // We expect len >= 128 to be the common case. Keep 56 bytes of state:
320  // v, w, x, y, and z.
321  uint128 v, w;
322  uint64 x = Uint128Low64(seed);
323  uint64 y = Uint128High64(seed);
324  uint64 z = len * k1;
325  size_t tail_done;
326  v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
327  v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
328  w.first = Rotate(y + z, 35) * k1 + x;
329  w.second = Rotate(x + Fetch64(s + 88), 53) * k1;
330 
331  // This is the same inner loop as CityHash64(), manually unrolled.
332  do {
333  x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
334  y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
335  x ^= w.second;
336  y += v.first + Fetch64(s + 40);
337  z = Rotate(z + w.first, 33) * k1;
338  v = WeakHashLen32WithSeeds3(s, v.second * k1, x + w.first);
339  w = WeakHashLen32WithSeeds3(s + 32, z + w.second, y + Fetch64(s + 16));
340  UNSAFE_SWAP(uint64, z, x);
341  s += 64;
342  x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
343  y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
344  x ^= w.second;
345  y += v.first + Fetch64(s + 40);
346  z = Rotate(z + w.first, 33) * k1;
347  v = WeakHashLen32WithSeeds3(s, v.second * k1, x + w.first);
348  w = WeakHashLen32WithSeeds3(s + 32, z + w.second, y + Fetch64(s + 16));
349  UNSAFE_SWAP(uint64, z, x);
350  s += 64;
351  len -= 128;
352  } while (LIKELY(len >= 128));
353  x += Rotate(v.first + z, 49) * k0;
354  z += Rotate(w.first, 37) * k0;
355  // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
356  for (tail_done = 0; tail_done < len; ) {
357  tail_done += 32;
358  y = Rotate(x + y, 42) * k0 + v.second;
359  w.first += Fetch64(s + len - tail_done + 16);
360  x = x * k0 + w.first;
361  z += w.second + Fetch64(s + len - tail_done);
362  w.second += v.first;
363  v = WeakHashLen32WithSeeds3(s + len - tail_done, v.first + z, v.second);
364  }
365  // At this point our 56 bytes of state should contain more than
366  // enough information for a strong 128-bit hash. We use two
367  // different 56-byte-to-8-byte hashes to get a 16-byte final result.
368  x = HashLen16(x, v.first);
369  y = HashLen16(y + z, w.first);
370  return UInt128(HashLen16(x + v.second, w.second) + y,
371  HashLen16(x + w.second, y + v.second));
372  } while(0);
373 }
374 
375 uint128 CityHash128(const char *s, size_t len) {
376  if (len >= 16) {
377  return CityHash128WithSeed(s + 16,
378  len - 16,
379  UInt128(Fetch64(s) ^ k3,
380  Fetch64(s + 8)));
381  } else if (len >= 8) {
382  return CityHash128WithSeed(NULL,
383  0,
384  UInt128(Fetch64(s) ^ (len * k0),
385  Fetch64(s + len - 8) ^ k1));
386  } else {
387  return CityHash128WithSeed(s, len, UInt128(k0, k1));
388  }
389 }
390 
391 #ifdef __SSE4_2__
392 #include "citycrc_c.h"
393 #include <nmmintrin.h>
394 
395 // Requires len >= 240.
396 static void CityHashCrc256Long(const char *s, size_t len, uint32 seed, uint64 *result) {
397  uint64 a = Fetch64(s + 56) + k0;
398  uint64 b = Fetch64(s + 96) + k0;
399  uint64 c = result[0] = HashLen16(b, len);
400  uint64 d = result[1] = Fetch64(s + 120) * k0 + len;
401  uint64 e = Fetch64(s + 184) + seed;
402  uint64 f = seed;
403  uint64 g = 0;
404  uint64 h = 0;
405  uint64 i = 0;
406  uint64 j = 0;
407  uint64 t = c + d;
408 
409  // 240 bytes of input per iter.
410  size_t iters = len / 240;
411  len -= iters * 240;
412  do {
413 #define CHUNK(multiplier, z) \
414  { \
415  uint64 old_a = a; \
416  a = Rotate(b, 41 ^ z) * multiplier + Fetch64(s); \
417  b = Rotate(c, 27 ^ z) * multiplier + Fetch64(s + 8); \
418  c = Rotate(d, 41 ^ z) * multiplier + Fetch64(s + 16); \
419  d = Rotate(e, 33 ^ z) * multiplier + Fetch64(s + 24); \
420  e = Rotate(t, 25 ^ z) * multiplier + Fetch64(s + 32); \
421  t = old_a; \
422  } \
423  f = _mm_crc32_u64(f, a); \
424  g = _mm_crc32_u64(g, b); \
425  h = _mm_crc32_u64(h, c); \
426  i = _mm_crc32_u64(i, d); \
427  j = _mm_crc32_u64(j, e); \
428  s += 40
429 
430  CHUNK(1, 1); CHUNK(k0, 0);
431  CHUNK(1, 1); CHUNK(k0, 0);
432  CHUNK(1, 1); CHUNK(k0, 0);
433  } while (--iters > 0);
434 
435  while (len >= 40) {
436  CHUNK(k0, 0);
437  len -= 40;
438  }
439  if (len > 0) {
440  s = s + len - 40;
441  CHUNK(k0, 0);
442  }
443  j += i << 32;
444  a = HashLen16(a, j);
445  h += g << 32;
446  b += h;
447  c = HashLen16(c, f) + i;
448  d = HashLen16(d, e + result[0]);
449  j += e;
450  i += HashLen16(h, t);
451  e = HashLen16(a, d) + j;
452  f = HashLen16(b, c) + a;
453  g = HashLen16(j, i) + c;
454  result[0] = e + f + g + h;
455  a = ShiftMix((a + g) * k0) * k0 + b;
456  result[1] += a + result[0];
457  a = ShiftMix(a * k0) * k0 + c;
458  result[2] = a + result[1];
459  a = ShiftMix((a + e) * k0) * k0;
460  result[3] = a + result[2];
461 }
462 
463 // Requires len < 240.
464 static inline void CityHashCrc256Short(const char *s, size_t len, uint64 *result) {
465  char buf[240];
466  memcpy(buf, s, len);
467  memset(buf + len, 0, 240 - len);
468  CityHashCrc256Long(buf, 240, ~(uint32)len, result);
469 }
470 
471 void CityHashCrc256(const char *s, size_t len, uint64 *result) {
472  if (LIKELY(len >= 240)) {
473  CityHashCrc256Long(s, len, 0, result);
474  } else {
475  CityHashCrc256Short(s, len, result);
476  }
477 }
478 
479 uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) {
480  if (len <= 900) {
481  return CityHash128WithSeed(s, len, seed);
482  } else {
483  uint64 result[4], u, v;
484  CityHashCrc256(s, len, result);
485  u = Uint128High64(seed) + result[0];
486  v = Uint128Low64(seed) + result[1];
487  return UInt128(HashLen16(u, v + result[2]),
488  HashLen16(Rotate(v, 32), u * k0 + result[3]));
489  }
490 }
491 
492 uint128 CityHashCrc128(const char *s, size_t len) {
493  if (len <= 900) {
494  return CityHash128(s, len);
495  } else {
496  uint64 result[4];
497  CityHashCrc256(s, len, result);
498  return UInt128(result[2], result[3]);
499  }
500 }
501 
502 #endif
static uint32 Fetch32(const char *p)
Definition: city_c.c:120
static uint128 WeakHashLen32WithSeeds3(const char *s, uint64 a, uint64 b)
Definition: city_c.c:199
uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed)
Definition: city_c.c:313
uint64_t uint64
Definition: city_c.h:55
uint128 CityHash128(const char *s, size_t len)
Definition: city_c.c:375
uint128 CityHashCrc128(const char *s, size_t len)
uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed)
#define LIKELY(x)
Definition: city_c.c:79
#define UNSAFE_SWAP(type, a, b)
Definition: city_c.c:83
static uint64 RotateByAtLeast1(uint64 val, int shift)
Definition: city_c.c:140
static uint64 UNALIGNED_LOAD64(const char *p)
Definition: city_c.c:92
uint64 CityHash64WithSeeds(const char *s, size_t len, uint64 seed0, uint64 seed1)
Definition: city_c.c:277
static uint32 UNALIGNED_LOAD32(const char *p)
Definition: city_c.c:98
uint64 first
Definition: city_c.h:65
uint64 second
Definition: city_c.h:65
#define Uint128Low64(x)
Definition: city_c.h:69
#define Uint128High64(x)
Definition: city_c.h:70
static uint64 Rotate(uint64 val, int shift)
Definition: city_c.c:132
uint64 CityHash64(const char *s, size_t len)
Definition: city_c.c:233
static uint64 HashLen17to32(const char *s, size_t len)
Definition: city_c.c:176
static uint64 Hash64Pairto64(uint64 u, uint64 v)
Definition: city_c.c:104
#define uint32_in_expected_order(x)
Definition: city_c.c:50
Definition: city_c.h:63
static uint128 WeakHashLen32WithSeeds6(uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b)
Definition: city_c.c:187
static const uint64 k1
Definition: city_c.c:126
static const uint64 k0
Definition: city_c.c:125
static uint128 CityMurmur(const char *s, size_t len, uint128 seed)
Definition: city_c.c:283
uint8_t uint8
Definition: city_c.h:53
static const uint64 k3
Definition: city_c.c:128
uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed)
Definition: city_c.c:273
static uint64 Fetch64(const char *p)
Definition: city_c.c:116
static uint64 ShiftMix(uint64 val)
Definition: city_c.c:144
static uint64 HashLen0to16(const char *s, size_t len)
Definition: city_c.c:153
#define uint64_in_expected_order(x)
Definition: city_c.c:51
static uint128 UInt128(uint64 low, uint64 high)
Definition: city_c.c:85
static const uint64 k2
Definition: city_c.c:127
static uint64 HashLen33to64(const char *s, size_t len)
Definition: city_c.c:209
uint32_t uint32
Definition: city_c.h:54
static uint64 HashLen16(uint64 u, uint64 v)
Definition: city_c.c:148
#define NULL
Definition: dlt_common.h:232
void CityHashCrc256(const char *s, size_t len, uint64 *result)