00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef HH_SENF_Utils_Statistics_
00027 #define HH_SENF_Utils_Statistics_ 1
00028
00029
00030 #include <map>
00031 #include <vector>
00032 #include <deque>
00033 #include <boost/iterator/transform_iterator.hpp>
00034 #include <boost/range/iterator_range.hpp>
00035 #include <boost/utility.hpp>
00036 #include <boost/ptr_container/ptr_vector.hpp>
00037 #include <boost/signals.hpp>
00038 #include <senf/Utils/Logger/Logger.hh>
00039 #include <senf/Utils/Console/ScopedDirectory.hh>
00040 #include "StatisticAccumulator.hh"
00041 #include "Exception.hh"
00042
00043
00044
00045
00046 namespace senf {
00047
00064 class Collector;
00065 class Statistics;
00066
00068 class StatisticsBase
00069 {
00070 typedef std::map<unsigned, Collector> Children;
00071
00072 struct Transform {
00073 typedef Children::value_type & first_argument_type;
00074 typedef Collector & result_type;
00075 result_type operator()(first_argument_type i) const;
00076 };
00077
00078 typedef boost::transform_iterator<Transform,Children::iterator> ValueIterator;
00079
00080 struct OutputEntry;
00081
00082 public:
00083
00084
00085
00086 typedef boost::iterator_range<ValueIterator> CollectorRange;
00087
00123 template <class Owner>
00124 class OutputProxy
00125 {
00126 public:
00127 template <class Target> Owner & connect(Target & target,
00128 std::string label="") const;
00130 template <class PTarget> Owner & connect(std::auto_ptr<PTarget> target,
00131 std::string label="") const;
00133 Owner & noconnect() const;
00134 senf::console::ScopedDirectory<> & dir() const;
00136
00137 #ifdef DOXYGEN
00138 private:
00139 #endif
00140 OutputProxy(Owner * owner, OutputEntry * entry);
00141 template <class OtherOwner>
00142 OutputProxy(Owner * owner, OutputProxy<OtherOwner> const & other);
00143
00144 private:
00145 Owner * owner_;
00146 OutputEntry * entry_;
00147
00148 template <class OtherOwner> friend class OutputProxy;
00149 };
00150
00151
00153
00154
00155 float min() const;
00156 float avg() const;
00157 float max() const;
00158 float dev() const;
00159
00160 virtual unsigned rank() const;
00161
00164
00165
00167
00168
00169 Collector & operator[](unsigned rank);
00171
00177 Collector const & operator[](unsigned rank) const;
00179
00185 CollectorRange collectors();
00186
00189 Collector & collect(unsigned rank);
00190
00197 Statistics & base();
00198
00203 std::string path() const;
00204
00209
00210
00212
00213 OutputProxy<StatisticsBase> output(unsigned n = 1u);
00215
00226
00227
00228
00229
00230 struct InvalidRankException : public senf::Exception
00231 { InvalidRankException() : senf::Exception("Invalid rank value") {} };
00232
00233 struct DuplicateRankException : public senf::Exception
00234 { DuplicateRankException() : senf::Exception("Duplicate rank value") {} };
00235
00236 void consoleList(unsigned level, std::ostream & os) const;
00237
00238 protected:
00239 StatisticsBase();
00240 virtual ~StatisticsBase();
00241 void enter(unsigned n, float min, float avg, float max, float dev);
00242
00243 private:
00244 virtual Statistics & v_base() = 0;
00245 virtual std::string v_path() const = 0;
00246
00247 void generateOutput();
00248
00249 float min_;
00250 float avg_;
00251 float max_;
00252 float dev_;
00253 Children children_;
00254
00255 struct QueueEntry {
00256 float min;
00257 float avg;
00258 float max;
00259 float dev;
00260 QueueEntry() : min(), avg(), max(), dev() {}
00261 QueueEntry(float min_, float avg_, float max_, float dev_)
00262 : min(min_), avg(avg_), max(max_), dev(dev_) {}
00263 };
00264 typedef std::deque<QueueEntry> Queue;
00265 Queue queue_;
00266
00267 struct OutputEntry {
00268 struct TargetBase
00269 {
00270 explicit TargetBase(std::string const & label_) : label (label_) {}
00271 virtual ~TargetBase() {};
00272 std::string label;
00273 };
00274
00275 template <class PTarget>
00276 struct Target : public TargetBase
00277 {
00278 boost::scoped_ptr<PTarget> target_;
00279 Target(std::auto_ptr<PTarget> target, std::string const & label)
00280 : TargetBase (label), target_ (target.release()) {}
00281 explicit Target(std::string const & label)
00282 : TargetBase (label), target_ (0) {}
00283 };
00284
00285 OutputEntry();
00286 explicit OutputEntry(unsigned n_);
00287 OutputEntry(const OutputEntry& other);
00288 OutputEntry& operator=(const OutputEntry& other);
00289
00290 void initDir();
00291 void consoleList(std::ostream & os);
00292
00293 unsigned n;
00294 float min;
00295 float avg;
00296 float max;
00297 float dev;
00298
00299 boost::signal<void(float,float,float,float)> signal;
00300 boost::ptr_vector<TargetBase> targets_;
00301
00302 senf::console::ScopedDirectory<> dir;
00303 };
00304 typedef std::map<unsigned, OutputEntry> OutputMap;
00305 OutputMap outputs_;
00306 unsigned maxQueueLen_;
00307 };
00308
00422 class Statistics
00423 : public StatisticsBase, boost::noncopyable
00424 {
00425 public:
00426 #ifndef SENF_DISABLE_CONSOLE
00427 console::ScopedDirectory<Statistics> dir;
00428 #endif
00429
00430 Statistics();
00431
00432 void operator()(unsigned n, float min, float avg, float max, float dev);
00434
00460 void operator()(float min, float avg, float max, float dev=0.0f);
00462
00464 void operator()(float value, float dev=0.0f);
00466
00468 void operator()(StatisticsData const & data);
00470
00472 template <class Value>
00473 void operator()(unsigned n, StatisticAccumulator<Value> & sa);
00475
00481 StatisticsBase::OutputProxy<Statistics> output(unsigned n = 1u);
00482
00483 void consoleList(std::ostream & os);
00484 void consoleCollect(std::vector<unsigned> & ranks);
00485 boost::shared_ptr<senf::console::DirectoryNode> consoleOutput(
00486 std::vector<unsigned> & ranks, unsigned window);
00487
00488 private:
00489 Statistics & v_base();
00490 std::string v_path() const;
00491 };
00492
00500 class Collector : public StatisticsBase
00501 {
00502 public:
00503 virtual unsigned rank() const;
00504
00505 StatisticsBase::OutputProxy<Collector> output(unsigned n = 1u);
00506
00507 private:
00508 Collector(StatisticsBase * owner, unsigned rank);
00509 void enter(unsigned n, float min, float avg, float max, float dev);
00510 Statistics & v_base();
00511 std::string v_path() const;
00512
00513 unsigned rank_;
00514 unsigned i_;
00515 float accMin_;
00516 float accSum_;
00517 float accSumSq_;
00518 float accMax_;
00519 StatisticsBase * owner_;
00520
00521 friend class StatisticsBase;
00522 };
00523
00524 }
00525
00526
00527 #include "Statistics.cci"
00528
00529 #include "Statistics.cti"
00530 #endif
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541