block_item_hasher.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #pragma once
  2. #include "block_item.h"
  3. #include <yql/essentials/public/udf/udf_ptr.h>
  4. #include <yql/essentials/public/udf/udf_type_inspection.h>
  5. #include <yql/essentials/public/udf/udf_type_ops.h>
  6. #include <yql/essentials/public/udf/udf_type_size_check.h>
  7. namespace NYql::NUdf {
  8. // ABI stable
  9. class IBlockItemHasher {
  10. public:
  11. using TPtr = TUniquePtr<IBlockItemHasher>;
  12. virtual ~IBlockItemHasher() = default;
  13. virtual ui64 Hash(TBlockItem value) const = 0;
  14. };
  15. UDF_ASSERT_TYPE_SIZE(IBlockItemHasher, 8);
  16. template <typename TDerived, bool Nullable>
  17. class TBlockItemHasherBase : public IBlockItemHasher {
  18. public:
  19. const TDerived* Derived() const {
  20. return static_cast<const TDerived*>(this);
  21. }
  22. ui64 Hash(TBlockItem value) const final {
  23. // keep hash computation in sync with
  24. // ydb/library/yql/minikql/mkql_type_builder.cpp: THash<NMiniKQL::TType::EKind::Optional>::Hash()
  25. if constexpr (Nullable) {
  26. if (!value) {
  27. return 0;
  28. }
  29. return CombineHashes(ui64(1), Derived()->DoHash(value));
  30. } else {
  31. return Derived()->DoHash(value);
  32. }
  33. }
  34. };
  35. template <typename T, bool Nullable>
  36. class TFixedSizeBlockItemHasher : public TBlockItemHasherBase<TFixedSizeBlockItemHasher<T, Nullable>, Nullable> {
  37. public:
  38. ui64 DoHash(TBlockItem value) const {
  39. return GetValueHash<TDataType<T>::Slot>(NUdf::TUnboxedValuePod(value.As<T>()));
  40. }
  41. };
  42. template <bool Nullable>
  43. class TFixedSizeBlockItemHasher<NYql::NDecimal::TInt128, Nullable> : public TBlockItemHasherBase<TFixedSizeBlockItemHasher<NYql::NDecimal::TInt128, Nullable>, Nullable> {
  44. public:
  45. ui64 DoHash(TBlockItem value) const {
  46. return GetValueHash<TDataType<NUdf::TDecimal>::Slot>(NUdf::TUnboxedValuePod(value.GetInt128()));
  47. }
  48. };
  49. template <typename T, bool Nullable>
  50. class TTzDateBlockItemHasher : public TBlockItemHasherBase<TTzDateBlockItemHasher<T, Nullable>, Nullable> {
  51. public:
  52. ui64 DoHash(TBlockItem value) const {
  53. using TLayout = typename TDataType<T>::TLayout;
  54. TUnboxedValuePod uv {value.Get<TLayout>()};
  55. uv.SetTimezoneId(value.GetTimezoneId());
  56. return GetValueHash<TDataType<T>::Slot>(uv);
  57. }
  58. };
  59. template <typename TStringType, bool Nullable>
  60. class TStringBlockItemHasher : public TBlockItemHasherBase<TStringBlockItemHasher<TStringType, Nullable>, Nullable> {
  61. public:
  62. ui64 DoHash(TBlockItem value) const {
  63. return GetStringHash(value.AsStringRef());
  64. }
  65. };
  66. template <bool Nullable>
  67. class TTupleBlockItemHasher : public TBlockItemHasherBase<TTupleBlockItemHasher<Nullable>, Nullable> {
  68. public:
  69. TTupleBlockItemHasher(TVector<std::unique_ptr<IBlockItemHasher>>&& children)
  70. : Children_(std::move(children))
  71. {}
  72. ui64 DoHash(TBlockItem value) const {
  73. // keep hash computation in sync with
  74. // ydb/library/yql/minikql/mkql_type_builder.cpp: TVectorHash::Hash()
  75. ui64 result = 0ULL;
  76. auto elements = value.GetElements();
  77. for (ui32 i = 0; i < Children_.size(); ++i) {
  78. result = CombineHashes(result, Children_[i]->Hash(elements[i]));
  79. }
  80. return result;
  81. }
  82. private:
  83. const TVector<std::unique_ptr<IBlockItemHasher>> Children_;
  84. };
  85. class TExternalOptionalBlockItemHasher : public TBlockItemHasherBase<TExternalOptionalBlockItemHasher, true> {
  86. public:
  87. TExternalOptionalBlockItemHasher(std::unique_ptr<IBlockItemHasher>&& inner)
  88. : Inner_(std::move(inner))
  89. {}
  90. ui64 DoHash(TBlockItem value) const {
  91. return Inner_->Hash(value.GetOptionalValue());
  92. }
  93. private:
  94. const std::unique_ptr<IBlockItemHasher> Inner_;
  95. };
  96. }