diff options
author | galtsev <galtsev@yandex-team.com> | 2025-01-10 20:37:38 +0300 |
---|---|---|
committer | galtsev <galtsev@yandex-team.com> | 2025-01-10 22:01:29 +0300 |
commit | c8a9d5ee43af5a4d6091b81c37726a752b5d94ea (patch) | |
tree | a792f362ecf478dc0286e4182003bcdcbfbe793f | |
parent | 52564b20aa3bff58cad057f4a7ae705d6e4b4cdc (diff) | |
download | ydb-c8a9d5ee43af5a4d6091b81c37726a752b5d94ea.tar.gz |
YT-21993: Add the `BeforeVersion()` modifier
commit_hash:3dfdc0b2e63d7ebc47a5b433c2f6548b15b3cb1e
-rw-r--r-- | yt/yt/core/phoenix/type_def-inl.h | 51 | ||||
-rw-r--r-- | yt/yt/core/phoenix/unittests/phoenix_ut.cpp | 69 |
2 files changed, 115 insertions, 5 deletions
diff --git a/yt/yt/core/phoenix/type_def-inl.h b/yt/yt/core/phoenix/type_def-inl.h index b7322d7955..47726ced5d 100644 --- a/yt/yt/core/phoenix/type_def-inl.h +++ b/yt/yt/core/phoenix/type_def-inl.h @@ -146,6 +146,11 @@ public: return std::move(*this); } + auto BeforeVersion(auto /*version*/) && + { + return std::move(*this); + } + auto InVersions(auto /*filter*/) && { return std::move(*this); @@ -346,6 +351,8 @@ template <auto Member, class TThis, class TContext, class TFieldSerializer> class PHOENIX_REGISTRAR_NODISCARD TFieldSaveRegistrar { public: + using TVersion = typename TTraits<TThis>::TVersion; + TFieldSaveRegistrar(const TThis* this_, TContext& context) : This_(this_) , Context_(context) @@ -362,6 +369,12 @@ public: return TFieldSaveRegistrar(std::move(*this)); } + auto BeforeVersion(TVersion version) && + { + BeforeVersion_ = version; + return TFieldSaveRegistrar(std::move(*this)); + } + auto InVersions(TVersionFilter<TThis> filter) && { VersionFilter_ = filter; @@ -381,7 +394,7 @@ public: void operator()() && { - if (!VersionFilter_ || VersionFilter_(Context_.GetVersion())) { + if (auto version = Context_.GetVersion(); version < BeforeVersion_ && (!VersionFilter_ || VersionFilter_(version))) { TFieldSerializer::Save(Context_, This_->*Member); } } @@ -394,6 +407,7 @@ private: TContext& Context_; TVersionFilter<TThis> VersionFilter_ = nullptr; + TVersion BeforeVersion_ = static_cast<TVersion>(std::numeric_limits<int>::max()); }; template <class TThis, class TContext> @@ -420,6 +434,11 @@ public: return TVirtualFieldSaveRegistrar(std::move(*this)); } + auto BeforeVersion(auto /*version*/) && + { + return TVirtualFieldSaveRegistrar(std::move(*this)); + } + auto InVersions(auto /*filter*/) && { return TVirtualFieldSaveRegistrar(std::move(*this)); @@ -548,6 +567,7 @@ public: , Context_(other.Context_) , Name_(other.Name_) , MinVersion_(other.MinVersion_) + , BeforeVersion_(other.BeforeVersion_) , VersionFilter_(other.VersionFilter_) , MissingHandler_(other.MissingHandler_) { } @@ -560,6 +580,12 @@ public: return TFieldLoadRegistrar(std::move(*this)); } + auto BeforeVersion(TVersion version) && + { + BeforeVersion_ = version; + return TFieldLoadRegistrar(std::move(*this)); + } + auto WhenMissing(TFieldMissingHandler<TThis, TContext> handler) && { MissingHandler_ = handler; @@ -581,7 +607,7 @@ public: void operator()() && { - if (auto version = Context_.GetVersion(); version >= MinVersion_ && (!VersionFilter_ || VersionFilter_(version))) { + if (auto version = Context_.GetVersion(); version >= MinVersion_ && version < BeforeVersion_ && (!VersionFilter_ || VersionFilter_(version))) { Context_.Dumper().SetFieldName(Name_); TFieldSerializer::Load(Context_, This_->*Member); } else if (MissingHandler_) { @@ -600,6 +626,7 @@ private: const TStringBuf Name_; TVersion MinVersion_ = static_cast<TVersion>(std::numeric_limits<int>::min()); + TVersion BeforeVersion_ = static_cast<TVersion>(std::numeric_limits<int>::max()); TVersionFilter<TThis> VersionFilter_ = nullptr; TFieldMissingHandler<TThis, TContext> MissingHandler_ = nullptr; }; @@ -625,6 +652,7 @@ public: , Name_(other.Name_) , LoadHandler_(other.LoadHandler) , MinVersion_(other.MinVersion_) + , BeforeVersion_(other.BeforeVersion_) , VersionFilter_(other.VersionFilter_) , MissingHandler_(other.MissingHandler_) { } @@ -637,6 +665,12 @@ public: return TFieldLoadRegistrar(std::move(*this)); } + auto BeforeVersion(TVersion version) && + { + BeforeVersion_ = version; + return TFieldLoadRegistrar(std::move(*this)); + } + auto WhenMissing(TFieldMissingHandler<TThis, TContext> handler) && { MissingHandler_ = handler; @@ -654,7 +688,7 @@ public: void operator()() && { - if (auto version = Context_.GetVersion(); version >= MinVersion_ && (!VersionFilter_ || VersionFilter_(version))) { + if (auto version = Context_.GetVersion(); version >= MinVersion_ && version < BeforeVersion_ && (!VersionFilter_ || VersionFilter_(version))) { Context_.Dumper().SetFieldName(Name_); LoadHandler_(This_, Context_); } else if (MissingHandler_) { @@ -669,6 +703,7 @@ private: const TFieldLoadHandler<TThis, TContext> LoadHandler_; TVersion MinVersion_ = static_cast<TVersion>(std::numeric_limits<int>::min()); + TVersion BeforeVersion_ = static_cast<TVersion>(std::numeric_limits<int>::max()); TVersionFilter VersionFilter_ = nullptr; TFieldMissingHandler<TThis, TContext> MissingHandler_ = nullptr; }; @@ -789,6 +824,11 @@ public: return std::move(*this); } + auto BeforeVersion(auto /*version*/) && + { + return std::move(*this); + } + auto InVersions(auto /*filter*/) && { return std::move(*this); @@ -835,6 +875,11 @@ public: return *this; } + auto BeforeVersion(auto /*version*/) && + { + return *this; + } + auto InVersions(auto /*filter*/) && { return *this; diff --git a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp index ac4ad2163d..165c157be2 100644 --- a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp +++ b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp @@ -25,11 +25,11 @@ using NYT::Load; //////////////////////////////////////////////////////////////////////////////// template <class T> -TString Serialize(const T& value) +TString Serialize(const T& value, int version = 0) { TString buffer; TStringOutput output(buffer); - TSaveContext context(&output); + TSaveContext context(&output, version); Save(context, value); context.Finish(); return buffer; @@ -312,6 +312,71 @@ TEST(TPhoenixTest, SinceVersionNew) //////////////////////////////////////////////////////////////////////////////// +namespace NBeforeVersion { + +struct S +{ + int A; + int B; + int C; + + bool operator==(const S&) const = default; + + PHOENIX_DECLARE_TYPE(S, 0xc8da1575); +}; + +void S::RegisterMetadata(auto&& registrar) +{ + PHOENIX_REGISTER_FIELD(1, A)(); + PHOENIX_REGISTER_FIELD(2, B) + .BeforeVersion(100)(); + PHOENIX_REGISTER_FIELD(3, C) + .BeforeVersion(200) + .WhenMissing([] (TThis* this_, auto& /*context*/) { + this_->C = 777; + })(); +} + +PHOENIX_DEFINE_TYPE(S); + +} // namespace NBeforeVersion + +TEST(TPhoenixTest, BeforeVersionOld) +{ + using namespace NBeforeVersion; + + S s1; + s1.A = 123; + s1.B = 456; + s1.C = 321; + + auto buffer = Serialize(s1); + ASSERT_EQ(buffer.size(), sizeof(s1)); + + auto s2 = Deserialize<S>(buffer); + EXPECT_EQ(s1, s2); +} + +TEST(TPhoenixTest, BeforeVersionNew) +{ + using namespace NBeforeVersion; + + S s1; + s1.A = 123; + s1.B = 0; + s1.C = 777; + + int version = 200; + + auto buffer = Serialize(s1, version); + ASSERT_EQ(buffer.size(), sizeof(s1.A)); + + auto s2 = Deserialize<S>(buffer, version); + EXPECT_EQ(s1, s2); +} + +//////////////////////////////////////////////////////////////////////////////// + namespace NInVersions { struct S |