]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/DecayCounter.h
import ceph quincy 17.2.6
[ceph.git] / ceph / src / common / DecayCounter.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_DECAYCOUNTER_H
16 #define CEPH_DECAYCOUNTER_H
17
18 #include "include/buffer.h"
19 #include "common/Formatter.h"
20 #include "common/StackStringStream.h"
21 #include "common/ceph_time.h"
22
23 #include <cmath>
24 #include <list>
25 #include <sstream>
26
27 /**
28 *
29 * TODO: normalize value based on some function of half_life,
30 * so that it can be interpreted as an approximation of a
31 * moving average of N seconds. currently, changing half-life
32 * skews the scale of the value, even at steady state.
33 *
34 */
35
36 class DecayRate {
37 public:
38 friend class DecayCounter;
39
40 DecayRate() {}
41 // cppcheck-suppress noExplicitConstructor
42 DecayRate(double hl) { set_halflife(hl); }
43 DecayRate(const DecayRate &dr) : k(dr.k) {}
44
45 void set_halflife(double hl) {
46 k = log(.5) / hl;
47 }
48 double get_halflife() const {
49 return log(.5) / k;
50 }
51
52 private:
53 double k = 0; // k = ln(.5)/half_life
54 };
55
56 class DecayCounter {
57 public:
58 using time = ceph::coarse_mono_time;
59 using clock = ceph::coarse_mono_clock;
60
61 DecayCounter() : DecayCounter(DecayRate()) {}
62 explicit DecayCounter(const DecayRate &rate) : last_decay(clock::now()), rate(rate) {}
63
64 void encode(ceph::buffer::list& bl) const;
65 void decode(ceph::buffer::list::const_iterator& p);
66 void dump(ceph::Formatter *f) const;
67 static void generate_test_instances(std::list<DecayCounter*>& ls);
68
69 /**
70 * reading
71 */
72
73 double get() const {
74 decay();
75 return val;
76 }
77
78 double get_last() const {
79 return val;
80 }
81
82 time get_last_decay() const {
83 return last_decay;
84 }
85
86 /**
87 * adjusting
88 */
89
90 double hit(double v = 1.0) {
91 decay(v);
92 return val;
93 }
94 void adjust(double v = 1.0) {
95 decay(v);
96 }
97
98 void scale(double f) {
99 val *= f;
100 }
101
102 /**
103 * decay etc.
104 */
105
106 void reset() {
107 last_decay = clock::now();
108 val = 0;
109 }
110
111 protected:
112 void decay(double delta) const;
113 void decay() const {decay(0.0);}
114
115 private:
116 mutable double val = 0.0; // value
117 mutable time last_decay = clock::zero(); // time of last decay
118 DecayRate rate;
119 };
120
121 inline void encode(const DecayCounter &c, ceph::buffer::list &bl) {
122 c.encode(bl);
123 }
124 inline void decode(DecayCounter &c, ceph::buffer::list::const_iterator &p) {
125 c.decode(p);
126 }
127
128 inline std::ostream& operator<<(std::ostream& out, const DecayCounter& d) {
129 CachedStackStringStream css;
130 css->precision(2);
131 double val = d.get();
132 *css << "[C " << std::scientific << val << "]";
133 return out << css->strv();
134 }
135
136 #endif