From 5784c0d473f364f5860a1a8df60098ed43f3ddc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20Benjamin=20Antal?= <benjamin.antal@memgraph.io> Date: Tue, 25 Oct 2022 15:26:42 +0200 Subject: [PATCH] Return the custom data for profile queries --- src/query/v2/interpreter.cpp | 2 +- src/query/v2/plan/profile.cpp | 65 ++++++++++++++++++++++++----------- src/query/v2/plan/profile.hpp | 2 ++ 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/query/v2/interpreter.cpp b/src/query/v2/interpreter.cpp index 0fd11fdde..f82d5ee01 100644 --- a/src/query/v2/interpreter.cpp +++ b/src/query/v2/interpreter.cpp @@ -1040,7 +1040,7 @@ PreparedQuery PrepareProfileQuery(ParsedQuery parsed_query, bool in_explicit_tra auto rw_type_checker = plan::ReadWriteTypeChecker(); rw_type_checker.InferRWType(const_cast<plan::LogicalOperator &>(cypher_query_plan->plan())); - return PreparedQuery{{"OPERATOR", "ACTUAL HITS", "RELATIVE TIME", "ABSOLUTE TIME"}, + return PreparedQuery{{"OPERATOR", "ACTUAL HITS", "RELATIVE TIME", "ABSOLUTE TIME", "CUSTOM DATA"}, std::move(parsed_query.required_privileges), [plan = std::move(cypher_query_plan), parameters = std::move(parsed_inner_query.parameters), summary, dba, interpreter_context, execution_memory, memory_limit, shard_request_manager, diff --git a/src/query/v2/plan/profile.cpp b/src/query/v2/plan/profile.cpp index 26c5280d4..3bd0953ba 100644 --- a/src/query/v2/plan/profile.cpp +++ b/src/query/v2/plan/profile.cpp @@ -24,18 +24,17 @@ namespace memgraph::query::v2::plan { namespace { -unsigned long long IndividualCycles(const ProfilingStats &cumulative_stats) { +uint64_t IndividualCycles(const ProfilingStats &cumulative_stats) { return cumulative_stats.num_cycles - std::accumulate(cumulative_stats.children.begin(), cumulative_stats.children.end(), 0ULL, [](auto acc, auto &stats) { return acc + stats.num_cycles; }); } -double RelativeTime(unsigned long long num_cycles, unsigned long long total_cycles) { - return static_cast<double>(num_cycles) / total_cycles; +double RelativeTime(uint64_t num_cycles, uint64_t total_cycles) { + return static_cast<double>(num_cycles) / static_cast<double>(total_cycles); } -double AbsoluteTime(unsigned long long num_cycles, unsigned long long total_cycles, - std::chrono::duration<double> total_time) { +double AbsoluteTime(uint64_t num_cycles, uint64_t total_cycles, std::chrono::duration<double> total_time) { return (RelativeTime(num_cycles, total_cycles) * static_cast<std::chrono::duration<double, std::milli>>(total_time)) .count(); } @@ -50,26 +49,29 @@ namespace { class ProfilingStatsToTableHelper { public: - ProfilingStatsToTableHelper(unsigned long long total_cycles, std::chrono::duration<double> total_time) + ProfilingStatsToTableHelper(uint64_t total_cycles, std::chrono::duration<double> total_time) : total_cycles_(total_cycles), total_time_(total_time) {} void Output(const ProfilingStats &cumulative_stats) { auto cycles = IndividualCycles(cumulative_stats); + auto custom_data_copy = cumulative_stats.custom_data; + ConvertCyclesToTime(custom_data_copy); - rows_.emplace_back(std::vector<TypedValue>{ - TypedValue(FormatOperator(cumulative_stats.name)), TypedValue(cumulative_stats.actual_hits), - TypedValue(FormatRelativeTime(cycles)), TypedValue(FormatAbsoluteTime(cycles))}); + rows_.emplace_back( + std::vector<TypedValue>{TypedValue(FormatOperator(cumulative_stats.name)), + TypedValue(cumulative_stats.actual_hits), TypedValue(FormatRelativeTime(cycles)), + TypedValue(FormatAbsoluteTime(cycles)), TypedValue(custom_data_copy.dump())}); for (size_t i = 1; i < cumulative_stats.children.size(); ++i) { Branch(cumulative_stats.children[i]); } - if (cumulative_stats.children.size() >= 1) { + if (!cumulative_stats.children.empty()) { Output(cumulative_stats.children[0]); } } - std::vector<std::vector<TypedValue>> rows() { return rows_; } + std::vector<std::vector<TypedValue>> rows() const { return rows_; } private: void Branch(const ProfilingStats &cumulative_stats) { @@ -80,7 +82,28 @@ class ProfilingStatsToTableHelper { --depth_; } - std::string Format(const char *str) { + double AbsoluteTime(const uint64_t cycles) const { return plan::AbsoluteTime(cycles, total_cycles_, total_time_); } + + double RelativeTime(const uint64_t cycles) const { return plan::RelativeTime(cycles, total_cycles_); } + + void ConvertCyclesToTime(nlohmann::json &custom_data) const { + const auto convert_cycles_in_json = [this](nlohmann::json &json) { + if (!json.is_object()) { + return; + } + if (auto it = json.find(ProfilingStats::kNumCycles); it != json.end()) { + auto num_cycles = it.value().get<uint64_t>(); + json[ProfilingStats::kAbsoluteTime] = AbsoluteTime(num_cycles); + json[ProfilingStats::kRelativeTime] = RelativeTime(num_cycles); + } + }; + + for (auto &json : custom_data) { + convert_cycles_in_json(json); + } + } + + std::string Format(const char *str) const { std::ostringstream ss; for (int64_t i = 0; i < depth_; ++i) { ss << "| "; @@ -89,21 +112,21 @@ class ProfilingStatsToTableHelper { return ss.str(); } - std::string Format(const std::string &str) { return Format(str.c_str()); } + std::string Format(const std::string &str) const { return Format(str.c_str()); } - std::string FormatOperator(const char *str) { return Format(std::string("* ") + str); } + std::string FormatOperator(const char *str) const { return Format(std::string("* ") + str); } - std::string FormatRelativeTime(unsigned long long num_cycles) { - return fmt::format("{: 10.6f} %", RelativeTime(num_cycles, total_cycles_) * 100); + std::string FormatRelativeTime(uint64_t num_cycles) const { + return fmt::format("{: 10.6f} %", RelativeTime(num_cycles) * 100); } - std::string FormatAbsoluteTime(unsigned long long num_cycles) { - return fmt::format("{: 10.6f} ms", AbsoluteTime(num_cycles, total_cycles_, total_time_)); + std::string FormatAbsoluteTime(uint64_t num_cycles) const { + return fmt::format("{: 10.6f} ms", AbsoluteTime(num_cycles)); } int64_t depth_{0}; std::vector<std::vector<TypedValue>> rows_; - unsigned long long total_cycles_; + uint64_t total_cycles_; std::chrono::duration<double> total_time_; }; @@ -126,7 +149,7 @@ class ProfilingStatsToJsonHelper { using json = nlohmann::json; public: - ProfilingStatsToJsonHelper(unsigned long long total_cycles, std::chrono::duration<double> total_time) + ProfilingStatsToJsonHelper(uint64_t total_cycles, std::chrono::duration<double> total_time) : total_cycles_(total_cycles), total_time_(total_time) {} void Output(const ProfilingStats &cumulative_stats) { return Output(cumulative_stats, &json_); } @@ -151,7 +174,7 @@ class ProfilingStatsToJsonHelper { } json json_; - unsigned long long total_cycles_; + uint64_t total_cycles_; std::chrono::duration<double> total_time_; }; diff --git a/src/query/v2/plan/profile.hpp b/src/query/v2/plan/profile.hpp index c18ae1e56..da25be33c 100644 --- a/src/query/v2/plan/profile.hpp +++ b/src/query/v2/plan/profile.hpp @@ -27,6 +27,8 @@ namespace plan { */ struct ProfilingStats { static constexpr std::string_view kNumCycles{"num_cycles"}; + static constexpr std::string_view kRelativeTime{"relative_time"}; + static constexpr std::string_view kAbsoluteTime{"absolute_time"}; int64_t actual_hits{0}; uint64_t num_cycles{0};