Coverage Report

Created: 2024-11-21 07:03

/src/cityhash/src/city.cc
Line
Count
Source (jump to first uncovered line)
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 "config.h"
31
#include <city.h>
32
33
#include <algorithm>
34
#include <string.h>  // for memcpy and memset
35
36
using namespace std;
37
38
427k
static uint64 UNALIGNED_LOAD64(const char *p) {
39
427k
  uint64 result;
40
427k
  memcpy(&result, p, sizeof(result));
41
427k
  return result;
42
427k
}
43
44
27.1k
static uint32 UNALIGNED_LOAD32(const char *p) {
45
27.1k
  uint32 result;
46
27.1k
  memcpy(&result, p, sizeof(result));
47
27.1k
  return result;
48
27.1k
}
49
50
#ifdef _MSC_VER
51
52
#include <stdlib.h>
53
#define bswap_32(x) _byteswap_ulong(x)
54
#define bswap_64(x) _byteswap_uint64(x)
55
56
#elif defined(__APPLE__)
57
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
63
#elif defined(__sun) || defined(sun)
64
65
#include <sys/byteorder.h>
66
#define bswap_32(x) BSWAP_32(x)
67
#define bswap_64(x) BSWAP_64(x)
68
69
#elif defined(__FreeBSD__)
70
71
#include <sys/endian.h>
72
#define bswap_32(x) bswap32(x)
73
#define bswap_64(x) bswap64(x)
74
75
#elif defined(__OpenBSD__)
76
77
#include <sys/types.h>
78
#define bswap_32(x) swap32(x)
79
#define bswap_64(x) swap64(x)
80
81
#elif defined(__NetBSD__)
82
83
#include <sys/types.h>
84
#include <machine/bswap.h>
85
#if defined(__BSWAP_RENAME) && !defined(__bswap_32)
86
#define bswap_32(x) bswap32(x)
87
#define bswap_64(x) bswap64(x)
88
#endif
89
90
#else
91
92
#include <byteswap.h>
93
94
#endif
95
96
#ifdef WORDS_BIGENDIAN
97
#define uint32_in_expected_order(x) (bswap_32(x))
98
#define uint64_in_expected_order(x) (bswap_64(x))
99
#else
100
27.1k
#define uint32_in_expected_order(x) (x)
101
427k
#define uint64_in_expected_order(x) (x)
102
#endif
103
104
#if !defined(LIKELY)
105
#if HAVE_BUILTIN_EXPECT
106
4.20k
#define LIKELY(x) (__builtin_expect(!!(x), 1))
107
#else
108
#define LIKELY(x) (x)
109
#endif
110
#endif
111
112
427k
static uint64 Fetch64(const char *p) {
113
427k
  return uint64_in_expected_order(UNALIGNED_LOAD64(p));
114
427k
}
115
116
27.1k
static uint32 Fetch32(const char *p) {
117
27.1k
  return uint32_in_expected_order(UNALIGNED_LOAD32(p));
118
27.1k
}
119
120
// Some primes between 2^63 and 2^64 for various uses.
121
static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
122
static const uint64 k1 = 0xb492b66fbe98f273ULL;
123
static const uint64 k2 = 0x9ae16a3b2f90404fULL;
124
125
// Magic numbers for 32-bit hashing.  Copied from Murmur3.
126
static const uint32 c1 = 0xcc9e2d51;
127
static const uint32 c2 = 0x1b873593;
128
129
// A 32-bit to 32-bit integer hash copied from Murmur3.
130
static uint32 fmix(uint32 h)
131
1
{
132
1
  h ^= h >> 16;
133
1
  h *= 0x85ebca6b;
134
1
  h ^= h >> 13;
135
1
  h *= 0xc2b2ae35;
136
1
  h ^= h >> 16;
137
1
  return h;
138
1
}
139
140
38.2k
static uint32 Rotate32(uint32 val, int shift) {
141
  // Avoid shifting by 32: doing so yields an undefined result.
142
38.2k
  return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
143
38.2k
}
144
145
#undef PERMUTE3
146
105k
#define PERMUTE3(a, b, c) do { std::swap(a, b); std::swap(a, c); } while (0)
147
148
3
static uint32 Mur(uint32 a, uint32 h) {
149
  // Helper from Murmur3 for combining two 32-bit values.
150
3
  a *= c1;
151
3
  a = Rotate32(a, 17);
152
3
  a *= c2;
153
3
  h ^= a;
154
3
  h = Rotate32(h, 19);
155
3
  return h * 5 + 0xe6546b64;
156
3
}
157
158
0
static uint32 Hash32Len13to24(const char *s, size_t len) {
159
0
  uint32 a = Fetch32(s - 4 + (len >> 1));
160
0
  uint32 b = Fetch32(s + 4);
161
0
  uint32 c = Fetch32(s + len - 8);
162
0
  uint32 d = Fetch32(s + (len >> 1));
163
0
  uint32 e = Fetch32(s);
164
0
  uint32 f = Fetch32(s + len - 4);
165
0
  uint32 h = static_cast<uint32>(len);
166
167
0
  return fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h)))))));
