userver: userver/utils/statistics/rate_counter.hpp Source File
Loading...
Searching...
No Matches
rate_counter.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/statistics/rate_counter.hpp
4/// @brief @copybrief utils::statistics::RateCounter
5
6#include <atomic>
7
8#include <userver/utils/statistics/rate.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace utils::statistics {
13
14class Writer;
15
16/// @brief Atomic counter of type Rate with relaxed memory ordering
17///
18/// This class is represented as Rate metric when serializing to statistics.
19/// Otherwise it is the same class as RelaxedCounter
20class RateCounter final {
21public:
22 using ValueType = Rate;
23
24 constexpr RateCounter() noexcept = default;
25
26 constexpr explicit RateCounter(Rate desired) noexcept : val_(desired.value) {}
27
28 constexpr explicit RateCounter(Rate::ValueType desired) noexcept : val_(desired) {}
29
30 RateCounter(const RateCounter& other) noexcept : val_(other.Load().value) {}
31
32 RateCounter& operator=(const RateCounter& other) noexcept {
33 if (this == &other) {
34 return *this;
35 }
36
37 Store(other.Load());
38 return *this;
39 }
40
41 RateCounter& operator=(Rate desired) noexcept {
42 Store(desired);
43 return *this;
44 }
45
46 void Store(Rate desired, std::memory_order order = std::memory_order_relaxed) noexcept {
47 val_.store(desired.value, order);
48 }
49
50 Rate Load() const noexcept { return Rate{val_.load(std::memory_order_relaxed)}; }
51
52 void Add(Rate arg, std::memory_order order = std::memory_order_relaxed) noexcept {
53 val_.fetch_add(arg.value, order);
54 }
55
56 void AddAsSingleProducer(Rate arg) noexcept {
57 val_.store(val_.load(std::memory_order_relaxed) + arg.value, std::memory_order_relaxed);
58 }
59
60 RateCounter& operator++() noexcept {
61 val_.fetch_add(1, std::memory_order_relaxed);
62 return *this;
63 }
64
65 Rate operator++(int) noexcept { return Rate{val_.fetch_add(1, std::memory_order_relaxed)}; }
66
67 RateCounter& operator+=(Rate arg) noexcept {
68 val_.fetch_add(arg.value, std::memory_order_relaxed);
69 return *this;
70 }
71
72 RateCounter& operator+=(const RateCounter& arg) noexcept {
73 *this += arg.Load();
74 return *this;
75 }
76
77private:
78 static_assert(std::atomic<Rate::ValueType>::is_always_lock_free);
79
80 std::atomic<Rate::ValueType> val_{0};
81};
82
83void DumpMetric(Writer& writer, const RateCounter& value);
84
85void ResetMetric(RateCounter& value);
86
87} // namespace utils::statistics
88
89USERVER_NAMESPACE_END