A subroutine for CityHash128(). Returns a decent 128-bit hash for strings of any length representable in signed long. Based on City and Murmur.
| 396 | // A subroutine for CityHash128(). Returns a decent 128-bit hash for strings |
| 397 | // of any length representable in signed long. Based on City and Murmur. |
| 398 | static uint128 CityMurmur(const char *s, size_t len, uint128 seed) { |
| 399 | uint64 a = Uint128Low64(seed); |
| 400 | uint64 b = Uint128High64(seed); |
| 401 | uint64 c = 0; |
| 402 | uint64 d = 0; |
| 403 | signed long l = len - 16; |
| 404 | if (l <= 0) { // len <= 16 |
| 405 | a = ShiftMix(a * k1) * k1; |
| 406 | c = b * k1 + HashLen0to16(s, len); |
| 407 | d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c)); |
| 408 | } else { // len > 16 |
| 409 | c = HashLen16(Fetch64(s + len - 8) + k1, a); |
| 410 | d = HashLen16(b + len, c + Fetch64(s + len - 16)); |
| 411 | a += d; |
| 412 | do { |
| 413 | a ^= ShiftMix(Fetch64(s) * k1) * k1; |
| 414 | a *= k1; |
| 415 | b ^= a; |
| 416 | c ^= ShiftMix(Fetch64(s + 8) * k1) * k1; |
| 417 | c *= k1; |
| 418 | d ^= c; |
| 419 | s += 16; |
| 420 | l -= 16; |
| 421 | } while (l > 0); |
| 422 | } |
| 423 | a = HashLen16(a, c); |
| 424 | b = HashLen16(d, b); |
| 425 | return uint128(a ^ b, HashLen16(b, a)); |
| 426 | } |
| 427 | |
| 428 | uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { |
| 429 | if (len < 128) { |
no test coverage detected