Skip to content

Commit b8d9dbd

Browse files
author
h0pless
committed
Sort all YSONStruct fields before saving, including unrecognized keys
commit_hash:4e04b10da96e7f9e6f201f51eb8f3ed249985d10
1 parent e41017e commit b8d9dbd

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

yt/yt/core/ytree/yson_struct.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,59 @@ void TYsonStructBase::Save(IYsonConsumer* consumer) const
9191
consumer->OnEndMap();
9292
}
9393

94-
void TYsonStructBase::SaveAsMapFragment(NYson::IYsonConsumer* consumer) const
94+
void TYsonStructBase::SaveRecognizedAsMapFragment(NYson::IYsonConsumer* consumer) const
9595
{
9696
for (const auto& [name, parameter] : Meta_->GetParameterSortedList()) {
9797
if (!parameter->CanOmitValue(this)) {
9898
consumer->OnKeyedItem(name);
9999
parameter->Save(this, consumer);
100100
}
101101
}
102+
}
103+
104+
void TYsonStructBase::SaveAsMapFragment(NYson::IYsonConsumer* consumer) const
105+
{
106+
if (!LocalUnrecognized_) {
107+
// Fast path.
108+
return SaveRecognizedAsMapFragment(consumer);
109+
}
110+
111+
const auto& recognizedList = Meta_->GetParameterSortedList();
112+
auto recognizedIt = recognizedList.begin();
113+
114+
auto unrecognizedList = LocalUnrecognized_->GetChildren();
115+
SortBy(unrecognizedList, [] (const auto& item) { return item.first; });
116+
auto unrecognizedIt = unrecognizedList.begin();
102117

103-
if (LocalUnrecognized_) {
104-
auto unrecognizedList = LocalUnrecognized_->GetChildren();
105-
SortBy(unrecognizedList, [] (const auto& item) { return item.first; });
106-
for (const auto& [key, child] : unrecognizedList) {
107-
consumer->OnKeyedItem(key);
108-
Serialize(child, consumer);
118+
auto saveRecognized = [&recognizedIt, this] (auto* consumer) {
119+
const auto& parameter = recognizedIt->second;
120+
if (!parameter->CanOmitValue(this)) {
121+
consumer->OnKeyedItem(recognizedIt->first);
122+
parameter->Save(this, consumer);
109123
}
124+
++recognizedIt;
125+
};
126+
127+
auto saveUnrecognized = [&unrecognizedIt] (auto* consumer) {
128+
consumer->OnKeyedItem(unrecognizedIt->first);
129+
Serialize(unrecognizedIt->second, consumer);
130+
++unrecognizedIt;
131+
};
132+
133+
while (recognizedIt != recognizedList.end() && unrecognizedIt != unrecognizedList.end()) {
134+
if (recognizedIt->first < unrecognizedIt->first) {
135+
saveRecognized(consumer);
136+
} else {
137+
saveUnrecognized(consumer);
138+
}
139+
}
140+
141+
while (recognizedIt != recognizedList.end()) {
142+
saveRecognized(consumer);
143+
}
144+
145+
while (unrecognizedIt != unrecognizedList.end()) {
146+
saveUnrecognized(consumer);
110147
}
111148
}
112149

yt/yt/core/ytree/yson_struct.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class TYsonStructBase
9090
// of the |Load| call.
9191
void SaveAsMapFragment(NYson::IYsonConsumer* consumer) const;
9292

93+
// Same as the above, but does not save local unrecognized parameters.
94+
void SaveRecognizedAsMapFragment(NYson::IYsonConsumer* consumer) const;
95+
9396
void Save(IOutputStream* output) const;
9497

9598
IMapNodePtr GetLocalUnrecognized() const;

0 commit comments

Comments
 (0)