diff --git a/Framework/Core/include/Framework/DeviceMetricsHelper.h b/Framework/Core/include/Framework/DeviceMetricsHelper.h index 9bf7b7ea649ee..6462a5bd4f715 100644 --- a/Framework/Core/include/Framework/DeviceMetricsHelper.h +++ b/Framework/Core/include/Framework/DeviceMetricsHelper.h @@ -13,12 +13,11 @@ #define O2_FRAMEWORK_DEVICEMETRICSHELPERS_H_ #include "Framework/DeviceMetricsInfo.h" -#include "Framework/RuntimeError.h" -#include +#include #include +#include #include #include -#include #include #include @@ -26,6 +25,19 @@ namespace o2::framework { struct DriverInfo; +// General definition of what can of values can be put in a metric. +// Notice that int8_t is used for enums. +template +concept DeviceMetricValue = std::same_as || std::same_as || std::same_as || std::same_as; + +// Numeric like metrics values. +template +concept DeviceMetricNumericValue = std::same_as || std::same_as || std::same_as; + +// Enum like values +template +concept DeviceMetricEnumValue = std::same_as; + struct DeviceMetricsHelper { /// Type of the callback which can be provided to be invoked every time a new /// metric is found by the system. @@ -43,68 +55,91 @@ struct DeviceMetricsHelper { DeviceMetricsInfo& info, NewMetricCallback newMetricCallback = nullptr); /// @return the index in metrics for the information of given metric - static size_t metricIdxByName(const std::string& name, + static size_t metricIdxByName(std::string_view const name, const DeviceMetricsInfo& info); - /// Typesafe way to get the actual store - template + template T> static auto& getMetricsStore(DeviceMetricsInfo& metrics) { - if constexpr (std::is_same_v) { - return metrics.intMetrics; - } else if constexpr (std::is_same_v) { - return metrics.floatMetrics; - } else if constexpr (std::is_same_v) { - return metrics.uint64Metrics; - } else if constexpr (std::is_same_v) { - return metrics.enumMetrics; - } else { - throw runtime_error("Unhandled metric type"); - }; + return metrics.intMetrics; + } + + template T> + static auto& getMetricsStore(DeviceMetricsInfo& metrics) + { + return metrics.floatMetrics; + } + + template T> + static auto& getMetricsStore(DeviceMetricsInfo& metrics) + { + return metrics.uint64Metrics; + } + + template T> + static auto& getMetricsStore(DeviceMetricsInfo& metrics) + { + return metrics.enumMetrics; } - /// Typesafe way to get the actual store - template + template T> static auto& getTimestampsStore(DeviceMetricsInfo& metrics) { - if constexpr (std::is_same_v) { - return metrics.intTimestamps; - } else if constexpr (std::is_same_v) { - return metrics.floatTimestamps; - } else if constexpr (std::is_same_v) { - return metrics.uint64Timestamps; - } else if constexpr (std::is_same_v) { - return metrics.enumTimestamps; - } else { - throw runtime_error("Unhandled metric type"); - }; + return metrics.intTimestamps; } - template - static auto getMetricType() + template T> + static auto& getTimestampsStore(DeviceMetricsInfo& metrics) { - if constexpr (std::is_same_v) { - return MetricType::Int; - } else if constexpr (std::is_same_v) { - return MetricType::Float; - } else if constexpr (std::is_same_v) { - return MetricType::Uint64; - } else if constexpr (std::is_same_v) { - return MetricType::Enum; - } else { - throw runtime_error("Unhandled metric type"); - }; + return metrics.floatTimestamps; + } + + template T> + static auto& getTimestampsStore(DeviceMetricsInfo& metrics) + { + return metrics.uint64Timestamps; + } + + template T> + static auto& getTimestampsStore(DeviceMetricsInfo& metrics) + { + return metrics.enumTimestamps; + } + + template T> + static auto getMetricType() -> MetricType + { + return MetricType::Int; } - static auto updateNumericInfo(DeviceMetricsInfo& metrics, size_t metricIndex, float value, size_t timestamp) { - metrics.minDomain[metricIndex] = std::min(metrics.minDomain[metricIndex], timestamp); - metrics.maxDomain[metricIndex] = std::max(metrics.maxDomain[metricIndex], timestamp); - metrics.max[metricIndex] = std::max(metrics.max[metricIndex], (float)value); - metrics.min[metricIndex] = std::min(metrics.min[metricIndex], (float)value); - metrics.changed.at(metricIndex) = true; + template T> + static auto getMetricType() -> MetricType + { + return MetricType::Float; + } + + template T> + static auto getMetricType() -> MetricType + { + return MetricType::Uint64; + } + + template T> + static auto getMetricType() -> MetricType + { + return MetricType::Enum; + } + + static auto updateNumericInfo(DeviceMetricsInfo& metrics, size_t metricIndex, float value, size_t timestamp) + { + metrics.minDomain[metricIndex] = std::min(metrics.minDomain[metricIndex], timestamp); + metrics.maxDomain[metricIndex] = std::max(metrics.maxDomain[metricIndex], timestamp); + metrics.max[metricIndex] = std::max(metrics.max[metricIndex], (float)value); + metrics.min[metricIndex] = std::min(metrics.min[metricIndex], (float)value); + metrics.changed.at(metricIndex) = true; } - template + template static auto getNumericMetricCursor(size_t metricIndex) { return [metricIndex](DeviceMetricsInfo& metrics, T value, size_t timestamp) { @@ -123,13 +158,12 @@ struct DeviceMetricsHelper { static size_t bookMetricInfo(DeviceMetricsInfo& metrics, char const* name, MetricType type); /// @return helper to insert a given value in the metrics - template + template static size_t bookNumericMetric(DeviceMetricsInfo& metrics, char const* name, NewMetricCallback newMetricsCallback = nullptr) { - static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Unsupported metric type"); size_t metricIndex = bookMetricInfo(metrics, name, getMetricType()); auto& metricInfo = metrics.metrics[metricIndex]; if (newMetricsCallback != nullptr) { @@ -139,13 +173,12 @@ struct DeviceMetricsHelper { } /// @return helper to insert a given value in the metrics - template + template static std::function createNumericMetric(DeviceMetricsInfo& metrics, char const* name, NewMetricCallback newMetricsCallback = nullptr) { - static_assert(std::is_same_v || std::is_same_v || std::is_same_v, "Unsupported metric type"); size_t metricIndex = bookNumericMetric(metrics, name, newMetricsCallback); return getNumericMetricCursor(metricIndex); } diff --git a/Framework/Core/src/DeviceMetricsHelper.cxx b/Framework/Core/src/DeviceMetricsHelper.cxx index 56197a92a9f60..bf92f32fc4543 100644 --- a/Framework/Core/src/DeviceMetricsHelper.cxx +++ b/Framework/Core/src/DeviceMetricsHelper.cxx @@ -538,14 +538,14 @@ bool DeviceMetricsHelper::processMetric(ParsedMetricMatch& match, return true; } -size_t DeviceMetricsHelper::metricIdxByName(const std::string& name, const DeviceMetricsInfo& info) +size_t DeviceMetricsHelper::metricIdxByName(std::string_view const name, const DeviceMetricsInfo& info) { size_t i = 0; while (i < info.metricLabels.size()) { - auto& metricName = info.metricLabels[i]; + std::string_view metricName(info.metricLabels[i].label, info.metricLabels[i].size); // We check the size first and then the last character because that's // likely to be different for multi-index metrics - if (metricName.size == name.size() && metricName.label[metricName.size - 1] == name[metricName.size - 1] && memcmp(metricName.label, name.c_str(), metricName.size) == 0) { + if (metricName.size() == name.size() && metricName[metricName.size() - 1] == name[name.size() - 1] && metricName == name) { return i; } ++i;