aboutsummaryrefslogtreecommitdiffstats
path: root/util/digest
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:15 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:15 +0300
commit72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch)
treeda2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /util/digest
parent778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff)
downloadydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'util/digest')
-rw-r--r--util/digest/benchmark/murmur/main.cpp14
-rw-r--r--util/digest/city.cpp622
-rw-r--r--util/digest/city.h64
-rw-r--r--util/digest/fnv.cpp2
-rw-r--r--util/digest/fnv.h108
-rw-r--r--util/digest/fnv_ut.cpp40
-rw-r--r--util/digest/multi.h4
-rw-r--r--util/digest/murmur.cpp4
-rw-r--r--util/digest/murmur.h32
-rw-r--r--util/digest/murmur_ut.cpp88
-rw-r--r--util/digest/numeric.cpp2
-rw-r--r--util/digest/numeric.h132
-rw-r--r--util/digest/sequence.h4
-rw-r--r--util/digest/sequence_ut.cpp4
-rw-r--r--util/digest/ut/ya.make8
15 files changed, 564 insertions, 564 deletions
diff --git a/util/digest/benchmark/murmur/main.cpp b/util/digest/benchmark/murmur/main.cpp
index 1fe2fdcc21..7729ef345f 100644
--- a/util/digest/benchmark/murmur/main.cpp
+++ b/util/digest/benchmark/murmur/main.cpp
@@ -6,21 +6,21 @@
#include <array>
constexpr auto MakeTestData() {
- std::array<ui64, 4096> result;
- for (ui64 i = 0; i < result.size(); ++i) {
- result[i] = i;
- }
- return result;
+ std::array<ui64, 4096> result;
+ for (ui64 i = 0; i < result.size(); ++i) {
+ result[i] = i;
+ }
+ return result;
}
constexpr auto TEST_DATA = MakeTestData();
template <typename Result>
static void BenchmarkMurmurHash(benchmark::State& state) {
- for (auto _ : state) {
+ for (auto _ : state) {
Result hash = MurmurHash<Result>(TEST_DATA.data(), sizeof(TEST_DATA));
Y_DO_NOT_OPTIMIZE_AWAY(hash);
- }
+ }
}
BENCHMARK_TEMPLATE(BenchmarkMurmurHash, ui32);
diff --git a/util/digest/city.cpp b/util/digest/city.cpp
index c25f175d54..f73f2fd1a0 100644
--- a/util/digest/city.cpp
+++ b/util/digest/city.cpp
@@ -1,323 +1,323 @@
#ifndef NO_CITYHASH
-// Copyright (c) 2011 Google, Inc.
-
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// CityHash Version 1, by Geoff Pike and Jyrki Alakuijala
-
-// This file provides CityHash64() and related functions.
-
-// It's probably possible to create even faster hash functions by
-// writing a program that systematically explores some of the space of
-// possible hash functions, by using SIMD instructions, or by
-// compromising on hash quality.
-
- #include "city.h"
-
+// Copyright (c) 2011 Google, Inc.
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// CityHash Version 1, by Geoff Pike and Jyrki Alakuijala
+
+// This file provides CityHash64() and related functions.
+
+// It's probably possible to create even faster hash functions by
+// writing a program that systematically explores some of the space of
+// possible hash functions, by using SIMD instructions, or by
+// compromising on hash quality.
+
+ #include "city.h"
+
using uint8 = ui8;
using uint32 = ui32;
using uint64 = ui64;
-
- #include <util/system/unaligned_mem.h>
- #include <util/generic/algorithm.h>
-
-using namespace std;
-
-//#define UNALIGNED_LOAD64(p) (*(const uint64*)(p))
-//#define UNALIGNED_LOAD32(p) (*(const uint32*)(p))
-
- #define UNALIGNED_LOAD64(p) (ReadUnaligned<uint64>((const void*)(p)))
- #define UNALIGNED_LOAD32(p) (ReadUnaligned<uint32>((const void*)(p)))
-
- #define LIKELY(x) Y_LIKELY(!!(x))
-
-// Some primes between 2^63 and 2^64 for various uses.
-static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
-static const uint64 k1 = 0xb492b66fbe98f273ULL;
-static const uint64 k2 = 0x9ae16a3b2f90404fULL;
-static const uint64 k3 = 0xc949d7c7509e6557ULL;
-
-// Bitwise right rotate. Normally this will compile to a single
-// instruction, especially if the shift is a manifest constant.
-static uint64 Rotate(uint64 val, int shift) {
- // Avoid shifting by 64: doing so yields an undefined result.
- return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
-}
-
-// Equivalent to Rotate(), but requires the second arg to be non-zero.
-// On x86-64, and probably others, it's possible for this to compile
-// to a single instruction if both args are already in registers.
-static uint64 RotateByAtLeast1(uint64 val, int shift) {
- return (val >> shift) | (val << (64 - shift));
-}
-
-static uint64 ShiftMix(uint64 val) {
- return val ^ (val >> 47);
-}
-
-static uint64 HashLen16(uint64 u, uint64 v) {
- return Hash128to64(uint128(u, v));
-}
-
-static uint64 HashLen0to16(const char* s, size_t len) {
- if (len > 8) {
- uint64 a = UNALIGNED_LOAD64(s);
- uint64 b = UNALIGNED_LOAD64(s + len - 8);
- return HashLen16(a, RotateByAtLeast1(b + len, static_cast<int>(len))) ^ b;
- }
- if (len >= 4) {
- uint64 a = UNALIGNED_LOAD32(s);
- return HashLen16(len + (a << 3), UNALIGNED_LOAD32(s + len - 4));
- }
- if (len > 0) {
- uint8 a = s[0];
- uint8 b = s[len >> 1];
- uint8 c = s[len - 1];
- uint32 y = static_cast<uint32>(a) + (static_cast<uint32>(b) << 8);
- uint32 z = static_cast<uint32>(len) + (static_cast<uint32>(c) << 2);
- return ShiftMix(y * k2 ^ z * k3) * k2;
- }
- return k2;
-}
-
-// This probably works well for 16-byte strings as well, but it may be overkill
-// in that case.
-static uint64 HashLen17to32(const char* s, size_t len) {
- uint64 a = UNALIGNED_LOAD64(s) * k1;
- uint64 b = UNALIGNED_LOAD64(s + 8);
- uint64 c = UNALIGNED_LOAD64(s + len - 8) * k2;
- uint64 d = UNALIGNED_LOAD64(s + len - 16) * k0;
- return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d,
- a + Rotate(b ^ k3, 20) - c + len);
-}
-
-// Return a 16-byte hash for 48 bytes. Quick and dirty.
-// Callers do best to use "random-looking" values for a and b.
-static pair<uint64, uint64> WeakHashLen32WithSeeds(
- uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) {
- a += w;
- b = Rotate(b + a + z, 21);
- uint64 c = a;
- a += x;
- a += y;
- b += Rotate(a, 44);
- return make_pair(a + z, b + c);
-}
-
-// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
-static pair<uint64, uint64> WeakHashLen32WithSeeds(
- const char* s, uint64 a, uint64 b) {
- return WeakHashLen32WithSeeds(UNALIGNED_LOAD64(s),
- UNALIGNED_LOAD64(s + 8),
- UNALIGNED_LOAD64(s + 16),
- UNALIGNED_LOAD64(s + 24),
- a,
- b);
-}
-
-// Return an 8-byte hash for 33 to 64 bytes.
-static uint64 HashLen33to64(const char* s, size_t len) {
- uint64 z = UNALIGNED_LOAD64(s + 24);
- uint64 a = UNALIGNED_LOAD64(s) + (len + UNALIGNED_LOAD64(s + len - 16)) * k0;
- uint64 b = Rotate(a + z, 52);
- uint64 c = Rotate(a, 37);
- a += UNALIGNED_LOAD64(s + 8);
- c += Rotate(a, 7);
- a += UNALIGNED_LOAD64(s + 16);
- uint64 vf = a + z;
- uint64 vs = b + Rotate(a, 31) + c;
- a = UNALIGNED_LOAD64(s + 16) + UNALIGNED_LOAD64(s + len - 32);
- z = UNALIGNED_LOAD64(s + len - 8);
- b = Rotate(a + z, 52);
- c = Rotate(a, 37);
- a += UNALIGNED_LOAD64(s + len - 24);
- c += Rotate(a, 7);
- a += UNALIGNED_LOAD64(s + len - 16);
- uint64 wf = a + z;
- uint64 ws = b + Rotate(a, 31) + c;
- uint64 r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0);
- return ShiftMix(r * k0 + vs) * k2;
-}
-
-uint64 CityHash64(const char* s, size_t len) noexcept {
- if (len <= 32) {
- if (len <= 16) {
- return HashLen0to16(s, len);
- } else {
- return HashLen17to32(s, len);
- }
- } else if (len <= 64) {
- return HashLen33to64(s, len);
- }
-
- // For strings over 64 bytes we hash the end first, and then as we
- // loop we keep 56 bytes of state: v, w, x, y, and z.
- uint64 x = UNALIGNED_LOAD64(s);
- uint64 y = UNALIGNED_LOAD64(s + len - 16) ^ k1;
- uint64 z = UNALIGNED_LOAD64(s + len - 56) ^ k0;
- pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, y);
- pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, len * k1, k0);
- z += ShiftMix(v.second) * k1;
- x = Rotate(z + x, 39) * k1;
- y = Rotate(y, 33) * k1;
-
- // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
- len = (len - 1) & ~static_cast<size_t>(63);
- do {
- x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
- y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
- x ^= w.second;
- y ^= v.first;
- z = Rotate(z ^ w.first, 33);
- v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
- DoSwap(z, x);
- s += 64;
- len -= 64;
- } while (len != 0);
- return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
- HashLen16(v.second, w.second) + x);
-}
-
-uint64 CityHash64WithSeed(const char* s, size_t len, uint64 seed) noexcept {
- return CityHash64WithSeeds(s, len, k2, seed);
-}
-
-uint64 CityHash64WithSeeds(const char* s, size_t len,
+
+ #include <util/system/unaligned_mem.h>
+ #include <util/generic/algorithm.h>
+
+using namespace std;
+
+//#define UNALIGNED_LOAD64(p) (*(const uint64*)(p))
+//#define UNALIGNED_LOAD32(p) (*(const uint32*)(p))
+
+ #define UNALIGNED_LOAD64(p) (ReadUnaligned<uint64>((const void*)(p)))
+ #define UNALIGNED_LOAD32(p) (ReadUnaligned<uint32>((const void*)(p)))
+
+ #define LIKELY(x) Y_LIKELY(!!(x))
+
+// Some primes between 2^63 and 2^64 for various uses.
+static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
+static const uint64 k1 = 0xb492b66fbe98f273ULL;
+static const uint64 k2 = 0x9ae16a3b2f90404fULL;
+static const uint64 k3 = 0xc949d7c7509e6557ULL;
+
+// Bitwise right rotate. Normally this will compile to a single
+// instruction, especially if the shift is a manifest constant.
+static uint64 Rotate(uint64 val, int shift) {
+ // Avoid shifting by 64: doing so yields an undefined result.
+ return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
+}
+
+// Equivalent to Rotate(), but requires the second arg to be non-zero.
+// On x86-64, and probably others, it's possible for this to compile
+// to a single instruction if both args are already in registers.
+static uint64 RotateByAtLeast1(uint64 val, int shift) {
+ return (val >> shift) | (val << (64 - shift));
+}
+
+static uint64 ShiftMix(uint64 val) {
+ return val ^ (val >> 47);
+}
+
+static uint64 HashLen16(uint64 u, uint64 v) {
+ return Hash128to64(uint128(u, v));
+}
+
+static uint64 HashLen0to16(const char* s, size_t len) {
+ if (len > 8) {
+ uint64 a = UNALIGNED_LOAD64(s);
+ uint64 b = UNALIGNED_LOAD64(s + len - 8);
+ return HashLen16(a, RotateByAtLeast1(b + len, static_cast<int>(len))) ^ b;
+ }
+ if (len >= 4) {
+ uint64 a = UNALIGNED_LOAD32(s);
+ return HashLen16(len + (a << 3), UNALIGNED_LOAD32(s + len - 4));
+ }
+ if (len > 0) {
+ uint8 a = s[0];
+ uint8 b = s[len >> 1];
+ uint8 c = s[len - 1];
+ uint32 y = static_cast<uint32>(a) + (static_cast<uint32>(b) << 8);
+ uint32 z = static_cast<uint32>(len) + (static_cast<uint32>(c) << 2);
+ return ShiftMix(y * k2 ^ z * k3) * k2;
+ }
+ return k2;
+}
+
+// This probably works well for 16-byte strings as well, but it may be overkill
+// in that case.
+static uint64 HashLen17to32(const char* s, size_t len) {
+ uint64 a = UNALIGNED_LOAD64(s) * k1;
+ uint64 b = UNALIGNED_LOAD64(s + 8);
+ uint64 c = UNALIGNED_LOAD64(s + len - 8) * k2;
+ uint64 d = UNALIGNED_LOAD64(s + len - 16) * k0;
+ return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d,
+ a + Rotate(b ^ k3, 20) - c + len);
+}
+
+// Return a 16-byte hash for 48 bytes. Quick and dirty.
+// Callers do best to use "random-looking" values for a and b.
+static pair<uint64, uint64> WeakHashLen32WithSeeds(
+ uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) {
+ a += w;
+ b = Rotate(b + a + z, 21);
+ uint64 c = a;
+ a += x;
+ a += y;
+ b += Rotate(a, 44);
+ return make_pair(a + z, b + c);
+}
+
+// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
+static pair<uint64, uint64> WeakHashLen32WithSeeds(
+ const char* s, uint64 a, uint64 b) {
+ return WeakHashLen32WithSeeds(UNALIGNED_LOAD64(s),
+ UNALIGNED_LOAD64(s + 8),
+ UNALIGNED_LOAD64(s + 16),
+ UNALIGNED_LOAD64(s + 24),
+ a,
+ b);
+}
+
+// Return an 8-byte hash for 33 to 64 bytes.
+static uint64 HashLen33to64(const char* s, size_t len) {
+ uint64 z = UNALIGNED_LOAD64(s + 24);
+ uint64 a = UNALIGNED_LOAD64(s) + (len + UNALIGNED_LOAD64(s + len - 16)) * k0;
+ uint64 b = Rotate(a + z, 52);
+ uint64 c = Rotate(a, 37);
+ a += UNALIGNED_LOAD64(s + 8);
+ c += Rotate(a, 7);
+ a += UNALIGNED_LOAD64(s + 16);
+ uint64 vf = a + z;
+ uint64 vs = b + Rotate(a, 31) + c;
+ a = UNALIGNED_LOAD64(s + 16) + UNALIGNED_LOAD64(s + len - 32);
+ z = UNALIGNED_LOAD64(s + len - 8);
+ b = Rotate(a + z, 52);
+ c = Rotate(a, 37);
+ a += UNALIGNED_LOAD64(s + len - 24);
+ c += Rotate(a, 7);
+ a += UNALIGNED_LOAD64(s + len - 16);
+ uint64 wf = a + z;
+ uint64 ws = b + Rotate(a, 31) + c;
+ uint64 r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0);
+ return ShiftMix(r * k0 + vs) * k2;
+}
+
+uint64 CityHash64(const char* s, size_t len) noexcept {
+ if (len <= 32) {
+ if (len <= 16) {
+ return HashLen0to16(s, len);
+ } else {
+ return HashLen17to32(s, len);
+ }
+ } else if (len <= 64) {
+ return HashLen33to64(s, len);
+ }
+
+ // For strings over 64 bytes we hash the end first, and then as we
+ // loop we keep 56 bytes of state: v, w, x, y, and z.
+ uint64 x = UNALIGNED_LOAD64(s);
+ uint64 y = UNALIGNED_LOAD64(s + len - 16) ^ k1;
+ uint64 z = UNALIGNED_LOAD64(s + len - 56) ^ k0;
+ pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, y);
+ pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, len * k1, k0);
+ z += ShiftMix(v.second) * k1;
+ x = Rotate(z + x, 39) * k1;
+ y = Rotate(y, 33) * k1;
+
+ // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
+ len = (len - 1) & ~static_cast<size_t>(63);
+ do {
+ x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
+ y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
+ x ^= w.second;
+ y ^= v.first;
+ z = Rotate(z ^ w.first, 33);
+ v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
+ DoSwap(z, x);
+ s += 64;
+ len -= 64;
+ } while (len != 0);
+ return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
+ HashLen16(v.second, w.second) + x);
+}
+
+uint64 CityHash64WithSeed(const char* s, size_t len, uint64 seed) noexcept {
+ return CityHash64WithSeeds(s, len, k2, seed);
+}
+
+uint64 CityHash64WithSeeds(const char* s, size_t len,
uint64 seed0, uint64 seed1) noexcept {
- return HashLen16(CityHash64(s, len) - seed0, seed1);
-}
-
-// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
-// of any length representable in ssize_t. Based on City and Murmur.
-static uint128 CityMurmur(const char* s, size_t len, uint128 seed) {
- uint64 a = Uint128Low64(seed);
- uint64 b = Uint128High64(seed);
- uint64 c = 0;
- uint64 d = 0;
- ssize_t l = len - 16;
- if (l <= 0) { // len <= 16
- c = b * k1 + HashLen0to16(s, len);
- d = Rotate(a + (len >= 8 ? UNALIGNED_LOAD64(s) : c), 32);
- } else { // len > 16
- c = HashLen16(UNALIGNED_LOAD64(s + len - 8) + k1, a);
- d = HashLen16(b + len, c + UNALIGNED_LOAD64(s + len - 16));
- a += d;
- do {
- a ^= ShiftMix(UNALIGNED_LOAD64(s) * k1) * k1;
- a *= k1;
- b ^= a;
- c ^= ShiftMix(UNALIGNED_LOAD64(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) noexcept {
- 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.
- pair<uint64, uint64> v, w;
- uint64 x = Uint128Low64(seed);
- uint64 y = Uint128High64(seed);
- uint64 z = len * k1;
- v.first = Rotate(y ^ k1, 49) * k1 + UNALIGNED_LOAD64(s);
- v.second = Rotate(v.first, 42) * k1 + UNALIGNED_LOAD64(s + 8);
- w.first = Rotate(y + z, 35) * k1 + x;
- w.second = Rotate(x + UNALIGNED_LOAD64(s + 88), 53) * k1;
-
- // This is the same inner loop as CityHash64(), manually unrolled.
- do {
- x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
- y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
- x ^= w.second;
- y ^= v.first;
- z = Rotate(z ^ w.first, 33);
- v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
- DoSwap(z, x);
- s += 64;
- x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
- y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
- x ^= w.second;
- y ^= v.first;
- z = Rotate(z ^ w.first, 33);
- v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
- w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
- DoSwap(z, x);
- s += 64;
- len -= 128;
- } while (LIKELY(len >= 128));
- y += Rotate(w.first, 37) * k0 + z;
- x += Rotate(v.first + z, 49) * 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(y - x, 42) * k0 + v.second;
- w.first += UNALIGNED_LOAD64(s + len - tail_done + 16);
- x = Rotate(x, 49) * k0 + w.first;
- w.first += v.first;
- v = WeakHashLen32WithSeeds(s + len - tail_done, v.first, v.second);
- }
- // At this point our 48 bytes of state should contain more than
- // enough information for a strong 128-bit hash. We use two
- // different 48-byte-to-8-byte hashes to get a 16-byte final result.
- x = HashLen16(x, v.first);
- y = HashLen16(y, 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) noexcept {
- if (len >= 16) {
- return CityHash128WithSeed(s + 16,
- len - 16,
- uint128(UNALIGNED_LOAD64(s) ^ k3,
- UNALIGNED_LOAD64(s + 8)));
- } else if (len >= 8) {
- return CityHash128WithSeed(nullptr,
- 0,
- uint128(UNALIGNED_LOAD64(s) ^ (len * k0),
- UNALIGNED_LOAD64(s + len - 8) ^ k1));
- } else {
- return CityHash128WithSeed(s, len, uint128(k0, k1));
- }
-}
+ return HashLen16(CityHash64(s, len) - seed0, seed1);
+}
+
+// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
+// of any length representable in ssize_t. Based on City and Murmur.
+static uint128 CityMurmur(const char* s, size_t len, uint128 seed) {
+ uint64 a = Uint128Low64(seed);
+ uint64 b = Uint128High64(seed);
+ uint64 c = 0;
+ uint64 d = 0;
+ ssize_t l = len - 16;
+ if (l <= 0) { // len <= 16
+ c = b * k1 + HashLen0to16(s, len);
+ d = Rotate(a + (len >= 8 ? UNALIGNED_LOAD64(s) : c), 32);
+ } else { // len > 16
+ c = HashLen16(UNALIGNED_LOAD64(s + len - 8) + k1, a);
+ d = HashLen16(b + len, c + UNALIGNED_LOAD64(s + len - 16));
+ a += d;
+ do {
+ a ^= ShiftMix(UNALIGNED_LOAD64(s) * k1) * k1;
+ a *= k1;
+ b ^= a;
+ c ^= ShiftMix(UNALIGNED_LOAD64(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) noexcept {
+ 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.
+ pair<uint64, uint64> v, w;
+ uint64 x = Uint128Low64(seed);
+ uint64 y = Uint128High64(seed);
+ uint64 z = len * k1;
+ v.first = Rotate(y ^ k1, 49) * k1 + UNALIGNED_LOAD64(s);
+ v.second = Rotate(v.first, 42) * k1 + UNALIGNED_LOAD64(s + 8);
+ w.first = Rotate(y + z, 35) * k1 + x;
+ w.second = Rotate(x + UNALIGNED_LOAD64(s + 88), 53) * k1;
+
+ // This is the same inner loop as CityHash64(), manually unrolled.
+ do {
+ x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
+ y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
+ x ^= w.second;
+ y ^= v.first;
+ z = Rotate(z ^ w.first, 33);
+ v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
+ DoSwap(z, x);
+ s += 64;
+ x = Rotate(x + y + v.first + UNALIGNED_LOAD64(s + 16), 37) * k1;
+ y = Rotate(y + v.second + UNALIGNED_LOAD64(s + 48), 42) * k1;
+ x ^= w.second;
+ y ^= v.first;
+ z = Rotate(z ^ w.first, 33);
+ v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
+ w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
+ DoSwap(z, x);
+ s += 64;
+ len -= 128;
+ } while (LIKELY(len >= 128));
+ y += Rotate(w.first, 37) * k0 + z;
+ x += Rotate(v.first + z, 49) * 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(y - x, 42) * k0 + v.second;
+ w.first += UNALIGNED_LOAD64(s + len - tail_done + 16);
+ x = Rotate(x, 49) * k0 + w.first;
+ w.first += v.first;
+ v = WeakHashLen32WithSeeds(s + len - tail_done, v.first, v.second);
+ }
+ // At this point our 48 bytes of state should contain more than
+ // enough information for a strong 128-bit hash. We use two
+ // different 48-byte-to-8-byte hashes to get a 16-byte final result.
+ x = HashLen16(x, v.first);
+ y = HashLen16(y, 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) noexcept {
+ if (len >= 16) {
+ return CityHash128WithSeed(s + 16,
+ len - 16,
+ uint128(UNALIGNED_LOAD64(s) ^ k3,
+ UNALIGNED_LOAD64(s + 8)));
+ } else if (len >= 8) {
+ return CityHash128WithSeed(nullptr,
+ 0,
+ uint128(UNALIGNED_LOAD64(s) ^ (len * k0),
+ UNALIGNED_LOAD64(s + len - 8) ^ k1));
+ } else {
+ return CityHash128WithSeed(s, len, uint128(k0, k1));
+ }
+}
// TODO(yazevnul): move this function to unittests
void TestCompilationOfCityHashTemplates() {
- TStringBuf s;
- CityHash64(s);
- CityHash64WithSeed(s, 1);
- CityHash64WithSeeds(s, 1, 2);
- CityHash128(s);
- CityHash128WithSeed(s, uint128(1, 2));
+ TStringBuf s;
+ CityHash64(s);
+ CityHash64WithSeed(s, 1);
+ CityHash64WithSeeds(s, 1, 2);
+ CityHash128(s);
+ CityHash128WithSeed(s, uint128(1, 2));
}
#endif
diff --git a/util/digest/city.h b/util/digest/city.h
index 675a798074..3c4b70fc55 100644
--- a/util/digest/city.h
+++ b/util/digest/city.h
@@ -1,48 +1,48 @@
-#pragma once
-
-#include <util/generic/utility.h>
+#pragma once
+
+#include <util/generic/utility.h>
#include <util/generic/strbuf.h>
-
+
#include <utility>
-
+
// NOTE: These functions provide CityHash 1.0 implementation whose results are *different* from
// the mainline version of CityHash.
using uint128 = std::pair<ui64, ui64>;
constexpr ui64 Uint128Low64(const uint128& x) {
- return x.first;
-}
-
+ return x.first;
+}
+
constexpr ui64 Uint128High64(const uint128& x) {
- return x.second;
-}
-
+ return x.second;
+}
+
// Hash functions for a byte array.
// http://en.wikipedia.org/wiki/CityHash
-Y_PURE_FUNCTION ui64 CityHash64(const char* buf, size_t len) noexcept;
-
-Y_PURE_FUNCTION ui64 CityHash64WithSeed(const char* buf, size_t len, ui64 seed) noexcept;
-
-Y_PURE_FUNCTION ui64 CityHash64WithSeeds(const char* buf, size_t len, ui64 seed0, ui64 seed1) noexcept;
-
-Y_PURE_FUNCTION uint128 CityHash128(const char* s, size_t len) noexcept;
-
-Y_PURE_FUNCTION uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) noexcept;
-
-// Hash 128 input bits down to 64 bits of output.
-// This is intended to be a reasonably good hash function.
+Y_PURE_FUNCTION ui64 CityHash64(const char* buf, size_t len) noexcept;
+
+Y_PURE_FUNCTION ui64 CityHash64WithSeed(const char* buf, size_t len, ui64 seed) noexcept;
+
+Y_PURE_FUNCTION ui64 CityHash64WithSeeds(const char* buf, size_t len, ui64 seed0, ui64 seed1) noexcept;
+
+Y_PURE_FUNCTION uint128 CityHash128(const char* s, size_t len) noexcept;
+
+Y_PURE_FUNCTION uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) noexcept;
+
+// Hash 128 input bits down to 64 bits of output.
+// This is intended to be a reasonably good hash function.
inline ui64 Hash128to64(const uint128& x) {
- // Murmur-inspired hashing.
- const ui64 kMul = 0x9ddfea08eb382d69ULL;
- ui64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
- a ^= (a >> 47);
- ui64 b = (Uint128High64(x) ^ a) * kMul;
- b ^= (b >> 47);
- b *= kMul;
- return b;
-}
+ // Murmur-inspired hashing.
+ const ui64 kMul = 0x9ddfea08eb382d69ULL;
+ ui64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
+ a ^= (a >> 47);
+ ui64 b = (Uint128High64(x) ^ a) * kMul;
+ b ^= (b >> 47);
+ b *= kMul;
+ return b;
+}
namespace NPrivateCityHash {
template <class TStringType>
diff --git a/util/digest/fnv.cpp b/util/digest/fnv.cpp
index 57fc5964c3..6aff124bd7 100644
--- a/util/digest/fnv.cpp
+++ b/util/digest/fnv.cpp
@@ -1 +1 @@
-#include "fnv.h"
+#include "fnv.h"
diff --git a/util/digest/fnv.h b/util/digest/fnv.h
index 87b41a3de7..e4aa6d3fb8 100644
--- a/util/digest/fnv.h
+++ b/util/digest/fnv.h
@@ -2,70 +2,70 @@
#include <util/system/defaults.h>
-#define FNV32INIT 2166136261U
+#define FNV32INIT 2166136261U
#define FNV32PRIME 16777619U
-#define FNV64INIT ULL(14695981039346656037)
+#define FNV64INIT ULL(14695981039346656037)
#define FNV64PRIME ULL(1099511628211)
-namespace NFnvPrivate {
- template <class It>
+namespace NFnvPrivate {
+ template <class It>
constexpr ui32 FnvHash32(It b, It e, ui32 init) {
- while (b != e) {
- init = (init * FNV32PRIME) ^ (unsigned char)*b++;
- }
-
- return init;
- }
-
- template <class It>
+ while (b != e) {
+ init = (init * FNV32PRIME) ^ (unsigned char)*b++;
+ }
+
+ return init;
+ }
+
+ template <class It>
constexpr ui64 FnvHash64(It b, It e, ui64 init) {
- while (b != e) {
- init = (init * FNV64PRIME) ^ (unsigned char)*b++;
- }
-
- return init;
- }
-
- template <unsigned N>
- struct TFnvHelper;
-
-#define DEF_FNV(t) \
- template <> \
- struct TFnvHelper<t> { \
- static const ui##t Init = FNV##t##INIT; \
- template <class It> \
+ while (b != e) {
+ init = (init * FNV64PRIME) ^ (unsigned char)*b++;
+ }
+
+ return init;
+ }
+
+ template <unsigned N>
+ struct TFnvHelper;
+
+#define DEF_FNV(t) \
+ template <> \
+ struct TFnvHelper<t> { \
+ static const ui##t Init = FNV##t##INIT; \
+ template <class It> \
static constexpr ui##t FnvHash(It b, It e, ui##t init) { \
- return FnvHash##t(b, e, init); \
- } \
- };
-
- DEF_FNV(32)
- DEF_FNV(64)
-
-#undef DEF_FNV
-}
-
-template <class T, class It>
+ return FnvHash##t(b, e, init); \
+ } \
+ };
+
+ DEF_FNV(32)
+ DEF_FNV(64)
+
+#undef DEF_FNV
+}
+
+template <class T, class It>
static constexpr T FnvHash(It b, It e, T init) {
- static_assert(sizeof(*b) == 1, "expect sizeof(*b) == 1");
-
- return (T)NFnvPrivate::TFnvHelper<8 * sizeof(T)>::FnvHash(b, e, init);
-}
-
-template <class T, class It>
+ static_assert(sizeof(*b) == 1, "expect sizeof(*b) == 1");
+
+ return (T)NFnvPrivate::TFnvHelper<8 * sizeof(T)>::FnvHash(b, e, init);
+}
+
+template <class T, class It>
static constexpr T FnvHash(It b, It e) {
- return FnvHash<T>(b, e, (T)NFnvPrivate::TFnvHelper<8 * sizeof(T)>::Init);
-}
-
-template <class T>
+ return FnvHash<T>(b, e, (T)NFnvPrivate::TFnvHelper<8 * sizeof(T)>::Init);
+}
+
+template <class T>
static constexpr T FnvHash(const void* buf, size_t len, T init) {
- return FnvHash<T>((const unsigned char*)buf, (const unsigned char*)buf + len, init);
-}
-
-template <class T>
+ return FnvHash<T>((const unsigned char*)buf, (const unsigned char*)buf + len, init);
+}
+
+template <class T>
static constexpr T FnvHash(const void* buf, size_t len) {
- return FnvHash<T>((const unsigned char*)buf, (const unsigned char*)buf + len);
-}
+ return FnvHash<T>((const unsigned char*)buf, (const unsigned char*)buf + len);
+}
template <class T, class Buf>
static constexpr T FnvHash(const Buf& buf) {
diff --git a/util/digest/fnv_ut.cpp b/util/digest/fnv_ut.cpp
index ce56642b3e..88c2096d77 100644
--- a/util/digest/fnv_ut.cpp
+++ b/util/digest/fnv_ut.cpp
@@ -1,23 +1,23 @@
-#include "fnv.h"
-
+#include "fnv.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-Y_UNIT_TEST_SUITE(TFnvTest) {
- Y_UNIT_TEST(TestFnv32) {
+
+Y_UNIT_TEST_SUITE(TFnvTest) {
+ Y_UNIT_TEST(TestFnv32) {
const auto h32 = ULL(2849763999);
- UNIT_ASSERT_EQUAL(FnvHash<ui32>("1234567", 7), h32);
- UNIT_ASSERT_EQUAL(FnvHash<ui32>(TStringBuf("1234567")), h32);
-
- UNIT_ASSERT_EQUAL(FnvHash<ui32>(nullptr, 0), FNV32INIT);
- UNIT_ASSERT_EQUAL(FnvHash<ui32>(TStringBuf()), FNV32INIT);
- }
-
- Y_UNIT_TEST(TestFnv64) {
- const auto h64 = ULL(2449551094593701855);
- UNIT_ASSERT_EQUAL(FnvHash<ui64>("1234567", 7), h64);
- UNIT_ASSERT_EQUAL(FnvHash<ui64>(TStringBuf("1234567")), h64);
+ UNIT_ASSERT_EQUAL(FnvHash<ui32>("1234567", 7), h32);
+ UNIT_ASSERT_EQUAL(FnvHash<ui32>(TStringBuf("1234567")), h32);
+
+ UNIT_ASSERT_EQUAL(FnvHash<ui32>(nullptr, 0), FNV32INIT);
+ UNIT_ASSERT_EQUAL(FnvHash<ui32>(TStringBuf()), FNV32INIT);
+ }
+
+ Y_UNIT_TEST(TestFnv64) {
+ const auto h64 = ULL(2449551094593701855);
+ UNIT_ASSERT_EQUAL(FnvHash<ui64>("1234567", 7), h64);
+ UNIT_ASSERT_EQUAL(FnvHash<ui64>(TStringBuf("1234567")), h64);
- UNIT_ASSERT_EQUAL(FnvHash<ui64>(nullptr, 0), FNV64INIT);
- UNIT_ASSERT_EQUAL(FnvHash<ui64>(TStringBuf()), FNV64INIT);
- }
-};
+ UNIT_ASSERT_EQUAL(FnvHash<ui64>(nullptr, 0), FNV64INIT);
+ UNIT_ASSERT_EQUAL(FnvHash<ui64>(TStringBuf()), FNV64INIT);
+ }
+};
diff --git a/util/digest/multi.h b/util/digest/multi.h
index 8e4597c9dc..20af44f426 100644
--- a/util/digest/multi.h
+++ b/util/digest/multi.h
@@ -4,11 +4,11 @@
#include "numeric.h"
-template <typename TOne>
+template <typename TOne>
constexpr size_t MultiHash(const TOne& one) noexcept {
return THash<TOne>()(one);
}
-template <typename THead, typename... TTail>
+template <typename THead, typename... TTail>
constexpr size_t MultiHash(const THead& head, const TTail&... tail) noexcept {
return CombineHashes(MultiHash(tail...), THash<THead>()(head));
}
diff --git a/util/digest/murmur.cpp b/util/digest/murmur.cpp
index b041d3e5f2..86b310a8ab 100644
--- a/util/digest/murmur.cpp
+++ b/util/digest/murmur.cpp
@@ -127,5 +127,5 @@ namespace NMurmurPrivate {
}
size_t MurmurHashSizeT(const char* buf, size_t len) noexcept {
- return MurmurHash<size_t>(buf, len);
-}
+ return MurmurHash<size_t>(buf, len);
+}
diff --git a/util/digest/murmur.h b/util/digest/murmur.h
index 6b519b430a..4715a2378d 100644
--- a/util/digest/murmur.h
+++ b/util/digest/murmur.h
@@ -1,20 +1,20 @@
#pragma once
-
+
#include <util/system/defaults.h>
#include <util/generic/array_ref.h>
-
+
/*
* murmur2 from http://murmurhash.googlepages.com/
*
- */
+ */
namespace NMurmurPrivate {
- Y_PURE_FUNCTION ui32 MurmurHash32(const void* key, size_t len, ui32 seed) noexcept;
-
- Y_PURE_FUNCTION ui64 MurmurHash64(const void* key, size_t len, ui64 seed) noexcept;
+ Y_PURE_FUNCTION ui32 MurmurHash32(const void* key, size_t len, ui32 seed) noexcept;
+
+ Y_PURE_FUNCTION ui64 MurmurHash64(const void* key, size_t len, ui64 seed) noexcept;
template <unsigned N>
struct TMurHelper;
-
+
#define DEF_MUR(t) \
template <> \
struct TMurHelper<t> { \
@@ -27,19 +27,19 @@ namespace NMurmurPrivate {
DEF_MUR(64)
#undef DEF_MUR
-}
-
-template <class T>
+}
+
+template <class T>
static inline T MurmurHash(const void* buf, size_t len, T init) noexcept {
return (T)NMurmurPrivate::TMurHelper<8 * sizeof(T)>::MurmurHash(buf, len, init);
-}
-
-template <class T>
+}
+
+template <class T>
static inline T MurmurHash(const void* buf, size_t len) noexcept {
return MurmurHash<T>(buf, len, (T)0);
-}
-
-//non-inline version
+}
+
+//non-inline version
size_t MurmurHashSizeT(const char* buf, size_t len) noexcept;
template <typename TOut = size_t>
diff --git a/util/digest/murmur_ut.cpp b/util/digest/murmur_ut.cpp
index 29287668bc..b12195bc7e 100644
--- a/util/digest/murmur_ut.cpp
+++ b/util/digest/murmur_ut.cpp
@@ -1,32 +1,32 @@
-#include "murmur.h"
-
+#include "murmur.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-class TMurmurHashTest: public TTestBase {
- UNIT_TEST_SUITE(TMurmurHashTest);
- UNIT_TEST(TestHash32)
+
+class TMurmurHashTest: public TTestBase {
+ UNIT_TEST_SUITE(TMurmurHashTest);
+ UNIT_TEST(TestHash32)
UNIT_TEST(TestUnalignedHash32)
- UNIT_TEST(TestHash64)
+ UNIT_TEST(TestHash64)
UNIT_TEST(TestUnalignedHash64)
UNIT_TEST(TestWrapperBiggerTypes)
- UNIT_TEST_SUITE_END();
-
-private:
- inline void TestHash32() {
- ui8 buf[256];
-
- for (size_t i = 0; i < 256; ++i) {
- buf[i] = i;
- }
-
- Test<ui32>(buf, 256, 2373126550UL);
+ UNIT_TEST_SUITE_END();
+
+private:
+ inline void TestHash32() {
+ ui8 buf[256];
+
+ for (size_t i = 0; i < 256; ++i) {
+ buf[i] = i;
+ }
+
+ Test<ui32>(buf, 256, 2373126550UL);
TestWrapper<ui8, ui32>({buf, buf + 256}, 2373126550UL);
- Test<ui32>(buf, 255, 3301607533UL);
- Test<ui32>(buf, 254, 2547410121UL);
- Test<ui32>(buf, 253, 80030810UL);
- }
-
+ Test<ui32>(buf, 255, 3301607533UL);
+ Test<ui32>(buf, 254, 2547410121UL);
+ Test<ui32>(buf, 253, 80030810UL);
+ }
+
inline void TestUnalignedHash32() {
ui8 buf[257];
ui8* unalignedBuf = buf + 1;
@@ -38,20 +38,20 @@ private:
Test<ui32>(unalignedBuf, 256, 2373126550UL);
}
- inline void TestHash64() {
- ui8 buf[256];
-
- for (size_t i = 0; i < 256; ++i) {
- buf[i] = i;
- }
-
- Test<ui64>(buf, 256, ULL(12604435678857905857));
+ inline void TestHash64() {
+ ui8 buf[256];
+
+ for (size_t i = 0; i < 256; ++i) {
+ buf[i] = i;
+ }
+
+ Test<ui64>(buf, 256, ULL(12604435678857905857));
TestWrapper<ui8, ui64>({buf, buf + 256}, ULL(12604435678857905857));
- Test<ui64>(buf, 255, ULL(1708835094528446095));
- Test<ui64>(buf, 254, ULL(5077937678736514994));
- Test<ui64>(buf, 253, ULL(11553864555081396353));
- }
-
+ Test<ui64>(buf, 255, ULL(1708835094528446095));
+ Test<ui64>(buf, 254, ULL(5077937678736514994));
+ Test<ui64>(buf, 253, ULL(11553864555081396353));
+ }
+
inline void TestUnalignedHash64() {
ui8 buf[257];
ui8* unalignedBuf = buf + 1;
@@ -69,17 +69,17 @@ private:
TestWrapper<ui32, ui64>({buf, buf + 2}, MurmurHash<ui64>(buf, sizeof(ui32) * 2));
}
-private:
- template <class T>
- inline void Test(const void* data, size_t len, T expected) {
- UNIT_ASSERT_STRINGS_EQUAL(ToString(MurmurHash<T>(data, len)), ToString(expected));
- }
+private:
+ template <class T>
+ inline void Test(const void* data, size_t len, T expected) {
+ UNIT_ASSERT_STRINGS_EQUAL(ToString(MurmurHash<T>(data, len)), ToString(expected));
+ }
template <class E, class T>
inline void TestWrapper(const TArrayRef<E>& array, T expected) {
auto val = TMurmurHash<T>()(array);
UNIT_ASSERT_EQUAL(val, expected);
}
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TMurmurHashTest);
+};
+
+UNIT_TEST_SUITE_REGISTRATION(TMurmurHashTest);
diff --git a/util/digest/numeric.cpp b/util/digest/numeric.cpp
index d4d3f063fa..7299191d58 100644
--- a/util/digest/numeric.cpp
+++ b/util/digest/numeric.cpp
@@ -1 +1 @@
-#include "numeric.h"
+#include "numeric.h"
diff --git a/util/digest/numeric.h b/util/digest/numeric.h
index e20bd908e4..87b8b648d6 100644
--- a/util/digest/numeric.h
+++ b/util/digest/numeric.h
@@ -1,86 +1,86 @@
#pragma once
-
+
#include <util/generic/typelist.h>
#include <util/system/defaults.h>
-
-/*
+
+/*
* original url (now dead): http://www.cris.com/~Ttwang/tech/inthash.htm
* copy: https://gist.github.com/badboy/6267743
- */
-
+ */
+
static constexpr ui8 IntHashImpl(ui8 key8) noexcept {
- size_t key = key8;
-
- key += ~(key << 15);
- key ^= (key >> 10);
- key += (key << 3);
- key ^= (key >> 6);
- key += ~(key << 11);
- key ^= (key >> 16);
-
+ size_t key = key8;
+
+ key += ~(key << 15);
+ key ^= (key >> 10);
+ key += (key << 3);
+ key ^= (key >> 6);
+ key += ~(key << 11);
+ key ^= (key >> 16);
+
return static_cast<ui8>(key);
-}
-
+}
+
static constexpr ui16 IntHashImpl(ui16 key16) noexcept {
- size_t key = key16;
-
- key += ~(key << 15);
- key ^= (key >> 10);
- key += (key << 3);
- key ^= (key >> 6);
- key += ~(key << 11);
- key ^= (key >> 16);
-
+ size_t key = key16;
+
+ key += ~(key << 15);
+ key ^= (key >> 10);
+ key += (key << 3);
+ key ^= (key >> 6);
+ key += ~(key << 11);
+ key ^= (key >> 16);
+
return static_cast<ui16>(key);
-}
-
+}
+
static constexpr ui32 IntHashImpl(ui32 key) noexcept {
- key += ~(key << 15);
- key ^= (key >> 10);
- key += (key << 3);
- key ^= (key >> 6);
- key += ~(key << 11);
- key ^= (key >> 16);
-
- return key;
-}
-
+ key += ~(key << 15);
+ key ^= (key >> 10);
+ key += (key << 3);
+ key ^= (key >> 6);
+ key += ~(key << 11);
+ key ^= (key >> 16);
+
+ return key;
+}
+
static constexpr ui64 IntHashImpl(ui64 key) noexcept {
- key += ~(key << 32);
- key ^= (key >> 22);
- key += ~(key << 13);
- key ^= (key >> 8);
- key += (key << 3);
- key ^= (key >> 15);
- key += ~(key << 27);
- key ^= (key >> 31);
-
+ key += ~(key << 32);
+ key ^= (key >> 22);
+ key += ~(key << 13);
+ key ^= (key >> 8);
+ key += (key << 3);
+ key ^= (key >> 15);
+ key += ~(key << 27);
+ key ^= (key >> 31);
+
return key;
-}
-
-template <class T>
+}
+
+template <class T>
static constexpr T IntHash(T t) noexcept {
using TCvt = TFixedWidthUnsignedInt<T>;
-
- return IntHashImpl((TCvt)(t));
-}
-
-/*
- * can handle floats && pointers
- */
-template <class T>
+
+ return IntHashImpl((TCvt)(t));
+}
+
+/*
+ * can handle floats && pointers
+ */
+template <class T>
static constexpr size_t NumericHash(T t) noexcept {
using TCvt = TFixedWidthUnsignedInt<T>;
-
- union Y_HIDDEN {
+
+ union Y_HIDDEN {
T t;
- TCvt cvt;
+ TCvt cvt;
} u{t};
-
+
return (size_t)IntHash(u.cvt);
-}
-
-template <class T>
+}
+
+template <class T>
static constexpr T CombineHashes(T l, T r) noexcept {
- return IntHash(l) ^ r;
-}
+ return IntHash(l) ^ r;
+}
diff --git a/util/digest/sequence.h b/util/digest/sequence.h
index 712331007b..31a5200617 100644
--- a/util/digest/sequence.h
+++ b/util/digest/sequence.h
@@ -11,7 +11,7 @@ private:
using TBase = std::conditional_t<
!std::is_void<ElementHash>::value,
ElementHash,
- THash<ElementType>>;
+ THash<ElementType>>;
public:
template <typename Range>
@@ -33,7 +33,7 @@ private:
using TBase = std::conditional_t<
!std::is_void<RegionHash>::value,
RegionHash,
- TRangeHash<ElementType>>;
+ TRangeHash<ElementType>>;
public:
template <typename ContainerType>
diff --git a/util/digest/sequence_ut.cpp b/util/digest/sequence_ut.cpp
index 87d6102ee5..5a8c5ddb30 100644
--- a/util/digest/sequence_ut.cpp
+++ b/util/digest/sequence_ut.cpp
@@ -44,11 +44,11 @@ private:
}
};
-class TSequenceHashTest: public TTestBase {
+class TSequenceHashTest: public TTestBase {
UNIT_TEST_SUITE(TSequenceHashTest);
UNIT_TEST(TestSimpleBuffer)
UNIT_TEST_SUITE_END();
-
+
private:
inline void TestSimpleBuffer() {
int arr[] = {1, 2, 3};
diff --git a/util/digest/ut/ya.make b/util/digest/ut/ya.make
index 245b2cf6d2..f8eee55a5f 100644
--- a/util/digest/ut/ya.make
+++ b/util/digest/ut/ya.make
@@ -1,12 +1,12 @@
-UNITTEST_FOR(util)
+UNITTEST_FOR(util)
OWNER(g:util)
SUBSCRIBER(g:util-subscribers)
SRCS(
- digest/fnv_ut.cpp
- digest/murmur_ut.cpp
- digest/multi_ut.cpp
+ digest/fnv_ut.cpp
+ digest/murmur_ut.cpp
+ digest/multi_ut.cpp
digest/sequence_ut.cpp
)