diff --git a/ydb/library/binary_json/write.cpp b/ydb/library/binary_json/write.cpp index 88f6338797c0..36c242391c3e 100644 --- a/ydb/library/binary_json/write.cpp +++ b/ydb/library/binary_json/write.cpp @@ -1,5 +1,9 @@ #include "write.h" +#include +#include +#include +#include #include #include @@ -551,17 +555,81 @@ void DomToJsonIndex(const NUdf::TUnboxedValue& value, TBinaryJsonCallbacks& call } } +void SimdJsonToJsonIndex(const simdjson::dom::element& value, TBinaryJsonCallbacks& callbacks) { + switch (value.type()) { + case simdjson::dom::element_type::STRING: { + std::string_view v; + Y_ABORT_UNLESS(value.get(v)); + callbacks.OnString(v); + break; + } + case simdjson::dom::element_type::BOOL: { + bool v; + Y_ABORT_UNLESS(value.get(v)); + callbacks.OnBoolean(v); + break; + } + case simdjson::dom::element_type::INT64: { + i64 v; + Y_ABORT_UNLESS(value.get(v)); + callbacks.OnInteger(v); + break; + } + case simdjson::dom::element_type::UINT64: { + ui64 v; + Y_ABORT_UNLESS(value.get(v)); + callbacks.OnUInteger(v); + break; + } + case simdjson::dom::element_type::DOUBLE: { + double v; + Y_ABORT_UNLESS(value.get(v)); + callbacks.OnUInteger(v); + break; + } + case simdjson::dom::element_type::NULL_VALUE: + callbacks.OnNull(); + break; + case simdjson::dom::element_type::ARRAY: { + callbacks.OnOpenArray(); + + simdjson::dom::array v; + Y_ABORT_UNLESS(value.get(v)); + for (const auto& item : v) { + SimdJsonToJsonIndex(item, callbacks); + } + + callbacks.OnCloseArray(); + break; + } + case simdjson::dom::element_type::OBJECT: { + callbacks.OnOpenMap(); + + simdjson::dom::object v; + Y_ABORT_UNLESS(value.get(v)); + for (const auto& item : v) { + callbacks.OnMapKey(item.key); + SimdJsonToJsonIndex(item.value, callbacks); + } + + callbacks.OnCloseMap(); + break; + } + } +} + } TMaybe SerializeToBinaryJsonImpl(const TStringBuf json) { - TMemoryInput input(json.data(), json.size()); - TBinaryJsonCallbacks callbacks(/* throwException */ false); - if (!ReadJson(&input, &callbacks)) { + simdjson::dom::parser parser; + auto doc = parser.parse(json); + if (doc.error() != simdjson::SUCCESS) { return Nothing(); } + TBinaryJsonCallbacks callbacks(/* throwException */ false); + SimdJsonToJsonIndex(doc.value(), callbacks); TBinaryJsonSerializer serializer(std::move(callbacks).GetResult()); return std::move(serializer).Serialize(); - } TMaybe SerializeToBinaryJson(const TStringBuf json) { diff --git a/ydb/library/binary_json/ya.make b/ydb/library/binary_json/ya.make index 93b3032fd223..6a27bd058d2f 100644 --- a/ydb/library/binary_json/ya.make +++ b/ydb/library/binary_json/ya.make @@ -9,6 +9,7 @@ YQL_ABI_VERSION( PEERDIR( library/cpp/json ydb/library/yql/minikql/dom + contrib/libs/simdjson ) SRCS(