168
0
}
169
170
0
static uint32 Hash32Len0to4(const char *s, size_t len) {
171
0
  uint32 b = 0;
172
0
  uint32 c = 9;
173
0
  for (size_t i = 0; i < len; i++) {
174
0
    signed char v = static_cast<signed char>(s[i]);
175
0
    b = b * c1 + static_cast<uint32>(v);
176
0
    c ^= b;
177
0
  }
178
0
  return fmix(Mur(b, Mur(static_cast<uint32>(len), c)));
179
0
}
180
181
1
static uint32 Hash32Len5to12(const char *s, size_t len) {
182
1
  uint32 a = static_cast<uint32>(len), b = a * 5, c = 9, d = b;
183
1
  a += Fetch32(s);
184
1
  b += Fetch32(s + len - 4);
185
1
  c += Fetch32(s + ((len >> 1) & 4));
186
1
  return fmix(Mur(c, Mur(b, Mur(a, d))));
187
1
}
188
189
21
uint32 CityHash32(const char *s, size_t len) {
190
21
  if (len <= 24) {
191
1
    return len <= 12 ?
192
1
        (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) :
193
1
        Hash32Len13to24(s, len);
194
1
  }
195
196
  // len > 24
197
20
  uint32 h = static_cast<uint32>(len), g = c1 * h, f = g;
198
20
  uint32 a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2;
199
20
  uint32 a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2;
200
20
  uint32 a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2;
201
20
  uint32 a3 = Rotate32(Fetch32(s + len - 12) * c1, 17) * c2;
202
20
  uint32 a4 = Rotate32(Fetch32(s + len - 20) * c1, 17) * c2;
203
20
  h ^= a0;
204
20
  h = Rotate32(h, 19);
205
20
  h = h * 5 + 0xe6546b64;
206
20
  h ^= a2;
207
20
  h = Rotate32(h, 19);
208
20
  h = h * 5 + 0xe6546b64;
209
20
  g ^= a1;
210
20
  g = Rotate32(g, 19);
211
20
  g = g * 5 + 0xe6546b64;
212
20
  g ^= a3;
213
20
  g = Rotate32(g, 19);
214
20
  g = g * 5 + 0xe6546b64;
215
20
  f += a4;
216
20
  f = Rotate32(f, 19);
217
20
  f = f * 5 + 0xe6546b64;
218
20
  size_t iters = (len - 1) / 20;
219
5.40k
  do {
220
5.40k
    uint32 a0 = Rotate32(Fetch32(s) * c1, 17) * c2;
221
5.40k
    uint32 a1 = Fetch32(s + 4);
222
5.40k
    uint32 a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2;
223
5.40k
    uint32 a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2;
224
5.40k
    uint32 a4 = Fetch32(s + 16);
225
5.40k
    h ^= a0;
226
5.40k
    h = Rotate32(h, 18);
227
5.40k
    h = h * 5 + 0xe6546b64;
228
5.40k
    f += a1;
229
5.40k
    f = Rotate32(f, 19);
230
5.40k
    f = f * c1;
231
5.40k
    g += a2;
232
5.40k
    g = Rotate32(g, 18);
233
5.40k
    g = g * 5 + 0xe6546b64;
234
5.40k
    h ^= a3 + a1;
235
5.40k
    h = Rotate32(h, 19);
236
5.40k
    h = h * 5 + 0xe6546b64;
237
5.40k
    g ^= a4;
238
5.40k
    g = bswap_32(g) * 5;
239
5.40k
    h += a4 * 5;
240
5.40k
    h = bswap_32(h);
241
5.40k
    f += a0;
242
5.40k
    PERMUTE3(f, h, g);
243
5.40k
    s += 20;
244
5.40k
  } while (--iters != 0);
245
20
  g = Rotate32(g, 11) * c1;
246
20
  g = Rotate32(g, 17) * c1;
247
20
  f = Rotate32(f, 11) * c1;
248
20
  f = Rotate32(f, 17) * c1;
249
20
  h = Rotate32(h + g, 19);
250
20
  h = h * 5 + 0xe6546b64;
251
20
  h = Rotate32(h, 17) * c1;
252
20
  h = Rotate32(h + f, 19);
253
20
  h = h * 5 + 0xe6546b64;
254
20
  h = Rotate32(h, 17) * c1;
255
20
  return h;
256
21
}
257
258
// Bitwise right rotate.  Normally this will compile to a single
259
// instruction, especially if the shift is a manifest constant.
260
153k
static uint64 Rotate(uint64 val, int shift) {
261
  // Avoid shifting by 64: doing so yields an undefined result.
262
153k
  return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
263
153k
}
264
265
154
static uint64 ShiftMix(uint64 val) {
266
154
  return val ^ (val >> 47);
267
154
}
268
269
545
static uint64 HashLen16(uint64 u, uint64 v) {
270
545
  return Hash128to64(uint128(u, v));
271
545
}
272
273
1
static uint64 HashLen16(uint64 u, uint64 v, uint64 mul) {
274
  // Murmur-inspired hashing.
275
1
  uint64 a = (u ^ v) * mul;
276
1
  a ^= (a >> 47);
277
1
  uint64 b = (v ^ a) * mul;
278
1
  b ^= (b >> 47);
279
1
  b *= mul;
280
1
  return b;
281
1
}
282
283
2
static uint64 HashLen0to16(const char *s, size_t len) {
284
2
  if (len >= 8) {
285
0
    uint64 mul = k2 + len * 2;
286
0
    uint64 a = Fetch64(s) + k2;
287
0
    uint64 b = Fetch64(s + len - 8);
288
0
    uint64 c = Rotate(b, 37) * mul + a;
289
0
    uint64 d = (Rotate(a, 25) + b) * mul;
290
0
    return HashLen16(c, d, mul);
291
0
  }
292
2
  if (len >= 4) {
293
1
    uint64 mul = k2 + len * 2;
294
1
    uint64 a = Fetch32(s);
295
1
    return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul);
296
1
  }
