1 
2 /* Web Polygraph       http://www.web-polygraph.org/
3  * Copyright 2003-2011 The Measurement Factory
4  * Licensed under the Apache License, Version 2.0 */
5 
6 #ifndef POLYGRAPH__BASE_HISTOGRAM_H
7 #define POLYGRAPH__BASE_HISTOGRAM_H
8 
9 #include "xstd/Array.h"
10 #include "base/AggrStat.h"
11 #include "base/ILog.h"
12 #include "base/OLog.h"
13 #include "base/LogObj.h"
14 
15 class HistogramConstIter;
16 
17 // general purpose histogram abstraction
18 // value range: [min, max)
19 class Histogram: public LogObj {
20 	friend class HistogramConstIter;
21 
22 	public:
23 		typedef int Val; // change to double if needed
24 
25 	public:
26 		Histogram();
27 		Histogram(Val aMin, Val aMax, int binCount);
28 		Histogram(const Histogram &h);
~Histogram()29 		virtual ~Histogram() {}
30 
31 		void limits(Val aMin, Val aMax, int binCount);
32 		virtual void reset();
33 
34 		void record(Val v);
35 
36 		virtual OLog &store(OLog &log) const;
37 		virtual ILog &load(ILog &);
38 
39 		virtual void add(const Histogram &h);
40 		Histogram &operator +=(const Histogram &h);
41 
sane()42 		bool sane() const { return stats().sane(); }
known()43 		bool known() const { return stats().known(); }
stats()44 		const AggrStat &stats() const { return theStats; }
45 
46 		// extreme bins' counters
extreme(int bin)47 		bool extreme(int bin) const { return !bin || bin == theBinMax; }
underCount()48 		Counter underCount() const { return theBins[0]; }
overCount()49 		Counter overCount() const { return theBins[theBinMax]; }
50 
51 		ostream &print(ostream &os, const String &pfx) const;
52 		void report(double step, ostream &os) const;
53 
54 	protected:
55 		virtual const char *type() const = 0; // val2bin type
56 		virtual int val2Bin(Val v) const = 0; // value is already offset
57 		virtual Val bin2Val(int b) const = 0; // does not offset value
58 
extract(int b)59 		Val extract(int b) const { return bin2Val(b-1) + theValMin; }
count(const int b)60 		Counter count(const int b) const { return theBins[b]; }
61 
62 	protected:
63 		Array<Counter> theBins; // counters are stored here
64 		AggrStat theStats;
65 		Val theValMin;
66 		Val theValMax;
67 		int theBinMax;
68 };
69 
70 
71 // a virtual representation of a histogram "bin"
72 class HistogramBin {
73 	public:
HistogramBin()74 		HistogramBin() { reset(); }
reset()75 		void reset() { count = accCount = idx = 0; min = sup = -1; }
76 
77 		HistogramBin &operator +=(const HistogramBin &b);
78 
79 	public:
80 		Histogram::Val min;
81 		Histogram::Val sup; // max+1
82 		int idx;
83 		Counter count;
84 		Counter accCount; // cumulative count
85 };
86 
87 // constant iterator for a histogram
88 class HistogramConstIter {
89 	public:
90 		HistogramConstIter(const Histogram &aHist);
91 
92 		operator void*() const { return theBin.idx <= theHist.theBinMax ? (void*)-1 : 0; }
93 		const HistogramBin &operator *() const { return theBin; }
94 		const HistogramBin *operator ->() const { return &theBin; }
95 		HistogramConstIter &operator ++();
96 
97 	private:
98 		void sync();
99 
100 	protected:
101 		const Histogram &theHist;
102 		HistogramBin theBin; // current bin;
103 };
104 
105 
106 // builds percentiles array with a given step (1% default)
107 extern void Percentiles(const Histogram &, Array<HistogramBin> &percs, double step = 0.01);
108 
109 
110 
111 #endif
112