/* 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/h/iomanip.h" #include "base/polyLogCats.h" #include "loganalyzers/InfoScope.h" #include "loganalyzers/SideInfo.h" #include "loganalyzers/PhaseInfo.h" #include "loganalyzers/ProcInfo.h" ProcInfo::ProcInfo(const String &aName): theName(aName), theSide(0), theLogCat(lgcEnd) { } ProcInfo::~ProcInfo() { while (thePhases.count()) delete thePhases.pop(); } const String &ProcInfo::name() const { if (theName) return theName; static String defName = "unnamed"; return defName; } int ProcInfo::logCat() const { return theLogCat; } const String &ProcInfo::benchmarkVersion() const { return theBenchmarkVersion; } const String &ProcInfo::pglCfg() const { return thePglCfg; } Time ProcInfo::startTime() const { return theStartTime; } void ProcInfo::logCat(int aLogCat) { Assert(theLogCat == lgcEnd && 0 <= aLogCat && aLogCat < lgcEnd); theLogCat = aLogCat; } void ProcInfo::side(SideInfo *aSide) { Assert(!theSide ^ !aSide); theSide = aSide; } void ProcInfo::benchmarkVersion(const String &aVersion) { Assert(!theBenchmarkVersion); theBenchmarkVersion = aVersion; } void ProcInfo::pglCfg(const String &aPglCfg) { Assert(!thePglCfg); thePglCfg = aPglCfg; } void ProcInfo::startTime(Time aStartTime) { Assert(theStartTime < 0); theStartTime = aStartTime; } const PhaseInfo &ProcInfo::execScopePhase() const { return theExecScopePhase; } const PhaseInfo &ProcInfo::allPhasesPhase() const { return theAllPhasesPhase; } int ProcInfo::repCount(const Scope &scope) const { int count = 0; for (int i = 0; i < thePhases.count(); ++i) { if (scope.hasPhase(thePhases[i]->name())) count += thePhases[i]->stats().theXactCnt; // all successfull } return count; } int ProcInfo::hitCount(const Scope &scope) const { int count = 0; for (int i = 0; i < thePhases.count(); ++i) { if (scope.hasPhase(thePhases[i]->name())) count += thePhases[i]->stats().theBasicXacts.hits().size().stats().count(); } return count; } int ProcInfo::offeredHitCount(const Scope &scope) const { int count = 0; for (int i = 0; i < thePhases.count(); ++i) { if (scope.hasPhase(thePhases[i]->name())) count += thePhases[i]->stats().theIdealHR.hits().count(); } return count; } BigSize ProcInfo::repVolume(const Scope &scope) const { BigSize volume = 0; for (int i = 0; i < thePhases.count(); ++i) { if (scope.hasPhase(thePhases[i]->name())) { const TmSzStat repAll = thePhases[i]->stats().reps(); volume += BigSize::Byted(repAll.size().sum()); } } return volume; } BigSize ProcInfo::hitVolume(const Scope &scope) const { BigSize volume = 0; for (int i = 0; i < thePhases.count(); ++i) { if (scope.hasPhase(thePhases[i]->name())) volume += BigSize::Byted(thePhases[i]->stats().theBasicXacts.hits().size().stats().sum()); } return volume; } BigSize ProcInfo::offeredHitVolume(const Scope &scope) const { BigSize volume = 0; for (int i = 0; i < thePhases.count(); ++i) { if (scope.hasPhase(thePhases[i]->name())) volume += BigSize::Byted(thePhases[i]->stats().theIdealHR.hits().size().sum()); } return volume; } void ProcInfo::noteIntvl(const StatIntvlRec &r, const String &phaseName) { if (!thePhases.count() || thePhases.last()->name() != phaseName) thePhases.append(new PhaseInfo()); thePhases.last()->noteIntvl(r, phaseName); } void ProcInfo::addPhase(const StatPhaseRec &r) { int foundCount = 0; for (int i = 0; i < thePhases.count(); ++i) { PhaseInfo &pi = *thePhases[i]; if (pi.name() == r.name()) { ++foundCount; if (!pi.hasStats()) { pi.notePhase(r); break; } } } if (foundCount == 0) { clog << name() << ": strange, phase '" << r.name() << "' has " << "phase statistics but no interval stats" << endl; thePhases.append(new PhaseInfo()); thePhases.last()->noteIntvl(r, r.name()); thePhases.last()->notePhase(r); } else if (foundCount > 1) { clog << name() << ": error: found " << foundCount << " phases named '" << r.name() << "', even after trying " << "to make all phase names unique; the reporter may fail or " << "mislead" << endl; } } void ProcInfo::noteEndOfLog() { for (int i = 0; i < thePhases.count(); ++i) thePhases[i]->noteEndOfLog(); } const PhaseInfo &ProcInfo::phase(int idx) const { Assert(0 <= idx && idx < thePhases.count()); return *thePhases[idx]; } const PhaseInfo *ProcInfo::hasPhase(const String &name) const { for (int i = 0; i < phaseCount(); ++i) { if (thePhases[i]->name() == name) return thePhases[i]; } return 0; } const PhaseInfo &ProcInfo::phase(const String &name) const { const PhaseInfo *p = hasPhase(name); Assert(p); return *p; } int ProcInfo::phaseCount() const { return thePhases.count(); } PhaseTrace *ProcInfo::tracePhase(const String &name) { for (int i = 0; i < phaseCount(); ++i) { if (thePhases[i]->name() == name) return thePhases[i]->startTrace(); } return 0; } void ProcInfo::checkConsistency() { if (!theBenchmarkVersion) cerr << name() << ": strange, no benchmark version found" << endl; if (!thePglCfg) cerr << name() << ": strange, no PGL configuration found" << endl; if (theStartTime < 0) cerr << name() << ": strange, no startup time could be determined" << endl; } void ProcInfo::compileStats(BlobDb &) { const Scope &scope = theSide->execScope(); for (int i = 0; i < phaseCount(); ++i) { if (scope.hasPhase(thePhases[i]->name())) theExecScopePhase.concat(*thePhases[i]); theAllPhasesPhase.concat(*thePhases[i]); } }