297
1
  if (len > 0) {
298
0
    uint8 a = static_cast<uint8>(s[0]);
299
0
    uint8 b = static_cast<uint8>(s[len >> 1]);
300
0
    uint8 c = static_cast<uint8>(s[len - 1]);
301
0
    uint32 y = static_cast<uint32>(a) + (static_cast<uint32>(b) << 8);
302
0
    uint32 z = static_cast<uint32>(len) + (static_cast<uint32>(c) << 2);
303
0
    return ShiftMix(y * k2 ^ z * k0) * k2;
304
0
  }
305
1
  return k2;
306
1
}
307
308
// This probably works well for 16-byte strings as well, but it may be overkill
309
// in that case.
310
0
static uint64 HashLen17to32(const char *s, size_t len) {
311
0
  uint64 mul = k2 + len * 2;
312
0
  uint64 a = Fetch64(s) * k1;
313
0
  uint64 b = Fetch64(s + 8);
314
0
  uint64 c = Fetch64(s + len - 8) * mul;
315
0
  uint64 d = Fetch64(s + len - 16) * k2;
316
0
  return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d,
317
0
                   a + Rotate(b + k2, 18) + c, mul);
318
0
}
319
320
// Return a 16-byte hash for 48 bytes.  Quick and dirty.
321
// Callers do best to use "random-looking" values for a and b.
322
static pair<uint64, uint64> WeakHashLen32WithSeeds(
323
29.2k
    uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) {
324
29.2k
  a += w;
325
29.2k
  b = Rotate(b + a + z, 21);
326
29.2k
  uint64 c = a;
327
29.2k
  a += x;
328
29.2k
  a += y;
329
29.2k
  b += Rotate(a, 44);
330
29.2k
  return make_pair(a + z, b + c);
331
29.2k
}
332
333
// Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
334
static pair<uint64, uint64> WeakHashLen32WithSeeds(
335
29.2k
    const char* s, uint64 a, uint64 b) {
336
29.2k
  return WeakHashLen32WithSeeds(Fetch64(s),
337
29.2k
                                Fetch64(s + 8),
338
29.2k
                                Fetch64(s + 16),
339
29.2k
                                Fetch64(s + 24),
340
29.2k
                                a,
341
29.2k
                                b);
342
29.2k
}
343
344
// Return an 8-byte hash for 33 to 64 bytes.
345
2
static uint64 HashLen33to64(const char *s, size_t len) {
346
2
  uint64 mul = k2 + len * 2;
347
2
  uint64 a = Fetch64(s) * k2;
348
2
  uint64 b = Fetch64(s + 8);
349
2
  uint64 c = Fetch64(s + len - 24);
350
2
  uint64 d = Fetch64(s + len - 32);
351
2
  uint64 e = Fetch64(s + 16) * k2;
352
2
  uint64 f = Fetch64(s + 24) * 9;
353
2
  uint64 g = Fetch64(s + len - 8);
354
2
  uint64 h = Fetch64(s + len - 16) * mul;
355
2
  uint64 u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9;
356
2
  uint64 v = ((a + g) ^ d) + f + 1;
357
2
  uint64 w = bswap_64((u + v) * mul) + h;
358
2
  uint64 x = Rotate(e + f, 42) + c;
359
2
  uint64 y = (bswap_64((v + w) * mul) + g) * mul;
360
2
  uint64 z = e + f + c;
361
2
  a = bswap_64((x + z) * mul + y) + b;
362
2
  b = ShiftMix((z + a) * mul + d + h) * mul;
363
2
  return b + x;
364
2
}
365
366
28
uint64 CityHash64(const char *s, size_t len) {
367
28
  if (len <= 32) {
368
1
    if (len <= 16) {
369
1
      return HashLen0to16(s, len);
370
1
    } else {
371
0
      return HashLen17to32(s, len);
372
0
    }
373
27
  } else if (len <= 64) {
374
2
    return HashLen33to64(s, len);
375
2
  }
376
377
  // For strings over 64 bytes we hash the end first, and then as we
378
  // loop we keep 56 bytes of state: v, w, x, y, and z.
379
25
  uint64 x = Fetch64(s + len - 40);
380
25
  uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56);
