#pragma once #include "block_item.h" #include #include #include #include namespace NYql::NUdf { // ABI stable class IBlockItemHasher { public: using TPtr = TUniquePtr; virtual ~IBlockItemHasher() = default; virtual ui64 Hash(TBlockItem value) const = 0; }; UDF_ASSERT_TYPE_SIZE(IBlockItemHasher, 8); template class TBlockItemHasherBase : public IBlockItemHasher { public: const TDerived* Derived() const { return static_cast(this); } ui64 Hash(TBlockItem value) const final { // keep hash computation in sync with // ydb/library/yql/minikql/mkql_type_builder.cpp: THash::Hash() if constexpr (Nullable) { if (!value) { return 0; } return CombineHashes(ui64(1), Derived()->DoHash(value)); } else { return Derived()->DoHash(value); } } }; template class TFixedSizeBlockItemHasher : public TBlockItemHasherBase, Nullable> { public: ui64 DoHash(TBlockItem value) const { return GetValueHash::Slot>(NUdf::TUnboxedValuePod(value.As())); } }; template class TFixedSizeBlockItemHasher : public TBlockItemHasherBase, Nullable> { public: ui64 DoHash(TBlockItem value) const { return GetValueHash::Slot>(NUdf::TUnboxedValuePod(value.GetInt128())); } }; template class TTzDateBlockItemHasher : public TBlockItemHasherBase, Nullable> { public: ui64 DoHash(TBlockItem value) const { using TLayout = typename TDataType::TLayout; TUnboxedValuePod uv {value.Get()}; uv.SetTimezoneId(value.GetTimezoneId()); return GetValueHash::Slot>(uv); } }; template class TStringBlockItemHasher : public TBlockItemHasherBase, Nullable> { public: ui64 DoHash(TBlockItem value) const { return GetStringHash(value.AsStringRef()); } }; template class TTupleBlockItemHasher : public TBlockItemHasherBase, Nullable> { public: TTupleBlockItemHasher(TVector>&& children) : Children_(std::move(children)) {} ui64 DoHash(TBlockItem value) const { // keep hash computation in sync with // ydb/library/yql/minikql/mkql_type_builder.cpp: TVectorHash::Hash() ui64 result = 0ULL; auto elements = value.GetElements(); for (ui32 i = 0; i < Children_.size(); ++i) { result = CombineHashes(result, Children_[i]->Hash(elements[i])); } return result; } private: const TVector> Children_; }; class TExternalOptionalBlockItemHasher : public TBlockItemHasherBase { public: TExternalOptionalBlockItemHasher(std::unique_ptr&& inner) : Inner_(std::move(inner)) {} ui64 DoHash(TBlockItem value) const { return Inner_->Hash(value.GetOptionalValue()); } private: const std::unique_ptr Inner_; }; }