]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / sdk / include / opentelemetry / sdk / _metrics / aggregator / min_max_sum_count_aggregator.h
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #pragma once
5 #ifdef ENABLE_METRICS_PREVIEW
6
7 # include "opentelemetry/_metrics/instrument.h"
8 # include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
9 # include "opentelemetry/version.h"
10
11 # include <memory>
12 # include <mutex>
13 # include <vector>
14
15 OPENTELEMETRY_BEGIN_NAMESPACE
16 namespace sdk
17 {
18 namespace metrics
19 {
20 const int MinValueIndex = 0;
21 const int MaxValueIndex = 1;
22 const int SumValueIndex = 2;
23 const int CountValueIndex = 3;
24 /**
25 * This aggregator stores and maintains a vector of
26 * type T where the contents in the vector are made
27 * up of the minimum value recorded to this instrument,
28 * the maximum value, the sum of all values, and the
29 * count of all values.
30 *
31 * @tparam T the type of values stored in this aggregator.
32 */
33 template <class T>
34 class MinMaxSumCountAggregator : public Aggregator<T>
35 {
36 public:
37 explicit MinMaxSumCountAggregator(opentelemetry::metrics::InstrumentKind kind)
38 {
39 static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
40 this->kind_ = kind;
41 this->values_ = std::vector<T>(4, 0); // {min, max, sum, count}
42 this->checkpoint_ = this->values_;
43 this->agg_kind_ = AggregatorKind::MinMaxSumCount;
44 }
45
46 ~MinMaxSumCountAggregator() = default;
47
48 MinMaxSumCountAggregator(const MinMaxSumCountAggregator &cp)
49 {
50 this->values_ = cp.values_;
51 this->checkpoint_ = cp.checkpoint_;
52 this->kind_ = cp.kind_;
53 this->agg_kind_ = cp.agg_kind_;
54 // use default initialized mutex as they cannot be copied
55 }
56
57 /**
58 * Receives a captured value from the instrument and applies it to the current aggregator value.
59 *
60 * @param val, the raw value used in aggregation
61 */
62 void update(T val) override
63 {
64 this->mu_.lock();
65 this->updated_ = true;
66
67 if (this->values_[CountValueIndex] == 0 || val < this->values_[MinValueIndex]) // set min
68 this->values_[MinValueIndex] = val;
69 if (this->values_[CountValueIndex] == 0 || val > this->values_[MaxValueIndex]) // set max
70 this->values_[MaxValueIndex] = val;
71
72 this->values_[SumValueIndex] += val; // compute sum
73 this->values_[CountValueIndex]++; // increment count
74
75 this->mu_.unlock();
76 }
77
78 /**
79 * Checkpoints the current value. This function will overwrite the current checkpoint with the
80 * current value.
81 *
82 */
83 void checkpoint() override
84 {
85 this->mu_.lock();
86 this->updated_ = false;
87 this->checkpoint_ = this->values_;
88 // Reset the values
89 this->values_[MinValueIndex] = 0;
90 this->values_[MaxValueIndex] = 0;
91 this->values_[SumValueIndex] = 0;
92 this->values_[CountValueIndex] = 0;
93 this->mu_.unlock();
94 }
95
96 /**
97 * Merges two MinMaxSumCount aggregators together
98 *
99 * @param other the aggregator to merge with this aggregator
100 */
101 void merge(const MinMaxSumCountAggregator &other)
102 {
103 if (this->kind_ == other.kind_)
104 {
105 this->mu_.lock();
106 // First merge values
107 // set min
108 if (this->values_[CountValueIndex] == 0 ||
109 other.values_[MinValueIndex] < this->values_[MinValueIndex])
110 this->values_[MinValueIndex] = other.values_[MinValueIndex];
111 // set max
112 if (this->values_[CountValueIndex] == 0 ||
113 other.values_[MaxValueIndex] > this->values_[MaxValueIndex])
114 this->values_[MaxValueIndex] = other.values_[MaxValueIndex];
115 // set sum
116 this->values_[SumValueIndex] += other.values_[SumValueIndex];
117 // set count
118 this->values_[CountValueIndex] += other.values_[CountValueIndex];
119
120 // Now merge checkpoints
121 if (this->checkpoint_[CountValueIndex] == 0 ||
122 other.checkpoint_[MinValueIndex] < this->checkpoint_[MinValueIndex])
123 this->checkpoint_[MinValueIndex] = other.checkpoint_[MinValueIndex];
124 // set max
125 if (this->checkpoint_[CountValueIndex] == 0 ||
126 other.checkpoint_[MaxValueIndex] > this->checkpoint_[MaxValueIndex])
127 this->checkpoint_[MaxValueIndex] = other.checkpoint_[MaxValueIndex];
128 // set sum
129 this->checkpoint_[SumValueIndex] += other.checkpoint_[SumValueIndex];
130 // set count
131 this->checkpoint_[CountValueIndex] += other.checkpoint_[CountValueIndex];
132
133 this->mu_.unlock();
134 }
135 else
136 {
137 // Log error
138 return;
139 }
140 }
141
142 /**
143 * Returns the checkpointed value
144 *
145 * @return the value of the checkpoint
146 */
147 std::vector<T> get_checkpoint() override { return this->checkpoint_; }
148
149 /**
150 * Returns the values currently held by the aggregator
151 *
152 * @return the values held by the aggregator
153 */
154 std::vector<T> get_values() override { return this->values_; }
155 };
156 } // namespace metrics
157 } // namespace sdk
158 OPENTELEMETRY_END_NAMESPACE
159 #endif