/* 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 "base/ConnCloseStat.h" // stores stats about one kind of conn close class ConnCloseStatItem: public LogObj { public: ConnCloseStatItem(int aKind); const TimeHist &ttlHist() const; const Log2Hist &useHist() const; void record(Time ttl, int useCnt); void add(const ConnCloseStatItem &i); virtual OLog &store(OLog &ol) const; virtual ILog &load(ILog &il); ostream &print(ostream &os, const String &pfx) const; protected: TimeHist theTtlH; Log2Hist theUseH; int theKind; }; /* ConnCloseStatItem */ ConnCloseStatItem::ConnCloseStatItem(int aKind): theUseH(0, 16*1024-1), theKind(aKind) { } const TimeHist &ConnCloseStatItem::ttlHist() const { return theTtlH; } const Log2Hist &ConnCloseStatItem::useHist() const { return theUseH; } void ConnCloseStatItem::record(Time ttl, int useCnt) { theTtlH.record(ttl); theUseH.record(useCnt); } void ConnCloseStatItem::add(const ConnCloseStatItem &i) { Assert(theKind == i.theKind); theTtlH.add(i.theTtlH); theUseH.add(i.theUseH); } OLog &ConnCloseStatItem::store(OLog &ol) const { return ol << theKind << theUseH << theTtlH; } ILog &ConnCloseStatItem::load(ILog &il) { return il >> theKind >> theUseH >> theTtlH; } ostream &ConnCloseStatItem::print(ostream &os, const String &pfx) const { const char *kind = (theKind == ConnCloseStat::ckBusy ? "busy" : (theKind == ConnCloseStat::ckIdleLocal ? "idle_local" : (theKind == ConnCloseStat::ckIdleForeign ? "idle_foreign" : "other"))); theUseH.print(os, pfx + kind + ".use."); theTtlH.print(os, pfx + kind + ".ttl."); return os; } /* ConnCloseStat */ ConnCloseStat::ConnCloseStat() { theStats.stretch((int)ckEnd); for (int i = 0; i < (int)ckEnd; ++i) theStats.append(new ConnCloseStatItem(i)); } ConnCloseStat::~ConnCloseStat() { while (theStats.count()) delete theStats.pop(); } void ConnCloseStat::useHist(Log2Hist &acc) const { for (int i = 0; i < theStats.count(); ++i) acc.add(useHist(i)); } void ConnCloseStat::ttlHist(TimeHist &acc) const { for (int i = 0; i < theStats.count(); ++i) acc.add(ttlHist(i)); } const Log2Hist &ConnCloseStat::useHist(int ck) const { Assert(0 <= ck && ck < theStats.count()); return theStats[ck]->useHist(); } const TimeHist &ConnCloseStat::ttlHist(int ck) const { Assert(0 <= ck && ck < theStats.count()); return theStats[ck]->ttlHist(); } void ConnCloseStat::record(CloseKind ck, Time ttl, int useCnt) { Assert(0 <= ck && ck < theStats.count()); theStats[(int)ck]->record(ttl, useCnt); } void ConnCloseStat::add(const ConnCloseStat &s) { Assert(theStats.count() == s.theStats.count()); for (int i = 0; i < theStats.count(); ++i) theStats[i]->add(*s.theStats[i]); } static OLog &operator <<(OLog &os, const ConnCloseStatItem *i) { Assert(i); return i->store(os); } static ILog &operator >>(ILog &is, ConnCloseStatItem *&i) { if (!i) i = new ConnCloseStatItem(-1); return i->load(is); } OLog &ConnCloseStat::store(OLog &ol) const { return ol << theStats; } ILog &ConnCloseStat::load(ILog &il) { return il >> theStats; } ostream &ConnCloseStat::print(ostream &os, const String &pfx) const { os << pfx << "categories:\t " << theStats.count() << endl; for (int i = 0; i < theStats.count(); ++i) theStats[i]->print(os, pfx); return os; }