aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgolear <dgolear@yandex-team.com>2025-01-21 17:15:56 +0300
committerdgolear <dgolear@yandex-team.com>2025-01-21 17:32:49 +0300
commit103573103ee8ce82c657c35d2e80e21e6c3dcf7f (patch)
treede3de184f59d3f164b561a71a7a6444444c6e9a6
parent471e5899d566a5fa8fe1f8b6c90e6d5e81f15756 (diff)
downloadydb-103573103ee8ce82c657c35d2e80e21e6c3dcf7f.tar.gz
YT: Move IYsonBuilder from ORM to core yson/ library
commit_hash:3d8bdd14cc5420209534498f0b1e61dea8e4aa1e
-rw-r--r--yt/yt/core/ya.make1
-rw-r--r--yt/yt/core/yson/unittests/ya.make1
-rw-r--r--yt/yt/core/yson/unittests/yson_builder_ut.cpp87
-rw-r--r--yt/yt/core/yson/yson_builder.cpp97
-rw-r--r--yt/yt/core/yson/yson_builder.h76
5 files changed, 262 insertions, 0 deletions
diff --git a/yt/yt/core/ya.make b/yt/yt/core/ya.make
index 857e56920b..a958bb1c6a 100644
--- a/yt/yt/core/ya.make
+++ b/yt/yt/core/ya.make
@@ -269,6 +269,7 @@ SRCS(
yson/string_merger.cpp
yson/ypath_designated_consumer.cpp
yson/ypath_filtering_consumer.cpp
+ yson/yson_builder.cpp
yson/depth_limiting_yson_consumer.cpp
yson/list_verb_lazy_yson_consumer.cpp
yson/attributes_stripper.cpp
diff --git a/yt/yt/core/yson/unittests/ya.make b/yt/yt/core/yson/unittests/ya.make
index 59a807fca4..8f8fc7dfc0 100644
--- a/yt/yt/core/yson/unittests/ya.make
+++ b/yt/yt/core/yson/unittests/ya.make
@@ -14,6 +14,7 @@ SRCS(
protobuf_yson_ut.cpp
ypath_designated_yson_consumer_ut.cpp
ypath_filtering_yson_consumer_ut.cpp
+ yson_builder_ut.cpp
yson_parser_ut.cpp
yson_pull_parser_ut.cpp
yson_token_writer_ut.cpp
diff --git a/yt/yt/core/yson/unittests/yson_builder_ut.cpp b/yt/yt/core/yson/unittests/yson_builder_ut.cpp
new file mode 100644
index 0000000000..c3353a56de
--- /dev/null
+++ b/yt/yt/core/yson/unittests/yson_builder_ut.cpp
@@ -0,0 +1,87 @@
+#include <yt/yt/core/yson/consumer.h>
+#include <yt/yt/core/yson/string.h>
+#include <yt/yt/core/yson/yson_builder.h>
+
+#include <yt/yt/core/test_framework/framework.h>
+
+namespace NYT::NYson {
+namespace {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TYsonStringBuilderTest, Simple)
+{
+ NYson::TYsonStringBuilder builder;
+ builder->OnStringScalar("some_scalar");
+ ASSERT_EQ(builder.Flush().ToString(), TString{"\1\x16some_scalar"});
+ ASSERT_TRUE(builder.IsEmpty());
+}
+
+TEST(TYsonStringBuilderTest, Reusing)
+{
+ NYson::TYsonStringBuilder builder;
+ builder->OnStringScalar("some_scalar1");
+ ASSERT_EQ(builder.Flush().ToString(), TString{"\1\x18some_scalar1"});
+ ASSERT_TRUE(builder.IsEmpty());
+
+ builder->OnStringScalar("some_scalar2");
+ ASSERT_EQ(builder.Flush().ToString(), TString{"\1\x18some_scalar2"});
+ ASSERT_TRUE(builder.IsEmpty());
+}
+
+TEST(TYsonStringBuilderTest, Checkpoints)
+{
+ NYson::TYsonStringBuilder builder;
+ builder->OnStringScalar("some_scalar");
+
+ auto checkpoint = builder.CreateCheckpoint();
+ builder.CreateCheckpoint();
+ builder.RestoreCheckpoint(checkpoint);
+ builder.RestoreCheckpoint(checkpoint);
+
+ ASSERT_EQ(builder.Flush().ToString(), TString{"\1\x16some_scalar"});
+ ASSERT_TRUE(builder.IsEmpty());
+}
+
+TEST(TYsonStringBuilderTest, MapCheckpoints)
+{
+ NYson::TYsonStringBuilder builder(NYson::EYsonFormat::Text);
+
+ builder->OnBeginMap();
+
+ builder->OnKeyedItem("key1");
+ builder->OnEntity();
+
+ auto checkpoint = builder.CreateCheckpoint();
+ builder->OnKeyedItem("key2");
+ builder->OnEntity();
+ builder.RestoreCheckpoint(checkpoint);
+
+ builder->OnEndMap();
+
+ ASSERT_EQ(builder.Flush().ToString(), TString{R"({"key1"=#;})"});
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TEST(TYsonBuilderTest, Forwarding)
+{
+ NYson::TYsonStringBuilder stringBuilder(NYson::EYsonFormat::Text);
+ NYson::TYsonBuilder builder(
+ NYson::EYsonBuilderForwardingPolicy::Forward,
+ &stringBuilder,
+ stringBuilder.GetConsumer());
+ builder->OnBeginMap();
+ auto checkpoint = builder.CreateCheckpoint();
+ builder->OnKeyedItem("key");
+ builder->OnEntity();
+ builder.RestoreCheckpoint(checkpoint);
+ builder->OnEndMap();
+
+ ASSERT_EQ(stringBuilder.Flush().ToString(), TString{R"({})"});
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace
+} // namespace NYT::NYson
diff --git a/yt/yt/core/yson/yson_builder.cpp b/yt/yt/core/yson/yson_builder.cpp
new file mode 100644
index 0000000000..a17b9b8772
--- /dev/null
+++ b/yt/yt/core/yson/yson_builder.cpp
@@ -0,0 +1,97 @@
+#include "yson_builder.h"
+
+#include "writer.h"
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+IYsonConsumer* IYsonBuilder::operator->()
+{
+ return GetConsumer();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TYsonStringBuilder::TYsonStringBuilder(EYsonFormat format, EYsonType type, bool enableRaw)
+ : Output_(ValueString_)
+ , Writer_(CreateYsonWriter(&Output_, format, type, enableRaw))
+{ }
+
+IYsonConsumer* TYsonStringBuilder::GetConsumer()
+{
+ return Writer_.get();
+}
+
+IYsonBuilder::TCheckpoint TYsonStringBuilder::CreateCheckpoint()
+{
+ Writer_->Flush();
+ return IYsonBuilder::TCheckpoint(std::ssize(ValueString_));
+}
+
+void TYsonStringBuilder::RestoreCheckpoint(IYsonBuilder::TCheckpoint checkpoint)
+{
+ Writer_->Flush();
+ int checkpointSize = checkpoint.Underlying();
+ YT_VERIFY(checkpointSize >= 0 && checkpointSize <= std::ssize(ValueString_));
+ ValueString_.resize(static_cast<size_t>(checkpointSize));
+}
+
+TYsonString TYsonStringBuilder::Flush()
+{
+ Writer_->Flush();
+ auto result = TYsonString(ValueString_);
+ ValueString_.clear();
+ return result;
+}
+
+bool TYsonStringBuilder::IsEmpty()
+{
+ Writer_->Flush();
+ return ValueString_.empty();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TYsonBuilder::TYsonBuilder(
+ EYsonBuilderForwardingPolicy policy,
+ IYsonBuilder* underlying,
+ IYsonConsumer* consumer)
+ : Policy_(policy)
+ , Underlying_(underlying)
+ , Consumer_(consumer)
+{ }
+
+IYsonConsumer* TYsonBuilder::GetConsumer()
+{
+ return Consumer_;
+}
+
+IYsonBuilder::TCheckpoint TYsonBuilder::CreateCheckpoint()
+{
+ switch (Policy_) {
+ case EYsonBuilderForwardingPolicy::Forward:
+ return Underlying_->CreateCheckpoint();
+ case EYsonBuilderForwardingPolicy::Crash:
+ return IYsonBuilder::TCheckpoint{};
+ case EYsonBuilderForwardingPolicy::Ignore:
+ return IYsonBuilder::TCheckpoint{};
+ }
+}
+
+void TYsonBuilder::RestoreCheckpoint(TCheckpoint checkpoint)
+{
+ switch (Policy_) {
+ case EYsonBuilderForwardingPolicy::Forward:
+ Underlying_->RestoreCheckpoint(checkpoint);
+ break;
+ case EYsonBuilderForwardingPolicy::Crash:
+ YT_ABORT();
+ case EYsonBuilderForwardingPolicy::Ignore:
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson
diff --git a/yt/yt/core/yson/yson_builder.h b/yt/yt/core/yson/yson_builder.h
new file mode 100644
index 0000000000..5f483124e8
--- /dev/null
+++ b/yt/yt/core/yson/yson_builder.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include "public.h"
+
+#include <library/cpp/yt/misc/strong_typedef.h>
+
+namespace NYT::NYson {
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct IYsonBuilder
+{
+ YT_DEFINE_STRONG_TYPEDEF(TCheckpoint, int);
+
+ virtual ~IYsonBuilder() = default;
+
+ virtual IYsonConsumer* GetConsumer() = 0;
+ virtual TCheckpoint CreateCheckpoint() = 0;
+ virtual void RestoreCheckpoint(TCheckpoint checkpoint) = 0;
+
+ IYsonConsumer* operator->();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TYsonStringBuilder
+ : public IYsonBuilder
+{
+public:
+ TYsonStringBuilder(
+ NYson::EYsonFormat format = NYson::EYsonFormat::Binary,
+ NYson::EYsonType type = NYson::EYsonType::Node,
+ bool enableRaw = true);
+
+ NYson::IYsonConsumer* GetConsumer() override;
+ IYsonBuilder::TCheckpoint CreateCheckpoint() override;
+ void RestoreCheckpoint(IYsonBuilder::TCheckpoint checkpoint) override;
+
+ NYson::TYsonString Flush();
+ bool IsEmpty();
+
+private:
+ TString ValueString_;
+ TStringOutput Output_;
+ const std::unique_ptr<NYson::IFlushableYsonConsumer> Writer_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_ENUM(EYsonBuilderForwardingPolicy,
+ (Forward)
+ (Ignore)
+ (Crash)
+);
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TYsonBuilder
+ : public IYsonBuilder
+{
+public:
+ TYsonBuilder(EYsonBuilderForwardingPolicy policy, IYsonBuilder* underlying, IYsonConsumer* consumer);
+
+ IYsonConsumer* GetConsumer() override;
+ IYsonBuilder::TCheckpoint CreateCheckpoint() override;
+ void RestoreCheckpoint(TCheckpoint checkpoint) override;
+
+private:
+ const EYsonBuilderForwardingPolicy Policy_;
+ IYsonBuilder* const Underlying_;
+ NYson::IYsonConsumer* const Consumer_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NYson