/* Web Polygraph http://www.web-polygraph.org/ * (C) 2003-2006 The Measurement Factory * Licensed under the Apache License, Version 2.0 */ #ifndef POLYGRAPH__BASE_HISTOGRAM_H #define POLYGRAPH__BASE_HISTOGRAM_H #include "xstd/Array.h" #include "base/AggrStat.h" #include "base/ILog.h" #include "base/OLog.h" #include "base/LogObj.h" class HistogramConstIter; // general purpose histogram abstraction // value range: [min, max) class Histogram: public LogObj { friend class HistogramConstIter; public: typedef int Val; // change to double if needed public: Histogram(); Histogram(Val aMin, Val aMax, int binCount); virtual ~Histogram() {} void limits(Val aMin, Val aMax, int binCount); virtual void reset(); void record(Val v); virtual OLog &store(OLog &log) const; virtual ILog &load(ILog &); virtual void add(const Histogram &h); Histogram &operator +=(const Histogram &h); bool known() const { return stats().known(); } const AggrStat &stats() const { return theStats; } // extreme bins' counters bool extreme(int bin) const { return !bin || bin == theBinMax; } int underCount() const { return theBins[0]; } int overCount() const { return theBins[theBinMax]; } ostream &print(ostream &os, const String &pfx) const; void report(double step, ostream &os) const; protected: virtual const char *type() const = 0; // val2bin type virtual int val2Bin(Val v) const = 0; // value is already offset virtual Val bin2Val(int b) const = 0; // does not offset value Val extract(int b) const { return bin2Val(b-1) + theValMin; } int count(int b) const { return theBins[b]; } private: Histogram(const Histogram &) {} protected: Array theBins; // counters are stored here AggrStat theStats; Val theValMin; Val theValMax; int theBinMax; }; // a virtual representation of a histogram "bin" class HistogramBin { public: HistogramBin() { reset(); } void reset() { idx = count = accCount = 0; min = sup = -1; } HistogramBin &operator +=(const HistogramBin &b); public: Histogram::Val min; Histogram::Val sup; // max+1 int idx; int count; int accCount; // cumulative count }; // constant iterator for a histogram class HistogramConstIter { public: HistogramConstIter(const Histogram &aHist); operator void*() const { return theBin.idx <= theHist.theBinMax ? (void*)-1 : 0; } const HistogramBin &operator *() const { return theBin; } const HistogramBin *operator ->() const { return &theBin; } HistogramConstIter &operator ++(); private: void sync(); protected: const Histogram &theHist; HistogramBin theBin; // current bin; }; // builds percentiles array with a given step (1% default) extern void Percentiles(const Histogram &, Array &percs, double step = 0.01); #endif