aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgaltsev <galtsev@yandex-team.com>2025-01-10 20:37:38 +0300
committergaltsev <galtsev@yandex-team.com>2025-01-10 22:01:29 +0300
commitc8a9d5ee43af5a4d6091b81c37726a752b5d94ea (patch)
treea792f362ecf478dc0286e4182003bcdcbfbe793f
parent52564b20aa3bff58cad057f4a7ae705d6e4b4cdc (diff)
downloadydb-c8a9d5ee43af5a4d6091b81c37726a752b5d94ea.tar.gz
YT-21993: Add the `BeforeVersion()` modifier
commit_hash:3dfdc0b2e63d7ebc47a5b433c2f6548b15b3cb1e
-rw-r--r--yt/yt/core/phoenix/type_def-inl.h51
-rw-r--r--yt/yt/core/phoenix/unittests/phoenix_ut.cpp69
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