From 0d3fcd5d16c141634c870825e57ad6c698025c9a Mon Sep 17 00:00:00 2001 From: yah01 Date: Wed, 26 Apr 2023 14:16:34 +0800 Subject: [PATCH] Add method to access nested field at once (#23720) Signed-off-by: yah01 --- internal/core/src/common/Json.h | 49 ++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/internal/core/src/common/Json.h b/internal/core/src/common/Json.h index 63211a6447..f4396f06a0 100644 --- a/internal/core/src/common/Json.h +++ b/internal/core/src/common/Json.h @@ -16,16 +16,23 @@ #pragma once +#include +#include +#include #include +#include #include +#include #include #include "exceptions/EasyAssert.h" #include "simdjson.h" #include "fmt/core.h" +#include "simdjson/dom/element.h" +#include "simdjson/error.h" namespace milvus { - +using document = simdjson::ondemand::document; class Json { public: Json() = default; @@ -73,25 +80,47 @@ class Json { data_ = data; } - auto + document doc() const { thread_local simdjson::ondemand::parser parser; // it's always safe to add the padding, // as we have allocated the memory with this padding - auto doc = - parser.iterate(data_, data_.size() + simdjson::SIMDJSON_PADDING); - return doc.get_object(); + document doc; + auto err = + parser.iterate(data_, data_.size() + simdjson::SIMDJSON_PADDING) + .get(doc); + AssertInfo(err == simdjson::SUCCESS, + fmt::format("failed to parse the json: {}", err)); + return doc; } - auto + simdjson::ondemand::value operator[](const std::string_view field) const { - return doc()[field]; + simdjson::ondemand::value result; + auto err = doc().get_value()[field].get(result); + AssertInfo( + err == simdjson::SUCCESS, + fmt::format("failed to access the field {}: {}", field, err)); + return result; } - auto - at_pointer(const std::string_view pointer) const { - return doc().at_pointer(pointer); + simdjson::ondemand::value + operator[](std::vector nested_path) const { + std::for_each( + nested_path.begin(), nested_path.end(), [](std::string& key) { + boost::replace_all(key, "~", "~0"); + boost::replace_all(key, "/", "~1"); + }); + auto pointer = boost::algorithm::join(nested_path, "/"); + simdjson::ondemand::value result; + auto err = doc().at_pointer(pointer).get(result); + AssertInfo( + err == simdjson::SUCCESS, + fmt::format("failed to access the field with json pointer {}: {}", + pointer, + err)); + return result; } std::string_view