summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbabenko <[email protected]>2024-06-10 18:58:27 +0300
committerbabenko <[email protected]>2024-06-10 19:07:43 +0300
commite2add312a22e219fb94e385160a305343d7b71b4 (patch)
tree00f1608428303f3be82f5bb88efbea9a1e05847d
parent68414a30062e5b7f2b9e63eca166c628c4917092 (diff)
Add InVersions field annotation
6dbc324457c2c7f6e2a6c72524d8a502e9a17f25
-rw-r--r--yt/yt/core/phoenix/descriptors.cpp12
-rw-r--r--yt/yt/core/phoenix/descriptors.h2
-rw-r--r--yt/yt/core/phoenix/load.cpp8
-rw-r--r--yt/yt/core/phoenix/schemas.cpp6
-rw-r--r--yt/yt/core/phoenix/schemas.h2
-rw-r--r--yt/yt/core/phoenix/type_decl-inl.h5
-rw-r--r--yt/yt/core/phoenix/type_def-inl.h75
-rw-r--r--yt/yt/core/phoenix/type_def.cpp6
-rw-r--r--yt/yt/core/phoenix/unittests/phoenix_ut.cpp124
9 files changed, 168 insertions, 72 deletions
diff --git a/yt/yt/core/phoenix/descriptors.cpp b/yt/yt/core/phoenix/descriptors.cpp
index e0240c04b0e..cbf2fa46135 100644
--- a/yt/yt/core/phoenix/descriptors.cpp
+++ b/yt/yt/core/phoenix/descriptors.cpp
@@ -23,16 +23,6 @@ bool TFieldDescriptor::IsDeprecated() const
return Deprecated_;
}
-int TFieldDescriptor::GetMinVersion() const
-{
- return MinVersion_;
-}
-
-int TFieldDescriptor::GetMaxVersion() const
-{
- return MaxVersion_;
-}
-
const TFieldSchemaPtr& TFieldDescriptor::GetSchema() const
{
std::call_once(
@@ -41,8 +31,6 @@ const TFieldSchemaPtr& TFieldDescriptor::GetSchema() const
Schema_ = New<TFieldSchema>();
Schema_->Name = Name_;
Schema_->Tag = Tag_;
- Schema_->MinVersion = MinVersion_;
- Schema_->MaxVersion = MaxVersion_;
Schema_->Deprecated = Deprecated_;
});
return Schema_;
diff --git a/yt/yt/core/phoenix/descriptors.h b/yt/yt/core/phoenix/descriptors.h
index 38303a85e04..d7ec04d7f25 100644
--- a/yt/yt/core/phoenix/descriptors.h
+++ b/yt/yt/core/phoenix/descriptors.h
@@ -30,8 +30,6 @@ public:
const TString& GetName() const;
TFieldTag GetTag() const;
bool IsDeprecated() const;
- int GetMinVersion() const;
- int GetMaxVersion() const;
const TFieldSchemaPtr& GetSchema() const;
diff --git a/yt/yt/core/phoenix/load.cpp b/yt/yt/core/phoenix/load.cpp
index 3f2f0868afb..5e8c72641de 100644
--- a/yt/yt/core/phoenix/load.cpp
+++ b/yt/yt/core/phoenix/load.cpp
@@ -31,14 +31,6 @@ bool AreFieldSchemasEquivalent(
return false;
}
- if (lhsFieldDescriptor->GetMinVersion() != rhsFieldSchema->MinVersion) {
- return false;
- }
-
- if (lhsFieldDescriptor->GetMaxVersion() != rhsFieldSchema->MaxVersion) {
- return false;
- }
-
if (lhsFieldDescriptor->IsDeprecated() != rhsFieldSchema->Deprecated) {
return false;
}
diff --git a/yt/yt/core/phoenix/schemas.cpp b/yt/yt/core/phoenix/schemas.cpp
index 0a84d2eecd8..bdf5fcb0e6b 100644
--- a/yt/yt/core/phoenix/schemas.cpp
+++ b/yt/yt/core/phoenix/schemas.cpp
@@ -10,12 +10,6 @@ void TFieldSchema::Register(TRegistrar registrar)
{
registrar.Parameter("name", &TThis::Name);
registrar.Parameter("tag", &TThis::Tag);
- registrar.Parameter("min_version", &TThis::MinVersion)
- .Default(std::numeric_limits<int>::min())
- .DontSerializeDefault();
- registrar.Parameter("max_version", &TThis::MaxVersion)
- .Default(std::numeric_limits<int>::max())
- .DontSerializeDefault();
registrar.Parameter("deprecated", &TThis::Deprecated)
.Default(false)
.DontSerializeDefault();
diff --git a/yt/yt/core/phoenix/schemas.h b/yt/yt/core/phoenix/schemas.h
index 93009ecdc62..c418919c5b7 100644
--- a/yt/yt/core/phoenix/schemas.h
+++ b/yt/yt/core/phoenix/schemas.h
@@ -13,8 +13,6 @@ struct TFieldSchema
{
TString Name;
TFieldTag Tag;
- int MinVersion;
- int MaxVersion;
bool Deprecated;
REGISTER_YSON_STRUCT(TFieldSchema);
diff --git a/yt/yt/core/phoenix/type_decl-inl.h b/yt/yt/core/phoenix/type_decl-inl.h
index f63ce8083fd..e8750b31c4c 100644
--- a/yt/yt/core/phoenix/type_decl-inl.h
+++ b/yt/yt/core/phoenix/type_decl-inl.h
@@ -23,10 +23,13 @@ public: \
\
private: \
using TThis = type; \
+ using TLoadContextImpl = TLoadContext; \
\
template <class TThis, class TContext> \
friend std::unique_ptr<::NYT::NPhoenix2::NDetail::TRuntimeTypeLoadSchedule<TThis, TContext>> NYT::NPhoenix2::NDetail::BuildRuntimeTypeLoadSchedule( \
- const ::NYT::NPhoenix2::NDetail::TTypeLoadSchedule* schedule)
+ const ::NYT::NPhoenix2::NDetail::TTypeLoadSchedule* schedule); \
+ template <auto Member, class TThis, class TContext, class TFieldSerializer> \
+ friend class ::NYT::NPhoenix2::NDetail::TFieldLoadRegistrar
#define PHOENIX_DECLARE_TYPE__IMPL(type, typeTagValue, saveLoadModifier) \
PHOENIX_DECLARE_TYPE__PROLOGUE(type, typeTagValue); \
diff --git a/yt/yt/core/phoenix/type_def-inl.h b/yt/yt/core/phoenix/type_def-inl.h
index 21848d892b2..5dae193ba8e 100644
--- a/yt/yt/core/phoenix/type_def-inl.h
+++ b/yt/yt/core/phoenix/type_def-inl.h
@@ -81,6 +81,11 @@ public:
return std::move(*this);
}
+ auto InVersions(auto /*filter*/) &&
+ {
+ return std::move(*this);
+ }
+
auto WhenMissing(auto&& /*handler*/) &&
{
return std::move(*this);
@@ -128,32 +133,6 @@ decltype(auto) RunRegistrar(auto&& registrar)
////////////////////////////////////////////////////////////////////////////////
-class TFieldSchemaRegistrar
-{
-public:
- explicit TFieldSchemaRegistrar(TFieldDescriptor* descriptor);
-
- auto SinceVersion(auto version) &&
- {
- Descriptor_->MinVersion_ = static_cast<int>(version);
- return std::move(*this);
- }
-
- auto WhenMissing(auto&& /*handler*/) &&
- {
- return std::move(*this);
- }
-
- template <class TFieldSerializer>
- auto Serializer() &&
- {
- return std::move(*this);
- }
-
-private:
- TFieldDescriptor* const Descriptor_;
-};
-
class TTypeSchemaBuilderRegistar
: public TTypeRegistrarBase
{
@@ -188,14 +167,14 @@ private:
std::unique_ptr<TTypeDescriptor> TypeDescriptor_ = std::make_unique<TTypeDescriptor>();
template <TFieldTag::TUnderlying TagValue>
- TFieldSchemaRegistrar DoField(TString name, bool deprecated)
+ auto DoField(TString name, bool deprecated)
{
auto fieldDescriptor = std::make_unique<TFieldDescriptor>();
fieldDescriptor->Name_ = std::move(name);
fieldDescriptor->Tag_ = TFieldTag(TagValue);
fieldDescriptor->Deprecated_ = deprecated;
TypeDescriptor_->Fields_.push_back(std::move(fieldDescriptor));
- return TFieldSchemaRegistrar(TypeDescriptor_->Fields_.back().get());
+ return TDummyFieldRegistrar();
}
};
@@ -279,6 +258,11 @@ public:
return TFieldSaveRegistrar(std::move(*this));
}
+ auto InVersions(auto /*filter*/) &&
+ {
+ return TFieldSaveRegistrar(std::move(*this));
+ }
+
auto WhenMissing(auto&& /*handler*/) &&
{
return TFieldSaveRegistrar(std::move(*this));
@@ -376,19 +360,21 @@ public:
, Context_(other.Context_)
, Name_(other.Name_)
, MinVersion_(other.MinVersion_)
- , MaxVersion_(other.MaxVersion_)
+ , VersionFilter_(other.VersionFilter_)
, MissingHandler_(other.MissingHandler_)
{
other.Armed_ = false;
}
- auto SinceVersion(auto verison) &&
+ using TVersion = decltype(std::declval<typename TThis::TLoadContextImpl>().GetVersion());
+
+ auto SinceVersion(TVersion version) &&
{
- MinVersion_ = static_cast<int>(verison);
+ MinVersion_ = version;
return TFieldLoadRegistrar(std::move(*this));
}
- using TMissingHandler = void (*)(TThis*, TContext&);
+ using TMissingHandler = void (*)(TThis* this_, TContext& context);
auto WhenMissing(TMissingHandler handler) &&
{
@@ -396,6 +382,15 @@ public:
return TFieldLoadRegistrar(std::move(*this));
}
+ using TVersionFilter = bool (*)(TVersion version);
+
+ auto InVersions(TVersionFilter filter) &&
+ {
+ VersionFilter_ = filter;
+ return TFieldLoadRegistrar(std::move(*this));
+ }
+
+
template <class TFieldSerializer_>
auto Serializer() &&
{
@@ -405,7 +400,7 @@ public:
~TFieldLoadRegistrar()
{
if (Armed_) {
- if (auto version = static_cast<int>(Context_.GetVersion()); version >= MinVersion_ && version <= MaxVersion_) {
+ if (auto version = Context_.GetVersion(); version >= MinVersion_ && (!VersionFilter_ || VersionFilter_(version))) {
Context_.Dumper().SetFieldName(Name_);
TFieldSerializer::Load(Context_, This_->*Member);
} else if (MissingHandler_) {
@@ -424,8 +419,8 @@ private:
TContext& Context_;
const TStringBuf Name_;
- int MinVersion_ = std::numeric_limits<int>::min();
- int MaxVersion_ = std::numeric_limits<int>::max();
+ TVersion MinVersion_ = static_cast<TVersion>(std::numeric_limits<int>::min());
+ TVersionFilter VersionFilter_ = nullptr;
TMissingHandler MissingHandler_ = nullptr;
bool Armed_ = true;
@@ -534,6 +529,11 @@ public:
return std::move(*this);
}
+ auto InVersions(auto /*filter*/) &&
+ {
+ return std::move(*this);
+ }
+
auto WhenMissing(TFieldHandler<TThis, TContext> handler) &&
{
Descriptor_->MissingHandler = handler;
@@ -579,6 +579,11 @@ public:
return *this;
}
+ auto InVersions(auto /*filter*/) &&
+ {
+ return *this;
+ }
+
auto WhenMissing(TFieldHandler<TThis, TContext> handler) &&
{
Descriptor_->MissingHandler = handler;
diff --git a/yt/yt/core/phoenix/type_def.cpp b/yt/yt/core/phoenix/type_def.cpp
index 1fae18668a4..e1f18349407 100644
--- a/yt/yt/core/phoenix/type_def.cpp
+++ b/yt/yt/core/phoenix/type_def.cpp
@@ -26,12 +26,6 @@ const TTypeDescriptor& TTypeSchemaBuilderRegistar::Finish() &&
////////////////////////////////////////////////////////////////////////////////
-TFieldSchemaRegistrar::TFieldSchemaRegistrar(TFieldDescriptor* descriptor)
- : Descriptor_(descriptor)
-{ }
-
-////////////////////////////////////////////////////////////////////////////////
-
NConcurrency::TFlsSlot<TUniverseLoadState> UniverseLoadState;
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp
index 8dcb2e3e62e..8099b7a42a4 100644
--- a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp
+++ b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp
@@ -295,6 +295,130 @@ TEST(TPhoenixTest, SinceVersionNew)
////////////////////////////////////////////////////////////////////////////////
+namespace NInVersions {
+
+struct S
+{
+ int A;
+ int B;
+ int C;
+
+ bool operator==(const S&) const = default;
+
+ PHOENIX_DECLARE_TYPE(S, 0x81be71aa);
+};
+
+void S::RegisterMetadata(auto&& registrar)
+{
+ registrar.template Field<1, &TThis::A>("a");
+ registrar.template Field<2, &TThis::B>("b")
+ .InVersions([] (int version) {
+ return version >= 150 && version <= 250;
+ });
+ registrar.template Field<3, &TThis::C>("c")
+ .InVersions([] (int version) {
+ return version >= 100 && version <= 200;
+ })
+ .WhenMissing([] (TThis* this_, auto& /*context*/) {
+ this_->C = 777;
+ });
+}
+
+PHOENIX_DEFINE_TYPE(S);
+
+} // namespace NVersions
+
+TEST(TPhoenixTest, InVersion1)
+{
+ using namespace NInVersions;
+
+ S s1;
+ s1.A = 123;
+ s1.B = 0;
+ s1.C = 777;
+
+ auto buffer = MakeBuffer([] (auto& context) {
+ Save<int>(context, 123);
+ });
+
+ auto s2 = Deserialize<S>(buffer, /*version*/ 10);
+ EXPECT_EQ(s1, s2);
+}
+
+TEST(TPhoenixTest, InVersion2)
+{
+ using namespace NInVersions;
+
+ S s1;
+ s1.A = 123;
+ s1.B = 0;
+ s1.C = 456;
+
+ auto buffer = MakeBuffer([] (auto& context) {
+ Save<int>(context, 123);
+ Save<int>(context, 456);
+ });
+
+ auto s2 = Deserialize<S>(buffer, /*version*/ 100);
+ EXPECT_EQ(s1, s2);
+}
+
+TEST(TPhoenixTest, InVersion3)
+{
+ using namespace NInVersions;
+
+ S s1;
+ s1.A = 123;
+ s1.B = 456;
+ s1.C = 789;
+
+ auto buffer = MakeBuffer([] (auto& context) {
+ Save<int>(context, 123);
+ Save<int>(context, 456);
+ Save<int>(context, 789);
+ });
+
+ auto s2 = Deserialize<S>(buffer, /*version*/ 150);
+ EXPECT_EQ(s1, s2);
+}
+
+TEST(TPhoenixTest, InVersion4)
+{
+ using namespace NInVersions;
+
+ S s1;
+ s1.A = 123;
+ s1.B = 456;
+ s1.C = 777;
+
+ auto buffer = MakeBuffer([] (auto& context) {
+ Save<int>(context, 123);
+ Save<int>(context, 456);
+ });
+
+ auto s2 = Deserialize<S>(buffer, /*version*/ 210);
+ EXPECT_EQ(s1, s2);
+}
+
+TEST(TPhoenixTest, InVersion5)
+{
+ using namespace NInVersions;
+
+ S s1;
+ s1.A = 123;
+ s1.B = 0;
+ s1.C = 777;
+
+ auto buffer = MakeBuffer([] (auto& context) {
+ Save<int>(context, 123);
+ });
+
+ auto s2 = Deserialize<S>(buffer, /*version*/ 300);
+ EXPECT_EQ(s1, s2);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
namespace NAfterLoad {
struct S