381
25
  uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24));
382
25
  pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, z);
383
25
  pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
384
25
  x = x * k1 + Fetch64(s);
385
386
  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
387
25
  len = (len - 1) & ~static_cast<size_t>(63);
388
6.22k
  do {
389
6.22k
    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
390
6.22k
    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
391
6.22k
    x ^= w.second;
392
6.22k
    y += v.first + Fetch64(s + 40);
393
6.22k
    z = Rotate(z + w.first, 33) * k1;
394
6.22k
    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
395
6.22k
    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
396
6.22k
    std::swap(z, x);
397
6.22k
    s += 64;
398
6.22k
    len -= 64;
399
6.22k
  } while (len != 0);
400
25
  return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
401
25
                   HashLen16(v.second, w.second) + x);
402
28
}
403
404
2
uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) {
405
2
  return CityHash64WithSeeds(s, len, k2, seed);
406
2
}
407
408
uint64 CityHash64WithSeeds(const char *s, size_t len,
409
6
                           uint64 seed0, uint64 seed1) {
410
6
  return HashLen16(CityHash64(s, len) - seed0, seed1);
411
6
}
412
413
// A subroutine for CityHash128().  Returns a decent 128-bit hash for strings
414
// of any length representable in signed long.  Based on City and Murmur.
415
3
static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
416
3
  uint64 a = Uint128Low64(seed);
417
3
  uint64 b = Uint128High64(seed);
418
3
  uint64 c = 0;
419
3
  uint64 d = 0;
420
3
  if (len <= 16) {
421
1
    a = ShiftMix(a * k1) * k1;
422
1
    c = b * k1 + HashLen0to16(s, len);
423
1
    d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c));
424
2
  } else {
425
2
    c = HashLen16(Fetch64(s + len - 8) + k1, a);
426
2
    d = HashLen16(b + len, c + Fetch64(s + len - 16));
427
2
    a += d;
428
    // len > 16 here, so do...while is safe
429
7
    do {
430
7
      a ^= ShiftMix(Fetch64(s) * k1) * k1;
431
7
      a *= k1;
432
7
      b ^= a;
433
7
      c ^= ShiftMix(Fetch64(s + 8) * k1) * k1;
434
7
      c *= k1;
435
7
      d ^= c;
436
7
      s += 16;
437
7
      len -= 16;
438
7
    } while (len > 16);
439
2
  }
440
3
  a = HashLen16(a, c);
441
3
  b = HashLen16(d, b);
442
3
  return uint128(a ^ b, HashLen16(b, a));
443
3
}
444
445
34
uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
446
34
  if (len < 128) {
447
3
    return CityMurmur(s, len, seed);
448
3
  }
