// -*- 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 * * 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 #include #include /** * * 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& 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