aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorh0pless <h0pless@yandex-team.com>2024-05-15 16:02:34 +0300
committerh0pless <h0pless@yandex-team.com>2024-05-15 16:18:32 +0300
commit1c3cea8ba893a97b04ddc33ad381f17d2bf05ef8 (patch)
tree31dba695a2633d58213313d7c00e51fb3316e319
parent60692c0c917cc24ca10fd4c1c0155090bd0f851c (diff)
downloadydb-1c3cea8ba893a97b04ddc33ad381f17d2bf05ef8.tar.gz
Improve support for DontSerializeDefault; Add DontSerializeDefault to fix snapshot divergence when rolling 23.2
964925e3330bb2bc336b4c2721370bbd33f05f34
-rw-r--r--yt/yt/core/ytree/yson_struct_detail-inl.h64
1 files changed, 51 insertions, 13 deletions
diff --git a/yt/yt/core/ytree/yson_struct_detail-inl.h b/yt/yt/core/ytree/yson_struct_detail-inl.h
index c34a934c162..fefe704afb6 100644
--- a/yt/yt/core/ytree/yson_struct_detail-inl.h
+++ b/yt/yt/core/ytree/yson_struct_detail-inl.h
@@ -18,20 +18,58 @@ namespace NYT::NYTree {
namespace NPrivate {
-// TODO(shakurov): get rid of this once concept support makes it into the standard
-// library implementation. Use equality-comparability instead.
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+concept CTupleLike = requires {
+ std::tuple_size<T>{};
+};
+
+template <class T>
+concept CContainerLike = requires {
+ typename T::value_type;
+};
+
+template <class T>
+struct TEqualityComparableHelper
+{
+ constexpr static bool Value = std::equality_comparable<T>;
+};
+
+template <class T, size_t... I>
+constexpr bool IsSequenceEqualityComparable(std::index_sequence<I...> /*sequence*/)
+{
+ return (TEqualityComparableHelper<typename std::tuple_element<I, T>::type>::Value && ...);
+}
+
+template <CTupleLike T>
+struct TEqualityComparableHelper<T>
+{
+ constexpr static bool Value = IsSequenceEqualityComparable<T>(std::make_index_sequence<std::tuple_size<T>::value>());
+};
+
+template <CContainerLike T>
+struct TEqualityComparableHelper<T>
+{
+ constexpr static bool Value = TEqualityComparableHelper<typename T::value_type>::Value;
+};
+
+} // namespace NDetail
+
+////////////////////////////////////////////////////////////////////////////////
+
+// TODO(h0pless): Get rid of this once containers will have constraints for equality operator.
+// Once this will be the case, it should be safe to use std::equality_comparable here instead.
template <class T>
-concept SupportsDontSerializeDefaultImpl =
- std::is_arithmetic_v<T> ||
- std::is_same_v<T, TString> ||
- std::is_same_v<T, TDuration> ||
- std::is_same_v<T, TGuid> ||
- std::is_same_v<T, std::optional<std::vector<TString>>> ||
- std::is_same_v<T, THashSet<TString>>;
+concept CRecursivelyEqualityComparable = NDetail::TEqualityComparableHelper<T>::Value;
template <class T>
-concept SupportsDontSerializeDefault =
- SupportsDontSerializeDefaultImpl<typename TWrapperTraits<T>::TRecursiveUnwrapped>;
+concept CSupportsDontSerializeDefault =
+ CRecursivelyEqualityComparable<typename TWrapperTraits<T>::TRecursiveUnwrapped>;
////////////////////////////////////////////////////////////////////////////////
@@ -654,7 +692,7 @@ template <class TValue>
bool TYsonStructParameter<TValue>::CanOmitValue(const TYsonStructBase* self) const
{
const auto& value = FieldAccessor_->GetValue(self);
- if constexpr (NPrivate::SupportsDontSerializeDefault<TValue>) {
+ if constexpr (NPrivate::CSupportsDontSerializeDefault<TValue>) {
if (!SerializeDefault_ && value == (*DefaultCtor_)()) {
return true;
}
@@ -745,7 +783,7 @@ TYsonStructParameter<TValue>& TYsonStructParameter<TValue>::DontSerializeDefault
// We should check for equality-comparability here but it is rather hard
// to do the deep validation.
static_assert(
- NPrivate::SupportsDontSerializeDefault<TValue>,
+ NPrivate::CSupportsDontSerializeDefault<TValue>,
"DontSerializeDefault requires |Parameter| to be TString, TDuration, an arithmetic type or an optional of those");
SerializeDefault_ = false;