449
450
  // We expect len >= 128 to be the common case.  Keep 56 bytes of state:
451
  // v, w, x, y, and z.
452
31
  pair<uint64, uint64> v, w;
453
31
  uint64 x = Uint128Low64(seed);
454
31
  uint64 y = Uint128High64(seed);
455
31
  uint64 z = len * k1;
456
31
  v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
457
31
  v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
458
31
  w.first = Rotate(y + z, 35) * k1 + x;
459
31
  w.second = Rotate(x + Fetch64(s + 88), 53) * k1;
460
461
  // This is the same inner loop as CityHash64(), manually unrolled.
462
4.17k
  do {
463
4.17k
    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
464
4.17k
    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
465
4.17k
    x ^= w.second;
466
4.17k
    y += v.first + Fetch64(s + 40);
467
4.17k
    z = Rotate(z + w.first, 33) * k1;
468
4.17k
    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
469
4.17k
    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
470
4.17k
    std::swap(z, x);
471
4.17k
    s += 64;
472
4.17k
    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
473
4.17k
    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
474
4.17k
    x ^= w.second;
475
4.17k
    y += v.first + Fetch64(s + 40);
476
4.17k
    z = Rotate(z + w.first, 33) * k1;
477
4.17k
    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
478
4.17k
    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
479
4.17k
    std::swap(z, x);
480
4.17k
    s += 64;
481
4.17k
    len -= 128;
482
4.17k
  } while (LIKELY(len >= 128));
483
31
  x += Rotate(v.first + z, 49) * k0;
484
31
  y = y * k0 + Rotate(w.second, 37);
485
31
  z = z * k0 + Rotate(w.first, 27);
486
31
  w.first *= 9;
487
31
  v.first *= k0;
488
  // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
489
111
  for (size_t tail_done = 0; tail_done < len; ) {
490
80
    tail_done += 32;
491
80
    y = Rotate(x + y, 42) * k0 + v.second;
492
80
    w.first += Fetch64(s + len - tail_done + 16);
493
80
    x = x * k0 + w.first;
494
80
    z += w.second + Fetch64(s + len - tail_done);
495
80
    w.second += v.first;
496
80
    v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second);
497
80
    v.first *= k0;
498
80
  }
499
  // At this point our 56 bytes of state should contain more than
500
  // enough information for a strong 128-bit hash.  We use two
501
  // different 56-byte-to-8-byte hashes to get a 16-byte final result.
502
31
  x = HashLen16(x, v.first);
503
31
  y = HashLen16(y + z, w.first);
504
31
  return uint128(HashLen16(x + v.second, w.second) + y,
505
31
                 HashLen16(x + w.second, y + v.second));
