city.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma once
  2. #include <util/generic/utility.h>
  3. #include <util/generic/strbuf.h>
  4. #include <utility>
  5. // NOTE: These functions provide CityHash 1.0 implementation whose results are *different* from
  6. // the mainline version of CityHash.
  7. using uint128 = std::pair<ui64, ui64>;
  8. constexpr ui64 Uint128Low64(const uint128& x) {
  9. return x.first;
  10. }
  11. constexpr ui64 Uint128High64(const uint128& x) {
  12. return x.second;
  13. }
  14. // Hash functions for a byte array.
  15. // http://en.wikipedia.org/wiki/CityHash
  16. Y_PURE_FUNCTION ui64 CityHash64(const char* buf, size_t len) noexcept;
  17. Y_PURE_FUNCTION ui64 CityHash64WithSeed(const char* buf, size_t len, ui64 seed) noexcept;
  18. Y_PURE_FUNCTION ui64 CityHash64WithSeeds(const char* buf, size_t len, ui64 seed0, ui64 seed1) noexcept;
  19. Y_PURE_FUNCTION uint128 CityHash128(const char* s, size_t len) noexcept;
  20. Y_PURE_FUNCTION uint128 CityHash128WithSeed(const char* s, size_t len, uint128 seed) noexcept;
  21. // Hash 128 input bits down to 64 bits of output.
  22. // This is intended to be a reasonably good hash function.
  23. inline ui64 Hash128to64(const uint128& x) {
  24. // Murmur-inspired hashing.
  25. const ui64 kMul = 0x9ddfea08eb382d69ULL;
  26. ui64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
  27. a ^= (a >> 47);
  28. ui64 b = (Uint128High64(x) ^ a) * kMul;
  29. b ^= (b >> 47);
  30. b *= kMul;
  31. return b;
  32. }
  33. namespace NPrivateCityHash {
  34. template <class TStringType>
  35. inline TStringBuf GetBufFromStr(const TStringType& str) {
  36. static_assert(std::is_integral<std::remove_reference_t<decltype(*str.data())>>::value, "invalid type passed to hash function");
  37. return TStringBuf(reinterpret_cast<const char*>(str.data()), (str.size()) * sizeof(*str.data()));
  38. }
  39. }
  40. template <class TStringType>
  41. inline ui64 CityHash64(const TStringType& str) {
  42. TStringBuf buf = NPrivateCityHash::GetBufFromStr(str);
  43. return CityHash64(buf.data(), buf.size());
  44. }
  45. template <class TStringType>
  46. inline ui64 CityHash64WithSeeds(const TStringType& str, ui64 seed0, ui64 seed1) {
  47. TStringBuf buf = NPrivateCityHash::GetBufFromStr(str);
  48. return CityHash64WithSeeds(buf.data(), buf.size(), seed0, seed1);
  49. }
  50. template <class TStringType>
  51. inline ui64 CityHash64WithSeed(const TStringType& str, ui64 seed) {
  52. TStringBuf buf = NPrivateCityHash::GetBufFromStr(str);
  53. return CityHash64WithSeed(buf.data(), buf.size(), seed);
  54. }
  55. template <class TStringType>
  56. inline uint128 CityHash128(const TStringType& str) {
  57. TStringBuf buf = NPrivateCityHash::GetBufFromStr(str);
  58. return CityHash128(buf.data(), buf.size());
  59. }
  60. template <class TStringType>
  61. inline uint128 CityHash128WithSeed(const TStringType& str, uint128 seed) {
  62. TStringBuf buf = NPrivateCityHash::GetBufFromStr(str);
  63. return CityHash128WithSeed(buf.data(), buf.size(), seed);
  64. }