1#pragma once
2
3#include <stddef.h>
4#include <cstdint>
5#include <utility>
6#include <atomic>
7#include <Core/Types.h>
8
9/** Allows to count number of simultaneously happening processes or current value of some metric.
10 * - for high-level profiling.
11 *
12 * See also ProfileEvents.h
13 * ProfileEvents counts number of happened events - for example, how many times queries was executed.
14 * CurrentMetrics counts number of simultaneously happening events - for example, number of currently executing queries, right now,
15 * or just current value of some metric - for example, replica delay in seconds.
16 *
17 * CurrentMetrics are updated instantly and are correct for any point in time.
18 * For periodically (asynchronously) updated metrics, see AsynchronousMetrics.h
19 */
20
21namespace CurrentMetrics
22{
23 /// Metric identifier (index in array).
24 using Metric = size_t;
25 using Value = DB::Int64;
26
27 /// Get name of metric by identifier. Returns statically allocated string.
28 const char * getName(Metric event);
29 /// Get text description of metric by identifier. Returns statically allocated string.
30 const char * getDocumentation(Metric event);
31
32 /// Metric identifier -> current value of metric.
33 extern std::atomic<Value> values[];
34
35 /// Get index just after last metric identifier.
36 Metric end();
37
38 /// Set value of specified metric.
39 inline void set(Metric metric, Value value)
40 {
41 values[metric].store(value, std::memory_order_relaxed);
42 }
43
44 /// Add value for specified metric. You must subtract value later; or see class Increment below.
45 inline void add(Metric metric, Value value = 1)
46 {
47 values[metric].fetch_add(value, std::memory_order_relaxed);
48 }
49
50 inline void sub(Metric metric, Value value = 1)
51 {
52 add(metric, -value);
53 }
54
55 /// For lifetime of object, add amout for specified metric. Then subtract.
56 class Increment
57 {
58 private:
59 std::atomic<Value> * what;
60 Value amount;
61
62 Increment(std::atomic<Value> * what_, Value amount_)
63 : what(what_), amount(amount_)
64 {
65 *what += amount;
66 }
67
68 public:
69 Increment(Metric metric, Value amount_ = 1)
70 : Increment(&values[metric], amount_) {}
71
72 ~Increment()
73 {
74 if (what)
75 what->fetch_sub(amount, std::memory_order_relaxed);
76 }
77
78 Increment(Increment && old)
79 {
80 *this = std::move(old);
81 }
82
83 Increment & operator= (Increment && old)
84 {
85 what = old.what;
86 amount = old.amount;
87 old.what = nullptr;
88 return *this;
89 }
90
91 void changeTo(Value new_amount)
92 {
93 what->fetch_add(new_amount - amount, std::memory_order_relaxed);
94 amount = new_amount;
95 }
96
97 /// Subtract value before destructor.
98 void destroy()
99 {
100 what->fetch_sub(amount, std::memory_order_relaxed);
101 what = nullptr;
102 }
103 };
104}
105