506
34
}
507
508
28
uint128 CityHash128(const char *s, size_t len) {
509
28
  return len >= 16 ?
510
28
      CityHash128WithSeed(s + 16, len - 16,
511
28
                          uint128(Fetch64(s), Fetch64(s + 8) + k0)) :
512
28
      CityHash128WithSeed(s, len, uint128(k0, k1));
513
28
}
514
515
#ifdef __SSE4_2__
516
#include <citycrc.h>
517
#include <nmmintrin.h>
518
519
// Requires len >= 240.
520
static void CityHashCrc256Long(const char *s, size_t len,
521
37
                               uint32 seed, uint64 *result) {
522
37
  uint64 a = Fetch64(s + 56) + k0;
523
37
  uint64 b = Fetch64(s + 96) + k0;
524
37
  uint64 c = result[0] = HashLen16(b, len);
525
37
  uint64 d = result[1] = Fetch64(s + 120) * k0 + len;
526
37
  uint64 e = Fetch64(s + 184) + seed;
527
37
  uint64 f = 0;
528
37
  uint64 g = 0;
529
37
  uint64 h = c + d;
530
37
  uint64 x = seed;
531
37
  uint64 y = 0;
532
37
  uint64 z = 0;
533
534
  // 240 bytes of input per iter.
535
37
  size_t iters = len / 240;
536
37
  len -= iters * 240;
537
8.36k
  do {
538
8.36k
#undef CHUNK
539
8.36k
#define CHUNK(r)                                \
540
50.2k
    PERMUTE3(x, z, y);                          \
541
50.2k
    b += Fetch64(s);                            \
542
50.2k
    c += Fetch64(s + 8);                        \
543
50.2k
    d += Fetch64(s + 16);                       \
544
50.2k
    e += Fetch64(s + 24);                       \
545
50.2k
    f += Fetch64(s + 32);                       \
546
50.2k
    a += b;                                     \
547
50.2k
    h += f;                                     \
548
50.2k
    b += c;                                     \
549
50.2k
    f += d;                                     \
550
50.2k
    g += e;                                     \
551
50.2k
    e += z;                                     \
552
50.2k
    g += x;                                     \
553
50.2k
    z = _mm_crc32_u64(z, b + g);                \
554
50.2k
    y = _mm_crc32_u64(y, e + h);                \
555
50.2k
    x = _mm_crc32_u64(x, f + a);                \
556
50.2k
    e = Rotate(e, r);                           \
557
50.2k
    c += e;                                     \
558
50.2k
    s += 40
559
560
8.36k
    CHUNK(0); PERMUTE3(a, h, c);
561
8.36k
    CHUNK(33); PERMUTE3(a, h, f);
562
8.36k
    CHUNK(0); PERMUTE3(b, h, f);
563
8.36k
    CHUNK(42); PERMUTE3(b, h, d);
564
8.36k
    CHUNK(0); PERMUTE3(b, h, e);
565
8.36k
    CHUNK(33); PERMUTE3(a, h, e);
566
8.36k
  } while (--iters > 0);
567
568
127
  while (len >= 40) {
569
90
    CHUNK(29);
570
90
    e ^= Rotate(a, 20);
571
90
    h += Rotate(b, 30);
572
90
    g ^= Rotate(c, 40);
573
90
    f += Rotate(d, 34);
574
90
    PERMUTE3(c, h, g);
575
90
    len -= 40;
576
90
  }
577
37
  if (len > 0) {
578
35
    s = s + len - 40;
579
35
    CHUNK(33);
580
35
    e ^= Rotate(a, 43);
581
35
    h += Rotate(b, 42);
582
35
    g ^= Rotate(c, 41);
583
35
    f += Rotate(d, 40);
584
35
  }
585
37
  result[0] ^= h;
586
37
  result[1] ^= g;
587
37
  g += h;
588
37
  a = HashLen16(a, g + z);
589
37
  x += y << 32;
590
37
  b += x;
591
37
  c = HashLen16(c, z) + h;
592
37
  d = HashLen16(d, e + result[0]);
593
37
  g += e;
594
37
  h += HashLen16(x, f);
595
37
  e = HashLen16(a, d) + g;
596
37
  z = HashLen16(b, c) + a;
597
37
  y = HashLen16(g, h) + c;
598
37
  result[0] = e + z + y + x;
599
37
  a = ShiftMix((a + y) * k0) * k0 + b;
600
37
  result[1] += a + result[0];
601
37
  a = ShiftMix(a * k0) * k0 + c;
602
37
  result[2] = a + result[1];
603
37
  a = ShiftMix((a + e) * k0) * k0;
604
37
  result[3] = a + result[2];
605
37
}
606
607
// Requires len < 240.
608
2
static void CityHashCrc256Short(const char *s, size_t len, uint64 *result) {
609
2
  char buf[240];
610
2
  memcpy(buf, s, len);
611
2
  memset(buf + len, 0, 240 - len);
612
2
  CityHashCrc256Long(buf, 240, ~static_cast<uint32>(len), result);
613
2
}
614
615
37
void CityHashCrc256(const char *s, size_t len, uint64 *result) {
616
37
  if (LIKELY(len >= 240)) {
617
35
    CityHashCrc256Long(s, len, 0, result);
618
35
  } else {
619
2
    CityHashCrc256Short(s, len, result);
620
2
  }
621
37
}
622
623
5
uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) {
624
5
  if (len <= 900) {
625
2
    return CityHash128WithSeed(s, len, seed);
626
3
  } else {
627
3
    uint64 result[4];
628
3
    CityHashCrc256(s, len, result);
629
3
    uint64 u = Uint128High64(seed) + result[0];
630
3
    uint64 v = Uint128Low64(seed) + result[1];
631
3
    return uint128(HashLen16(u, v + result[2]),
632
3
                   HashLen16(Rotate(v, 32), u * k0 + result[3]));
633
3
  }
634
5
}
635
636
19
uint128 CityHashCrc128(const char *s, size_t len) {
637
19
  if (len <= 900) {
638
5
    return CityHash128(s, len);
639
14
  } else {
640
14
    uint64 result[4];
641
14
    CityHashCrc256(s, len, result);
642
14
    return uint128(result[2], result[3]);
643
14
  }
644
19
}
645
646
#endif