made some members non-inline to decrease size
[senf.git] / senf / Utils / Statistics.cc
index 2efca87..f2b9c9d 100644 (file)
@@ -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 <g0dil@berlios.de>
 
 // Custom includes
 #include <cmath>
+#include <cstdlib>
 #include <sstream>
-#include <senf/Utils/Console/Console.hh>
 #include <senf/Utils/Format.hh>
 #include "StatisticsTargets.hh"
 
 //#include "Statistics.mpp"
 #define prefix_
-///////////////////////////////cc.p////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 
-///////////////////////////////////////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 // 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)
@@ -58,6 +62,15 @@ prefix_ senf::Collector & senf::StatisticsBase::operator[](unsigned rank)
     return i->second;
 }
 
+prefix_ senf::Collector const & senf::StatisticsBase::operator[](unsigned rank)
+    const
+{
+    Children::const_iterator i (children_.find(rank));
+    if (i == children_.end())
+        throw InvalidRankException();
+    return i->second;
+}
+
 prefix_ senf::Collector & senf::StatisticsBase::collect(unsigned rank)
 {
     std::pair<Children::iterator, bool> state (
@@ -88,17 +101,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,15 +149,18 @@ prefix_ void senf::StatisticsBase::generateOutput()
     }
 }
 
-prefix_ void senf::StatisticsBase::signalChildren()
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
+// senf::StatisticsBase::OutputEntry
+
+prefix_ void senf::StatisticsBase::OutputEntry::consoleList(std::ostream & os)
 {
-    Children::iterator i (children_.begin());
-    Children::iterator const i_end  (children_.end());
-    for (; i != i_end; ++i)
-        i->second.enter(min_, avg_, max_, dev_);
+    for (boost::ptr_vector<TargetBase>::iterator i (targets_.begin());
+         i != targets_.end(); ++i)
+        if (! i->label.empty())
+            os << i->label << "\n";
 }
 
-///////////////////////////////////////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 // senf::Statistics
 
 prefix_ senf::Statistics::Statistics()
@@ -155,7 +171,7 @@ prefix_ senf::Statistics::Statistics()
 #ifndef SENF_DISABLE_CONSOLE
     namespace fty = senf::console::factory;
 
-    dir.add("list", fty::BoundCommand(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 +182,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::BoundCommand(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 +197,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::BoundCommand(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 +246,7 @@ prefix_ void senf::Statistics::consoleCollect(std::vector<unsigned> & ranks)
 
     for (; i != i_end; ++i)
         stats = & (stats->collect(*i));
-        
+
 }
 
 prefix_  boost::shared_ptr<senf::console::DirectoryNode>
@@ -239,7 +255,7 @@ senf::Statistics::consoleOutput(std::vector<unsigned> & ranks, unsigned window)
     StatisticsBase * stats (this);
     std::vector<unsigned>::const_iterator i (ranks.begin());
     std::vector<unsigned>::const_iterator const i_end (ranks.end());
-    
+
     try {
         for (; i != i_end; ++i)
             stats = &(*stats)[*i];
@@ -248,7 +264,7 @@ senf::Statistics::consoleOutput(std::vector<unsigned> & ranks, unsigned window)
 
     for (; i != i_end; ++i)
         stats = & (stats->collect(*i));
-    
+
     return stats->output(window).dir().node().thisptr();
 }
 
@@ -263,24 +279,40 @@ prefix_ std::string senf::Statistics::v_path()
     return "";
 }
 
-///////////////////////////////////////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 // 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;
     }
 }
 
@@ -295,7 +327,7 @@ prefix_ std::string senf::Collector::v_path()
     return owner_->path() + "-" + senf::str(rank_);
 }
 
-///////////////////////////////cc.e////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
 #undef prefix_
 //#include "Statistics.mpp"