X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FStatistics.cc;h=2fe933431710ed11b518cba960d318e19a2ca430;hb=c505c034e5fdc932c02aa3dc3847a5551011d87e;hp=3dd6d89786fe8deb2da9d7ce1b8447325faba43e;hpb=21be434729b552e31b856b2f42fc978062d0dd55;p=senf.git diff --git a/senf/Utils/Statistics.cc b/senf/Utils/Statistics.cc index 3dd6d89..2fe9334 100644 --- a/senf/Utils/Statistics.cc +++ b/senf/Utils/Statistics.cc @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2008 +// Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund @@ -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) @@ -88,17 +93,17 @@ prefix_ void senf::StatisticsBase::consoleList(unsigned level, std::ostream & os { namespace fmt = senf::format; - os << boost::format("%s%-5d%|15t| %12.5g %19.5g %12.5g\n") - % std::string(2*level,' ') % rank() + os << boost::format("%s%-5d%|15t| %12.5g %19.5g %12.5g\n") + % std::string(2*level,' ') % rank() % fmt::eng(min()).setw() % fmt::eng(avg(),dev()).setw() % fmt::eng(max()).setw(); { OutputMap::const_iterator i (outputs_.begin()); OutputMap::const_iterator i_end (outputs_.end()); for (; i != i_end; ++i) os << boost::format(" %3d %12.5g %19.5g %12.5g\n") - % i->second.n - % fmt::eng(i->second.min).setw() - % fmt::eng(i->second.avg, i->second.dev).setw() + % i->second.n + % fmt::eng(i->second.min).setw() + % fmt::eng(i->second.avg, i->second.dev).setw() % fmt::eng(i->second.max).setw(); } { @@ -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 @@ -155,7 +152,7 @@ prefix_ senf::Statistics::Statistics() #ifndef SENF_DISABLE_CONSOLE namespace fty = senf::console::factory; - dir.add("list", fty::Command(this,&Statistics::consoleList) + dir.add("list", fty::Command(&Statistics::consoleList, this) .doc("List statistics collection intervals and current values.\n" "\n" "Columns:\n" @@ -166,7 +163,7 @@ prefix_ senf::Statistics::Statistics() " AVG Last entered average value.\n" " DEV Standard deviation of average value over the collector rank.\n" " MAX Last entered maximum value.") ); - dir.add("collect", fty::Command(this, &Statistics::consoleCollect) + dir.add("collect", fty::Command(&Statistics::consoleCollect, this) .doc("Add statistics collection groups. The argument gives a sequence of collector\n" "ranks each building on the preceding collector:\n" "\n" @@ -181,7 +178,7 @@ prefix_ senf::Statistics::Statistics() "You may call collect multiple times. Any missing collection ranks will be\n" "added.") .arg("ranks","chain of collector ranks") ); - dir.add("output", fty::Command(this, &Statistics::consoleOutput) + dir.add("output", fty::Command(&Statistics::consoleOutput, this) .doc("Generate statistics output. This statement will add an additional output\n" "generator. This generator will be attached to the collector specified by\n" "the {rank} parameter. This parameter is a chain of successive rank values\n" @@ -230,7 +227,7 @@ prefix_ void senf::Statistics::consoleCollect(std::vector & ranks) for (; i != i_end; ++i) stats = & (stats->collect(*i)); - + } prefix_ boost::shared_ptr @@ -239,7 +236,7 @@ senf::Statistics::consoleOutput(std::vector & ranks, unsigned window) StatisticsBase * stats (this); std::vector::const_iterator i (ranks.begin()); std::vector::const_iterator const i_end (ranks.end()); - + try { for (; i != i_end; ++i) stats = &(*stats)[*i]; @@ -248,7 +245,7 @@ senf::Statistics::consoleOutput(std::vector & ranks, unsigned window) for (; i != i_end; ++i) stats = & (stats->collect(*i)); - + return stats->output(window).dir().node().thisptr(); } @@ -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; } }