diff options
author | Sergey Polovko <sergey@polovko.me> | 2022-02-10 16:47:02 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:02 +0300 |
commit | 3e0b762a82514bac89c1dd6ea7211e381d8aa248 (patch) | |
tree | c2d1b379ecaf05ca8f11ed0b5da9d1a950e6e554 /library/cpp/monlib/metrics/metric_value.h | |
parent | ab3783171cc30e262243a0227c86118f7080c896 (diff) | |
download | ydb-3e0b762a82514bac89c1dd6ea7211e381d8aa248.tar.gz |
Restoring authorship annotation for Sergey Polovko <sergey@polovko.me>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/monlib/metrics/metric_value.h')
-rw-r--r-- | library/cpp/monlib/metrics/metric_value.h | 586 |
1 files changed, 293 insertions, 293 deletions
diff --git a/library/cpp/monlib/metrics/metric_value.h b/library/cpp/monlib/metrics/metric_value.h index 607fcc8602..d7b2f6a680 100644 --- a/library/cpp/monlib/metrics/metric_value.h +++ b/library/cpp/monlib/metrics/metric_value.h @@ -1,17 +1,17 @@ -#pragma once - -#include "histogram_collector.h" -#include "metric_value_type.h" +#pragma once + +#include "histogram_collector.h" +#include "metric_value_type.h" #include "summary_collector.h" #include "log_histogram_snapshot.h" - -#include <util/datetime/base.h> -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> + +#include <util/datetime/base.h> +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> #include <util/generic/cast.h> #include <util/generic/ymath.h> - -namespace NMonitoring { + +namespace NMonitoring { namespace NPrivate { template <typename T> T FromFloatSafe(double d) { @@ -25,71 +25,71 @@ namespace NMonitoring { }; } // namespace NPrivate - template <typename T, typename Enable = void> - struct TValueType; - - template <> - struct TValueType<double> { - static constexpr auto Type = EMetricValueType::DOUBLE; - }; - - template <> - struct TValueType<i64> { - static constexpr auto Type = EMetricValueType::INT64; - }; - - template <> - struct TValueType<ui64> { - static constexpr auto Type = EMetricValueType::UINT64; - }; - + template <typename T, typename Enable = void> + struct TValueType; + + template <> + struct TValueType<double> { + static constexpr auto Type = EMetricValueType::DOUBLE; + }; + + template <> + struct TValueType<i64> { + static constexpr auto Type = EMetricValueType::INT64; + }; + + template <> + struct TValueType<ui64> { + static constexpr auto Type = EMetricValueType::UINT64; + }; + template <> struct TValueType<TLogHistogramSnapshot*> { static constexpr auto Type = EMetricValueType::LOGHISTOGRAM; }; - template <typename T> - struct TValueType<T*, typename std::enable_if_t<std::is_base_of<IHistogramSnapshot, T>::value>> { - static constexpr auto Type = EMetricValueType::HISTOGRAM; - }; - + template <typename T> + struct TValueType<T*, typename std::enable_if_t<std::is_base_of<IHistogramSnapshot, T>::value>> { + static constexpr auto Type = EMetricValueType::HISTOGRAM; + }; + template <typename T> struct TValueType<T*, typename std::enable_if_t<std::is_base_of<ISummaryDoubleSnapshot, T>::value>> { - static constexpr auto Type = EMetricValueType::SUMMARY; + static constexpr auto Type = EMetricValueType::SUMMARY; }; - - /////////////////////////////////////////////////////////////////////////// - // TMetricValue - /////////////////////////////////////////////////////////////////////////// - // TMetricValue represents a generic value. It does not contain type + + /////////////////////////////////////////////////////////////////////////// + // TMetricValue + /////////////////////////////////////////////////////////////////////////// + // TMetricValue represents a generic value. It does not contain type // information about a value. This is done to minimize object footprint. // To read an actual value from the object the type must be checked // first or provided to AsXxxx(type) member-functions. // This class does not hold an ownership of an IHistogramSnapshot or // SummarySnapshot, so this must be done somewhere outside. - class TMetricValue { - public: - TMetricValue() noexcept { - Value_.Uint64 = 0; - } - - explicit TMetricValue(double value) noexcept { - Value_.Double = value; - } - - explicit TMetricValue(i64 value) noexcept { - Value_.Int64 = value; - } - - explicit TMetricValue(ui64 value) noexcept { - Value_.Uint64 = value; - } - - explicit TMetricValue(IHistogramSnapshot* histogram) noexcept { - Value_.Histogram = histogram; - } - - explicit TMetricValue(ISummaryDoubleSnapshot* summary) noexcept { + class TMetricValue { + public: + TMetricValue() noexcept { + Value_.Uint64 = 0; + } + + explicit TMetricValue(double value) noexcept { + Value_.Double = value; + } + + explicit TMetricValue(i64 value) noexcept { + Value_.Int64 = value; + } + + explicit TMetricValue(ui64 value) noexcept { + Value_.Uint64 = value; + } + + explicit TMetricValue(IHistogramSnapshot* histogram) noexcept { + Value_.Histogram = histogram; + } + + explicit TMetricValue(ISummaryDoubleSnapshot* summary) noexcept { Value_.Summary = summary; } @@ -97,90 +97,90 @@ namespace NMonitoring { Value_.LogHistogram = logHist; } - double AsDouble() const noexcept { - return Value_.Double; - } - - // will cast value into double, current value type is determined by - // the given type argument - double AsDouble(EMetricValueType type) const { - switch (type) { - case EMetricValueType::DOUBLE: - return Value_.Double; - case EMetricValueType::INT64: - return static_cast<double>(Value_.Int64); - case EMetricValueType::UINT64: - return static_cast<double>(Value_.Uint64); - case EMetricValueType::HISTOGRAM: - ythrow yexception() << "histogram cannot be casted to Double"; - case EMetricValueType::SUMMARY: + double AsDouble() const noexcept { + return Value_.Double; + } + + // will cast value into double, current value type is determined by + // the given type argument + double AsDouble(EMetricValueType type) const { + switch (type) { + case EMetricValueType::DOUBLE: + return Value_.Double; + case EMetricValueType::INT64: + return static_cast<double>(Value_.Int64); + case EMetricValueType::UINT64: + return static_cast<double>(Value_.Uint64); + case EMetricValueType::HISTOGRAM: + ythrow yexception() << "histogram cannot be casted to Double"; + case EMetricValueType::SUMMARY: ythrow yexception() << "summary cannot be casted to Double"; case EMetricValueType::LOGHISTOGRAM: ythrow yexception() << "loghistogram cannot be casted to Double"; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown value type"; - } - Y_FAIL(); // for GCC - } - - ui64 AsUint64() const noexcept { - return Value_.Uint64; - } - - // will cast value into uint64, current value's type is determined by - // the given type argument - ui64 AsUint64(EMetricValueType type) const { - switch (type) { - case EMetricValueType::DOUBLE: + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown value type"; + } + Y_FAIL(); // for GCC + } + + ui64 AsUint64() const noexcept { + return Value_.Uint64; + } + + // will cast value into uint64, current value's type is determined by + // the given type argument + ui64 AsUint64(EMetricValueType type) const { + switch (type) { + case EMetricValueType::DOUBLE: return NPrivate::FromFloatSafe<ui64>(Value_.Double); - case EMetricValueType::INT64: + case EMetricValueType::INT64: return SafeIntegerCast<ui64>(Value_.Int64); - case EMetricValueType::UINT64: - return Value_.Uint64; - case EMetricValueType::HISTOGRAM: - ythrow yexception() << "histogram cannot be casted to Uint64"; - case EMetricValueType::SUMMARY: + case EMetricValueType::UINT64: + return Value_.Uint64; + case EMetricValueType::HISTOGRAM: + ythrow yexception() << "histogram cannot be casted to Uint64"; + case EMetricValueType::SUMMARY: ythrow yexception() << "summary cannot be casted to Uint64"; case EMetricValueType::LOGHISTOGRAM: ythrow yexception() << "loghistogram cannot be casted to Uint64"; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown value type"; - } - Y_FAIL(); // for GCC - } - - i64 AsInt64() const noexcept { - return Value_.Int64; - } - - // will cast value into int64, current value's type is determined by - // the given type argument - i64 AsInt64(EMetricValueType type) const { - switch (type) { - case EMetricValueType::DOUBLE: + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown value type"; + } + Y_FAIL(); // for GCC + } + + i64 AsInt64() const noexcept { + return Value_.Int64; + } + + // will cast value into int64, current value's type is determined by + // the given type argument + i64 AsInt64(EMetricValueType type) const { + switch (type) { + case EMetricValueType::DOUBLE: return NPrivate::FromFloatSafe<i64>(Value_.Double); - case EMetricValueType::INT64: - return Value_.Int64; - case EMetricValueType::UINT64: + case EMetricValueType::INT64: + return Value_.Int64; + case EMetricValueType::UINT64: return SafeIntegerCast<i64>(Value_.Uint64); - case EMetricValueType::HISTOGRAM: - ythrow yexception() << "histogram cannot be casted to Int64"; - case EMetricValueType::SUMMARY: + case EMetricValueType::HISTOGRAM: + ythrow yexception() << "histogram cannot be casted to Int64"; + case EMetricValueType::SUMMARY: ythrow yexception() << "summary cannot be casted to Int64"; case EMetricValueType::LOGHISTOGRAM: ythrow yexception() << "loghistogram cannot be casted to Int64"; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown value type"; - } - Y_FAIL(); // for GCC - } - - IHistogramSnapshot* AsHistogram() const noexcept { - return Value_.Histogram; - } - - IHistogramSnapshot* AsHistogram(EMetricValueType type) const { - if (type != EMetricValueType::HISTOGRAM) { + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown value type"; + } + Y_FAIL(); // for GCC + } + + IHistogramSnapshot* AsHistogram() const noexcept { + return Value_.Histogram; + } + + IHistogramSnapshot* AsHistogram(EMetricValueType type) const { + if (type != EMetricValueType::HISTOGRAM) { ythrow yexception() << type << " cannot be casted to Histogram"; } @@ -191,8 +191,8 @@ namespace NMonitoring { return Value_.Summary; } - ISummaryDoubleSnapshot* AsSummaryDouble(EMetricValueType type) const { - if (type != EMetricValueType::SUMMARY) { + ISummaryDoubleSnapshot* AsSummaryDouble(EMetricValueType type) const { + if (type != EMetricValueType::SUMMARY) { ythrow yexception() << type << " cannot be casted to SummaryDouble"; } @@ -211,35 +211,35 @@ namespace NMonitoring { return Value_.LogHistogram; } - protected: - union { - double Double; - i64 Int64; - ui64 Uint64; - IHistogramSnapshot* Histogram; + protected: + union { + double Double; + i64 Int64; + ui64 Uint64; + IHistogramSnapshot* Histogram; ISummaryDoubleSnapshot* Summary; TLogHistogramSnapshot* LogHistogram; - } Value_; - }; - + } Value_; + }; + /////////////////////////////////////////////////////////////////////////// - // TMetricValueWithType + // TMetricValueWithType /////////////////////////////////////////////////////////////////////////// - // Same as TMetricValue, but this type holds an ownership of + // Same as TMetricValue, but this type holds an ownership of // snapshots and contains value type information. - class TMetricValueWithType: private TMetricValue, public TMoveOnly { + class TMetricValueWithType: private TMetricValue, public TMoveOnly { public: - using TBase = TMetricValue; + using TBase = TMetricValue; template <typename T> - explicit TMetricValueWithType(T value) + explicit TMetricValueWithType(T value) : TBase(value) , ValueType_{TValueType<T>::Type} { Ref(); } - TMetricValueWithType(TMetricValueWithType&& other) + TMetricValueWithType(TMetricValueWithType&& other) : TBase(std::move(other)) , ValueType_{other.ValueType_} { @@ -247,7 +247,7 @@ namespace NMonitoring { other.Clear(); } - TMetricValueWithType& operator=(TMetricValueWithType&& other) { + TMetricValueWithType& operator=(TMetricValueWithType&& other) { TBase::operator=(other); ValueType_ = other.ValueType_; @@ -257,16 +257,16 @@ namespace NMonitoring { return *this; } - ~TMetricValueWithType() { + ~TMetricValueWithType() { UnRef(); } void Clear() { UnRef(); - ValueType_ = EMetricValueType::UNKNOWN; + ValueType_ = EMetricValueType::UNKNOWN; } - EMetricValueType GetType() const noexcept { + EMetricValueType GetType() const noexcept { return ValueType_; } @@ -296,9 +296,9 @@ namespace NMonitoring { private: void Ref() { - if (ValueType_ == EMetricValueType::SUMMARY) { + if (ValueType_ == EMetricValueType::SUMMARY) { TBase::AsSummaryDouble()->Ref(); - } else if (ValueType_ == EMetricValueType::HISTOGRAM) { + } else if (ValueType_ == EMetricValueType::HISTOGRAM) { TBase::AsHistogram()->Ref(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { TBase::AsLogHistogram()->Ref(); @@ -306,9 +306,9 @@ namespace NMonitoring { } void UnRef() { - if (ValueType_ == EMetricValueType::SUMMARY) { + if (ValueType_ == EMetricValueType::SUMMARY) { TBase::AsSummaryDouble()->UnRef(); - } else if (ValueType_ == EMetricValueType::HISTOGRAM) { + } else if (ValueType_ == EMetricValueType::HISTOGRAM) { TBase::AsHistogram()->UnRef(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { TBase::AsLogHistogram()->UnRef(); @@ -316,114 +316,114 @@ namespace NMonitoring { } private: - EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; + EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; }; - static_assert(sizeof(TMetricValue) == sizeof(ui64), - "expected size of TMetricValue is one machine word"); - - /////////////////////////////////////////////////////////////////////////// - // TMetricTimeSeries - /////////////////////////////////////////////////////////////////////////// - class TMetricTimeSeries: private TMoveOnly { - public: - class TPoint { - public: - TPoint() - : Time_(TInstant::Zero()) - { - } - - template <typename T> - TPoint(TInstant time, T value) - : Time_(time) - , Value_(value) - { - } - - TInstant GetTime() const noexcept { - return Time_; - } - - TMetricValue GetValue() const noexcept { - return Value_; - } - - void ClearValue() { - Value_ = {}; - } - - private: - TInstant Time_; - TMetricValue Value_; - }; - - public: - TMetricTimeSeries() = default; - - TMetricTimeSeries(TMetricTimeSeries&& rhs) noexcept - : ValueType_(rhs.ValueType_) - , Points_(std::move(rhs.Points_)) - { - rhs.ValueType_ = EMetricValueType::UNKNOWN; - } - - TMetricTimeSeries& operator=(TMetricTimeSeries&& rhs) noexcept { - Clear(); - - ValueType_ = rhs.ValueType_; - rhs.ValueType_ = EMetricValueType::UNKNOWN; - - Points_ = std::move(rhs.Points_); - return *this; - } - - ~TMetricTimeSeries() { - Clear(); - } - - template <typename T> - void Add(TInstant time, T value) { + static_assert(sizeof(TMetricValue) == sizeof(ui64), + "expected size of TMetricValue is one machine word"); + + /////////////////////////////////////////////////////////////////////////// + // TMetricTimeSeries + /////////////////////////////////////////////////////////////////////////// + class TMetricTimeSeries: private TMoveOnly { + public: + class TPoint { + public: + TPoint() + : Time_(TInstant::Zero()) + { + } + + template <typename T> + TPoint(TInstant time, T value) + : Time_(time) + , Value_(value) + { + } + + TInstant GetTime() const noexcept { + return Time_; + } + + TMetricValue GetValue() const noexcept { + return Value_; + } + + void ClearValue() { + Value_ = {}; + } + + private: + TInstant Time_; + TMetricValue Value_; + }; + + public: + TMetricTimeSeries() = default; + + TMetricTimeSeries(TMetricTimeSeries&& rhs) noexcept + : ValueType_(rhs.ValueType_) + , Points_(std::move(rhs.Points_)) + { + rhs.ValueType_ = EMetricValueType::UNKNOWN; + } + + TMetricTimeSeries& operator=(TMetricTimeSeries&& rhs) noexcept { + Clear(); + + ValueType_ = rhs.ValueType_; + rhs.ValueType_ = EMetricValueType::UNKNOWN; + + Points_ = std::move(rhs.Points_); + return *this; + } + + ~TMetricTimeSeries() { + Clear(); + } + + template <typename T> + void Add(TInstant time, T value) { Add(TPoint(time, value), TValueType<T>::Type); } void Add(TPoint point, EMetricValueType valueType) { - if (Empty()) { + if (Empty()) { ValueType_ = valueType; - } else { + } else { CheckTypes(ValueType_, valueType); - } + } Points_.push_back(point); - - if (ValueType_ == EMetricValueType::SUMMARY) { + + if (ValueType_ == EMetricValueType::SUMMARY) { TPoint& p = Points_.back(); p.GetValue().AsSummaryDouble()->Ref(); - } else if (ValueType_ == EMetricValueType::HISTOGRAM) { + } else if (ValueType_ == EMetricValueType::HISTOGRAM) { TPoint& p = Points_.back(); p.GetValue().AsHistogram()->Ref(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { TPoint& p = Points_.back(); p.GetValue().AsLogHistogram()->Ref(); - } - } - - void CopyFrom(const TMetricTimeSeries& other) { + } + } + + void CopyFrom(const TMetricTimeSeries& other) { if (Empty()) { ValueType_ = other.ValueType_; } else { CheckTypes(GetValueType(), other.GetValueType()); } - - size_t prevSize = Points_.size(); - Copy(std::begin(other.Points_), std::end(other.Points_), - std::back_inserter(Points_)); - - if (ValueType_ == EMetricValueType::HISTOGRAM) { - for (size_t i = prevSize; i < Points_.size(); i++) { - TPoint& point = Points_[i]; - point.GetValue().AsHistogram()->Ref(); - } - } else if (ValueType_ == EMetricValueType::SUMMARY) { + + size_t prevSize = Points_.size(); + Copy(std::begin(other.Points_), std::end(other.Points_), + std::back_inserter(Points_)); + + if (ValueType_ == EMetricValueType::HISTOGRAM) { + for (size_t i = prevSize; i < Points_.size(); i++) { + TPoint& point = Points_[i]; + point.GetValue().AsHistogram()->Ref(); + } + } else if (ValueType_ == EMetricValueType::SUMMARY) { for (size_t i = prevSize; i < Points_.size(); ++i) { TPoint& point = Points_[i]; point.GetValue().AsSummaryDouble()->Ref(); @@ -436,56 +436,56 @@ namespace NMonitoring { } } - template <typename TConsumer> - void ForEach(TConsumer c) const { - for (const auto& point : Points_) { - c(point.GetTime(), ValueType_, point.GetValue()); - } - } - - bool Empty() const noexcept { - return Points_.empty(); - } - - size_t Size() const noexcept { - return Points_.size(); - } - + template <typename TConsumer> + void ForEach(TConsumer c) const { + for (const auto& point : Points_) { + c(point.GetTime(), ValueType_, point.GetValue()); + } + } + + bool Empty() const noexcept { + return Points_.empty(); + } + + size_t Size() const noexcept { + return Points_.size(); + } + size_t Capacity() const noexcept { return Points_.capacity(); } - const TPoint& operator[](size_t index) const noexcept { - return Points_[index]; - } - - void SortByTs(); - - void Clear() noexcept; - - EMetricValueType GetValueType() const noexcept { - return ValueType_; - } - - private: - static void CheckTypes(EMetricValueType t1, EMetricValueType t2) { - Y_ENSURE(t1 == t2, + const TPoint& operator[](size_t index) const noexcept { + return Points_[index]; + } + + void SortByTs(); + + void Clear() noexcept; + + EMetricValueType GetValueType() const noexcept { + return ValueType_; + } + + private: + static void CheckTypes(EMetricValueType t1, EMetricValueType t2) { + Y_ENSURE(t1 == t2, "Series type mismatch: expected " << t1 << ", but got " << t2); - } - - private: - EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; - TVector<TPoint> Points_; - }; - - template <EMetricValueType valueType, typename TPoint> + } + + private: + EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; + TVector<TPoint> Points_; + }; + + template <EMetricValueType valueType, typename TPoint> static inline void SnapshotUnRef(TPoint& point) { - if constexpr (valueType == EMetricValueType::HISTOGRAM) { + if constexpr (valueType == EMetricValueType::HISTOGRAM) { if (auto* hist = point.GetValue().AsHistogram()) { hist->UnRef(); } - } else if constexpr (valueType == EMetricValueType::SUMMARY) { + } else if constexpr (valueType == EMetricValueType::SUMMARY) { if (auto* summary = point.GetValue().AsSummaryDouble()) { summary->UnRef(); } @@ -496,14 +496,14 @@ namespace NMonitoring { } } - template <EMetricValueType valueType, typename TPoint> + template <EMetricValueType valueType, typename TPoint> static void EraseDuplicates(TVector<TPoint>& points) { // we have to manually clean reference to a snapshot from point // while removing duplicates auto result = points.rbegin(); for (auto it = result + 1; it != points.rend(); ++it) { if (result->GetTime() != it->GetTime() && ++result != it) { - SnapshotUnRef<valueType>(*result); + SnapshotUnRef<valueType>(*result); *result = *it; // (2) copy it->ClearValue(); // (3) clean pointer in the source } @@ -511,13 +511,13 @@ namespace NMonitoring { // erase tail points for (auto it = result + 1; it != points.rend(); ++it) { - SnapshotUnRef<valueType>(*it); + SnapshotUnRef<valueType>(*it); } points.erase(points.begin(), (result + 1).base()); } template <typename TPoint> - void SortPointsByTs(EMetricValueType valueType, TVector<TPoint>& points) { + void SortPointsByTs(EMetricValueType valueType, TVector<TPoint>& points) { if (points.size() < 2) { return; } @@ -530,13 +530,13 @@ namespace NMonitoring { points.erase(points.begin(), it.base()); } else { StableSortBy(points, NPrivate::POINT_KEY_FN); - if (valueType == EMetricValueType::HISTOGRAM) { - EraseDuplicates<EMetricValueType::HISTOGRAM>(points); + if (valueType == EMetricValueType::HISTOGRAM) { + EraseDuplicates<EMetricValueType::HISTOGRAM>(points); } else if (valueType == EMetricValueType::LOGHISTOGRAM) { EraseDuplicates<EMetricValueType::LOGHISTOGRAM>(points); } else { - EraseDuplicates<EMetricValueType::SUMMARY>(points); + EraseDuplicates<EMetricValueType::SUMMARY>(points); } } } -} +} |