diff options
Diffstat (limited to 'src/common/DecayCounter.h')
-rw-r--r-- | src/common/DecayCounter.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/common/DecayCounter.h b/src/common/DecayCounter.h new file mode 100644 index 000000000..9455ecc5a --- /dev/null +++ b/src/common/DecayCounter.h @@ -0,0 +1,136 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#ifndef CEPH_DECAYCOUNTER_H +#define CEPH_DECAYCOUNTER_H + +#include "include/buffer.h" +#include "common/Formatter.h" +#include "common/StackStringStream.h" +#include "common/ceph_time.h" + +#include <cmath> +#include <list> +#include <sstream> + +/** + * + * TODO: normalize value based on some function of half_life, + * so that it can be interpreted as an approximation of a + * moving average of N seconds. currently, changing half-life + * skews the scale of the value, even at steady state. + * + */ + +class DecayRate { +public: + friend class DecayCounter; + + DecayRate() {} + // cppcheck-suppress noExplicitConstructor + DecayRate(double hl) { set_halflife(hl); } + DecayRate(const DecayRate &dr) : k(dr.k) {} + + void set_halflife(double hl) { + k = log(.5) / hl; + } + double get_halflife() const { + return log(.5) / k; + } + +private: + double k = 0; // k = ln(.5)/half_life +}; + +class DecayCounter { +public: + using time = ceph::coarse_mono_time; + using clock = ceph::coarse_mono_clock; + + DecayCounter() : DecayCounter(DecayRate()) {} + explicit DecayCounter(const DecayRate &rate) : last_decay(clock::now()), rate(rate) {} + + void encode(ceph::buffer::list& bl) const; + void decode(ceph::buffer::list::const_iterator& p); + void dump(ceph::Formatter *f) const; + static void generate_test_instances(std::list<DecayCounter*>& ls); + + /** + * reading + */ + + double get() const { + decay(); + return val; + } + + double get_last() const { + return val; + } + + time get_last_decay() const { + return last_decay; + } + + /** + * adjusting + */ + + double hit(double v = 1.0) { + decay(v); + return val; + } + void adjust(double v = 1.0) { + decay(v); + } + + void scale(double f) { + val *= f; + } + + /** + * decay etc. + */ + + void reset() { + last_decay = clock::now(); + val = 0; + } + +protected: + void decay(double delta) const; + void decay() const {decay(0.0);} + +private: + mutable double val = 0.0; // value + mutable time last_decay = clock::zero(); // time of last decay + DecayRate rate; +}; + +inline void encode(const DecayCounter &c, ceph::buffer::list &bl) { + c.encode(bl); +} +inline void decode(DecayCounter &c, ceph::buffer::list::const_iterator &p) { + c.decode(p); +} + +inline std::ostream& operator<<(std::ostream& out, const DecayCounter& d) { + CachedStackStringStream css; + css->precision(2); + double val = d.get(); + *css << "[C " << std::scientific << val << "]"; + return out << css->strv(); +} + +#endif |