aboutsummaryrefslogtreecommitdiffhomepage
path: root/absl/hash/internal/city.cc
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2018-10-10 12:31:37 -0700
committerGravatar CJ Johnson <johnsoncj@google.com>2018-10-10 15:35:19 -0400
commitf340f773edab951656b19b6f1a77c964a78ec4c2 (patch)
treec42bf7faf49fb2355661c9f39c40513bc1ff2697 /absl/hash/internal/city.cc
parent445998d7ac4e5d3c50411d377e3b50e960d2d6c2 (diff)
Export of internal Abseil changes.
-- 906c47420646d510edd2479d5542c56f5fa31b65 by CJ Johnson <johnsoncj@google.com>: Import of CCTZ from GitHub. PiperOrigin-RevId: 216573923 -- 74560d4afd2b605909e677c6fc3076049fb3010a by Eric Fiselier <ericwf@google.com>: Avoid -Wformat-pedantic in benchmark. PiperOrigin-RevId: 216523769 -- 9bcc9da8b03e6d1ea43ee78931256c5541cb9686 by Eric Fiselier <ericwf@google.com>: Delete unused CityHash functions. PiperOrigin-RevId: 216464492 -- a42563b394c89fbb4c55cb5a6a5edbf96d271eea by Abseil Team <absl-team@google.com>: Introduce new Abseil interfaces for converting between civil times and absolute times.s Deprecates absl::ConvertDateTime() and absl::FromDateTime(). PiperOrigin-RevId: 216424948 -- 088e11235124267517d7f137854fa5554679c24f by Eric Fiselier <ericwf@google.com>: Remove unneeded break statements in test. PiperOrigin-RevId: 216403321 GitOrigin-RevId: 906c47420646d510edd2479d5542c56f5fa31b65 Change-Id: Idb44420be623e369c66f5a9c92bdc9ab46d3ec92
Diffstat (limited to 'absl/hash/internal/city.cc')
-rw-r--r--absl/hash/internal/city.cc246
1 files changed, 0 insertions, 246 deletions
diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc
index 8f72dd1..122906f 100644
--- a/absl/hash/internal/city.cc
+++ b/absl/hash/internal/city.cc
@@ -340,251 +340,5 @@ uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0,
return HashLen16(CityHash64(s, len) - seed0, seed1);
}
-// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
-// of any length representable in signed long. Based on City and Murmur.
-static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
- uint64_t a = Uint128Low64(seed);
- uint64_t b = Uint128High64(seed);
- uint64_t c = 0;
- uint64_t d = 0;
- int64_t l = len - 16;
- if (l <= 0) { // len <= 16
- a = ShiftMix(a * k1) * k1;
- c = b * k1 + HashLen0to16(s, len);
- d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c));
- } else { // len > 16
- c = HashLen16(Fetch64(s + len - 8) + k1, a);
- d = HashLen16(b + len, c + Fetch64(s + len - 16));
- a += d;
- do {
- a ^= ShiftMix(Fetch64(s) * k1) * k1;
- a *= k1;
- b ^= a;
- c ^= ShiftMix(Fetch64(s + 8) * k1) * k1;
- c *= k1;
- d ^= c;
- s += 16;
- l -= 16;
- } while (l > 0);
- }
- a = HashLen16(a, c);
- b = HashLen16(d, b);
- return uint128(a ^ b, HashLen16(b, a));
-}
-
-uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
- if (len < 128) {
- return CityMurmur(s, len, seed);
- }
-
- // We expect len >= 128 to be the common case. Keep 56 bytes of state:
- // v, w, x, y, and z.
- std::pair<uint64_t, uint64_t> v, w;
- uint64_t x = Uint128Low64(seed);
- uint64_t y = Uint128High64(seed);
- uint64_t z = len * k1;
- v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
- v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
- w.first = Rotate(y + z, 35) * k1 + x;
- w.second = Rotate(x + Fetch64(s + 88), 53) * k1;
-
- // This is the same inner loop as CityHash64(), manually unrolled.
- do {
- x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
- y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
- x ^= w.second;
- y += v.first + Fetch64(s + 40);
- z = Rotate(z + w.first, 33) * k1;
- v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
- std::swap(z, x);
- s += 64;
- x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
- y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
- x ^= w.second;
- y += v.first + Fetch64(s + 40);
- z = Rotate(z + w.first, 33) * k1;
- v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
- std::swap(z, x);
- s += 64;
- len -= 128;
- } while (ABSL_PREDICT_TRUE(len >= 128));
- x += Rotate(v.first + z, 49) * k0;
- y = y * k0 + Rotate(w.second, 37);
- z = z * k0 + Rotate(w.first, 27);
- w.first *= 9;
- v.first *= k0;
- // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
- for (size_t tail_done = 0; tail_done < len;) {
- tail_done += 32;
- y = Rotate(x + y, 42) * k0 + v.second;
- w.first += Fetch64(s + len - tail_done + 16);
- x = x * k0 + w.first;
- z += w.second + Fetch64(s + len - tail_done);
- w.second += v.first;
- v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second);
- v.first *= k0;
- }
- // At this point our 56 bytes of state should contain more than
- // enough information for a strong 128-bit hash. We use two
- // different 56-byte-to-8-byte hashes to get a 16-byte final result.
- x = HashLen16(x, v.first);
- y = HashLen16(y + z, w.first);
- return uint128(HashLen16(x + v.second, w.second) + y,
- HashLen16(x + w.second, y + v.second));
-}
-
-uint128 CityHash128(const char *s, size_t len) {
- return len >= 16
- ? CityHash128WithSeed(s + 16, len - 16,
- uint128(Fetch64(s), Fetch64(s + 8) + k0))
- : CityHash128WithSeed(s, len, uint128(k0, k1));
-}
} // namespace hash_internal
} // namespace absl
-
-#ifdef __SSE4_2__
-#include <nmmintrin.h>
-#include "absl/hash/internal/city_crc.h"
-
-namespace absl {
-namespace hash_internal {
-
-// Requires len >= 240.
-static void CityHashCrc256Long(const char *s, size_t len, uint32_t seed,
- uint64_t *result) {
- uint64_t a = Fetch64(s + 56) + k0;
- uint64_t b = Fetch64(s + 96) + k0;
- uint64_t c = result[0] = HashLen16(b, len);
- uint64_t d = result[1] = Fetch64(s + 120) * k0 + len;
- uint64_t e = Fetch64(s + 184) + seed;
- uint64_t f = 0;
- uint64_t g = 0;
- uint64_t h = c + d;
- uint64_t x = seed;
- uint64_t y = 0;
- uint64_t z = 0;
-
- // 240 bytes of input per iter.
- size_t iters = len / 240;
- len -= iters * 240;
- do {
-#undef CHUNK
-#define CHUNK(r) \
- PERMUTE3(x, z, y); \
- b += Fetch64(s); \
- c += Fetch64(s + 8); \
- d += Fetch64(s + 16); \
- e += Fetch64(s + 24); \
- f += Fetch64(s + 32); \
- a += b; \
- h += f; \
- b += c; \
- f += d; \
- g += e; \
- e += z; \
- g += x; \
- z = _mm_crc32_u64(z, b + g); \
- y = _mm_crc32_u64(y, e + h); \
- x = _mm_crc32_u64(x, f + a); \
- e = Rotate(e, r); \
- c += e; \
- s += 40
-
- CHUNK(0);
- PERMUTE3(a, h, c);
- CHUNK(33);
- PERMUTE3(a, h, f);
- CHUNK(0);
- PERMUTE3(b, h, f);
- CHUNK(42);
- PERMUTE3(b, h, d);
- CHUNK(0);
- PERMUTE3(b, h, e);
- CHUNK(33);
- PERMUTE3(a, h, e);
- } while (--iters > 0);
-
- while (len >= 40) {
- CHUNK(29);
- e ^= Rotate(a, 20);
- h += Rotate(b, 30);
- g ^= Rotate(c, 40);
- f += Rotate(d, 34);
- PERMUTE3(c, h, g);
- len -= 40;
- }
- if (len > 0) {
- s = s + len - 40;
- CHUNK(33);
- e ^= Rotate(a, 43);
- h += Rotate(b, 42);
- g ^= Rotate(c, 41);
- f += Rotate(d, 40);
- }
- result[0] ^= h;
- result[1] ^= g;
- g += h;
- a = HashLen16(a, g + z);
- x += y << 32;
- b += x;
- c = HashLen16(c, z) + h;
- d = HashLen16(d, e + result[0]);
- g += e;
- h += HashLen16(x, f);
- e = HashLen16(a, d) + g;
- z = HashLen16(b, c) + a;
- y = HashLen16(g, h) + c;
- result[0] = e + z + y + x;
- a = ShiftMix((a + y) * k0) * k0 + b;
- result[1] += a + result[0];
- a = ShiftMix(a * k0) * k0 + c;
- result[2] = a + result[1];
- a = ShiftMix((a + e) * k0) * k0;
- result[3] = a + result[2];
-}
-
-// Requires len < 240.
-static void CityHashCrc256Short(const char *s, size_t len, uint64_t *result) {
- char buf[240];
- memcpy(buf, s, len);
- memset(buf + len, 0, 240 - len);
- CityHashCrc256Long(buf, 240, ~static_cast<uint32_t>(len), result);
-}
-
-void CityHashCrc256(const char *s, size_t len, uint64_t *result) {
- if (ABSL_PREDICT_TRUE(len >= 240)) {
- CityHashCrc256Long(s, len, 0, result);
- } else {
- CityHashCrc256Short(s, len, result);
- }
-}
-
-uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) {
- if (len <= 900) {
- return CityHash128WithSeed(s, len, seed);
- } else {
- uint64_t result[4];
- CityHashCrc256(s, len, result);
- uint64_t u = Uint128High64(seed) + result[0];
- uint64_t v = Uint128Low64(seed) + result[1];
- return uint128(HashLen16(u, v + result[2]),
- HashLen16(Rotate(v, 32), u * k0 + result[3]));
- }
-}
-
-uint128 CityHashCrc128(const char *s, size_t len) {
- if (len <= 900) {
- return CityHash128(s, len);
- } else {
- uint64_t result[4];
- CityHashCrc256(s, len, result);
- return uint128(result[2], result[3]);
- }
-}
-
-} // namespace hash_internal
-} // namespace absl
-
-#endif