/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "base/polygraph.h"
#include "xstd/Clock.h"
#include "base/ILog.h"
#include "base/OLog.h"
#include "base/LevelStat.h"
#include "xstd/gadgets.h"
LevelStat::LevelStat() {
theIncCnt = theDecCnt = theLevel = 0;
theSum = Time(0, 0);
theNom = theDenom = -1;
}
void LevelStat::restart() {
theIncCnt = theDecCnt = 0; // but keep level
theStart = theCurStart = TheClock;
theSum = Time(0, 0);
theNom = theDenom = -1;
}
void LevelStat::change() {
if (theStart <= 0)
theStart = TheClock;
else
theSum += (TheClock - theCurStart) * theLevel;
theCurStart = TheClock;
theNom = theDenom = -1;
}
double LevelStat::mean() const {
if (theDenom > 0)
return theNom/theDenom;
return theCurStart > theStart && theSum >= 0 ?
theSum/(theCurStart-theStart) :
theLevel;
}
void LevelStat::store(OLog &log) const {
log << theIncCnt << theDecCnt << theLevel
<< theStart << theCurStart << theSum;
}
void LevelStat::load(ILog &log) {
log >> theIncCnt >> theDecCnt >> theLevel
>> theStart >> theCurStart >> theSum;
}
bool LevelStat::sane() const {
return theIncCnt >= 0 && theDecCnt >= 0;
}
void LevelStat::keepLevel(const LevelStat &prevLevel) {
theLevel = prevLevel.theLevel;
}
void LevelStat::merge(const LevelStat &s) {
if (known() && s.known())
theLevel += s.theLevel; // imprecise
else
theLevel = s.theLevel;
LevelStat::join(s);
}
void LevelStat::concat(const LevelStat &s) {
if (s.known())
theLevel = s.theLevel;
// else should not happen
LevelStat::join(s);
}
void LevelStat::join(const LevelStat &s) {
if (theStart < 0) {
// join() should not alter theLevel that can be already computed
const int savedLevel = theLevel;
*this = s;
theLevel = savedLevel;
} else
if (theStart >= 0 && s.theStart >= 0) {
theIncCnt += s.theIncCnt;
theDecCnt += s.theDecCnt;
// set theNom before changing members nom() depends on
theNom = nom() + s.nom();
// note: this will produce correct means for levels
// with different start/stop times, but usually
// merged_mean will not be (mean1 + mean2)/2.
theStart = Min(theStart, s.theStart);
// assume that the curStart is also the end
theCurStart = Max(theCurStart, s.theCurStart);
theSum += s.theSum;
theDenom = (theCurStart-theStart).secd();
}
// else do nothing, should not happen
}
double LevelStat::nom() const {
return theNom > 0 ? theNom : theSum.secd();
}
double LevelStat::denom() const {
return theDenom > 0 ? theDenom : (theCurStart-theStart).secd();
}
ostream &LevelStat::print(ostream &os, const String &pfx) const {
os << pfx << "started: \t " << incCnt() << endl;
os << pfx << "finished: \t " << decCnt() << endl;
os << pfx << "level.mean:\t " << mean() << endl;
os << pfx << "level.last:\t " << level() << endl;
return os;
}
syntax highlighted by Code2HTML, v. 0.9.1