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 #include "base/polygraph.h"
7 
8 #include "base/ILog.h"
9 #include "base/OLog.h"
10 #include "base/GoalRec.h"
11 #include "xstd/gadgets.h"
12 
13 
14 template <class T>
15 inline
SetOrInc(T & var,const T & inc)16 void SetOrInc(T &var, const T &inc) {
17 	if (var < 0)
18 		var = inc;
19 	else
20 	if (inc >= 0)
21 		var += inc;
22 }
23 
24 
25 /* ErrGoalRec */
26 
ErrGoalRec()27 ErrGoalRec::ErrGoalRec(): theRatio(-1), theCount(-1) {
28 }
29 
operator +=(const ErrGoalRec & e)30 ErrGoalRec &ErrGoalRec::operator +=(const ErrGoalRec &e) {
31 
32 	SetOrInc(theCount, e.theCount);
33 
34 	if (theRatio < 0)
35 		theRatio = e.theRatio;
36 	else
37 	if (e.theRatio >= 0)
38 		theRatio = Min(theRatio, e.theRatio);
39 
40 	return *this;
41 }
42 
store(OLog & ol) const43 OLog &ErrGoalRec::store(OLog &ol) const {
44 	return ol << theRatio << theCount;
45 }
46 
load(ILog & il)47 ILog &ErrGoalRec::load(ILog &il) {
48 	return il >> theRatio >> theCount;
49 }
50 
print(ostream & os) const51 ostream &ErrGoalRec::print(ostream &os) const {
52 	if (theRatio > 0)
53 		return os << 100*theRatio << '%';
54 	if (theCount > 0)
55 		return os << theCount;
56 	return os << "<none>";
57 }
58 
print(ostream & os,const String & pfx) const59 ostream &ErrGoalRec::print(ostream &os, const String &pfx) const {
60 	if (theRatio > 0)
61 		os << pfx << "ratio:\t " << 100*theRatio << endl;
62 	if (theCount > 0)
63 		os << pfx << "count:\t " << theCount << endl;
64 	return os;
65 }
66 
67 /* GoalRec */
68 
GoalRec()69 GoalRec::GoalRec(): theXactCnt(-1), theFillSz(-1) {
70 }
71 
operator void*() const72 GoalRec::operator void*() const {
73 	// note: errors alone do not count as a real goal
74 	return theDuration >= 0 || theXactCnt >= 0 || theFillSz >= 0 ?
75 		(void*)-1 : 0;
76 }
77 
join(const GoalRec & g)78 void GoalRec::join(const GoalRec &g) {
79 	if (theDuration < 0)
80 		theDuration = g.theDuration;
81 	SetOrInc(theXactCnt, g.theXactCnt);
82 	SetOrInc(theFillSz, g.theFillSz);
83 	theErrs += g.theErrs;
84 }
85 
concat(const GoalRec & g)86 void GoalRec::concat(const GoalRec &g) {
87 	SetOrInc(theDuration, g.theDuration);
88 	join(g);
89 }
90 
merge(const GoalRec & g)91 void GoalRec::merge(const GoalRec &g) {
92 	join(g);
93 }
94 
store(OLog & ol) const95 OLog &GoalRec::store(OLog &ol) const {
96 	return ol << theDuration << theXactCnt << theFillSz << theErrs;
97 }
98 
load(ILog & il)99 ILog &GoalRec::load(ILog &il) {
100 	return il >> theDuration >> theXactCnt >> theFillSz >> theErrs;
101 }
102 
print(ostream & os) const103 ostream &GoalRec::print(ostream &os) const {
104 #define grp_stream_hack  (count++ ? os << ':' : os)
105 	int count = 0;
106 
107 	if (theDuration >= 0)
108 		grp_stream_hack << theDuration;
109 	if (theXactCnt >= 0)
110 		grp_stream_hack << theXactCnt;
111 	if (theFillSz >= 0)
112 		grp_stream_hack << theFillSz;
113 	if (theErrs)
114 		theErrs.print(grp_stream_hack);
115 
116 	if (!count)
117 		os << "<none>";
118 
119 	return os;
120 }
121 
122 
print(ostream & os,const String & pfx) const123 ostream &GoalRec::print(ostream &os, const String &pfx) const {
124 
125 	if (theDuration >= 0)
126 		os << pfx << "duration:\t " << theDuration.secd() << endl;
127 	if (theXactCnt >= 0)
128 		os << pfx << "xactions:\t " << theXactCnt << endl;
129 	if (theFillSz >= 0)
130 		os << pfx << "fill.size:\t " << theFillSz.byted() << endl;
131 	if (theErrs)
132 		theErrs.print(os, pfx + "errors.");
133 	return os;
134 }
135