From: g0dil Date: Fri, 7 May 2010 08:46:25 +0000 (+0000) Subject: Utils: Aggregate statistics submit interface X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=1ff86abcd6cd22bffcab7967b0bf7495e83a0de5;p=senf.git Utils: Aggregate statistics submit interface git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1627 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/senf/Utils/Statistics.cc b/senf/Utils/Statistics.cc index 01122b2..2fe9334 100644 --- a/senf/Utils/Statistics.cc +++ b/senf/Utils/Statistics.cc @@ -28,6 +28,7 @@ // Custom includes #include +#include #include #include #include @@ -40,14 +41,18 @@ /////////////////////////////////////////////////////////////////////////// // senf::StatisticsBase -prefix_ void senf::StatisticsBase::enter(float min, float avg, float max, float dev) +prefix_ void senf::StatisticsBase::enter(unsigned n, float min, float avg, float max, float dev) { min_ = min; avg_ = avg; max_ = max; dev_ = dev; - generateOutput(); - signalChildren(); + for (unsigned i (0); i < n; ++i) + generateOutput(); + Children::iterator i (children_.begin()); + Children::iterator const i_end (children_.end()); + for (; i != i_end; ++i) + i->second.enter(n, min_, avg_, max_, dev_); } prefix_ senf::Collector & senf::StatisticsBase::operator[](unsigned rank) @@ -136,14 +141,6 @@ prefix_ void senf::StatisticsBase::generateOutput() } } -prefix_ void senf::StatisticsBase::signalChildren() -{ - Children::iterator i (children_.begin()); - Children::iterator const i_end (children_.end()); - for (; i != i_end; ++i) - i->second.enter(min_, avg_, max_, dev_); -} - /////////////////////////////////////////////////////////////////////////// // senf::Statistics @@ -266,21 +263,37 @@ prefix_ std::string senf::Statistics::v_path() /////////////////////////////////////////////////////////////////////////// // senf::Collector -prefix_ void senf::Collector::enter(float min, float avg, float max, float dev) +prefix_ void senf::Collector::enter(unsigned n, float min, float avg, float max, float dev) { - accSum_ += avg; - accSumSq_ += avg*avg + dev*dev; if (min < accMin_) accMin_ = min; if (max > accMax_) accMax_ = max; - if (++i_ >= rank_) { - float accAvg (accSum_ / i_); - float accDev (std::sqrt(std::max(0.0f,accSumSq_ / i_ - accAvg*accAvg))); - StatisticsBase::enter(accMin_, accAvg, accMax_, accDev); - i_ = 0; + + if (i_ + n >= rank_) { + accSum_ += (rank_-i_)*avg; + accSumSq_ += (rank_-i_)*(rank_-i_)*(avg*avg + dev*dev); + float accAvg (accSum_ / rank_); + float accDev (std::sqrt(std::max(0.0f,accSumSq_ / rank_ - accAvg*accAvg))); + StatisticsBase::enter(1, accMin_, accAvg, accMax_, accDev); accMin_ = FLT_MAX; accSum_ = 0.0f; accSumSq_ = 0.0f; accMax_ = -FLT_MAX; + n -= (rank_ - i_); + i_ = 0; + + if (n >= rank_) { + std::div_t d (std::div(int(n), int(rank_))); + StatisticsBase::enter(d.quot, min, avg, max, dev); + n = d.rem; + } + } + + if (n>0) { + accSum_ += n*avg; + accSumSq_ += n*n*(avg*avg+dev*dev); + i_ += n; + if (min < accMin_) accMin_ = min; + if (max > accMax_) accMax_ = max; } } diff --git a/senf/Utils/Statistics.cci b/senf/Utils/Statistics.cci index 3b9ed9b..6fa454b 100644 --- a/senf/Utils/Statistics.cci +++ b/senf/Utils/Statistics.cci @@ -170,14 +170,20 @@ senf::Collector::output(unsigned n) /////////////////////////////////////////////////////////////////////////// // senf::Statistics +prefix_ void senf::Statistics::operator()(unsigned n, float min, float avg, float max, + float dev) +{ + enter(n, min, avg, max, dev); +} + prefix_ void senf::Statistics::operator()(float min, float avg, float max, float dev) { - enter(min, avg, max, dev); + enter(1, min, avg, max, dev); } prefix_ void senf::Statistics::operator()(float value, float dev) { - enter(value, value, value, dev); + enter(1, value, value, value, dev); } prefix_ senf::StatisticsBase::OutputProxy diff --git a/senf/Utils/Statistics.hh b/senf/Utils/Statistics.hh index b4cf0bf..3ac5d43 100644 --- a/senf/Utils/Statistics.hh +++ b/senf/Utils/Statistics.hh @@ -228,14 +228,13 @@ namespace senf { protected: StatisticsBase(); virtual ~StatisticsBase(); - void enter(float min, float avg, float max, float dev); + void enter(unsigned n, float min, float avg, float max, float dev); private: virtual Statistics & v_base() = 0; virtual std::string v_path() const = 0; void generateOutput(); - void signalChildren(); float min_; float avg_; @@ -420,24 +419,40 @@ namespace senf { Statistics(); - void operator()(float min, float avg, float max, float dev=0.0f); + void operator()(unsigned n, float min, float avg, float max, float dev); ///< Enter new data - /**< This member must be called whenever a new data value is - available. It is important to call this member \e - periodically. The frequency at which this member is - called defines the basic statistics time scale. + /**< This member must be called whenever new data is + available. If \a min and \a max values are not available, this member should be called with \a min, \a avg and \a max - set to the same value. - + set to the same value. If no error estimate is + available, call with \a dev = 0. + + In the most common case, this member is to be called + periodically and \a n will be 1 on all calls. The + interval, at which this member is called then defines + the statistics time scale. + + Calling with \a n > 1 will submit the value \a n + times. This makes it possible to aggregate multiple + time slices into a single call. This does not change + the basic time scale but can change the number of + submits per unit time. If the basic time slice is + small, this allows to submit values almost arbitrarily + non-periodic. + + \param[in] n number of time-slices \param[in] min minimal data value since last call \param[in] avg average data value since last call \param[in] max maximal data values since last call \param[in] dev standard deviation of avg value */ - + void operator()(float min, float avg, float max, float dev=0.0f); + ///< Same as operator() with \a n==1 + /**< Provided so a Statistics instance can be directly used + as a signal target. */ void operator()(float value, float dev=0.0f); - ///< Same as enter() with \a min == \a avg == \a max + ///< Same as operator() with \a min == \a avg == \a max /**< Provided so a Statistics instance can be directly used as a signal target. */ @@ -469,7 +484,7 @@ namespace senf { private: Collector(StatisticsBase * owner, unsigned rank); - void enter(float min, float avg, float max, float dev); + void enter(unsigned n, float min, float avg, float max, float dev); Statistics & v_base(); std::string v_path() const;