/* 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/iostream.h" #include "xstd/h/iomanip.h" #include "xstd/Error.h" #include "xstd/gadgets.h" #include "base/ILog.h" #include "base/OLog.h" #include "base/ErrorRec.h" #include "base/ErrorHash.h" #include "base/ErrorStat.h" ErrorStat::ErrorStat(): theHash(0), theCount(0) { newHash(); } ErrorStat::~ErrorStat() { delete theHash; } void ErrorStat::reset() { delete theHash; newHash(); theCount = 0; } void ErrorStat::newHash() { theHash = new ErrorHash(251); } bool ErrorStat::record(const Error &e, ErrorRec *&rec, int count) { Assert(count); rec = theHash->findOrAdd(e); Assert(rec); theCount += count; rec->noteError(count); return rec->needReport(); } void ErrorStat::add(const ErrorStat &s) { theCount += s.theCount; theHash->add(*s.theHash); } ErrorStat &ErrorStat::operator =(const ErrorStat &es) { reset(); add(es); return *this; } int ErrorStat::count(const Error &e) const { if (const ErrorRec *rec = theHash->find(e)) return rec->count(); else return 0; } OLog &ErrorStat::store(OLog &ol) const { theHash->store(ol); return ol << theCount; } ILog &ErrorStat::load(ILog &il) { reset(); theHash->load(il); return il >> theCount; } static int cmpErrRecPtr(const void *p1, const void *p2) { if (const int cmp = (*(const ErrorRec**)p1)->count() - (*(const ErrorRec**)p2)->count()) return -cmp; else return (*(const ErrorRec**)p1)->no() - (*(const ErrorRec**)p2)->no(); } int ErrorStat::index(Index &idx) const { idx.stretch(theHash->count()); for (ErrorHashIter i = theHash->iterator(); i; ++i) idx.append(&*i); qsort(idx.items(), idx.count(), sizeof(ErrorRec*), &cmpErrRecPtr); return idx.count(); } ostream &ErrorStat::print(ostream &os, const String &pfx) const { os << pfx << "count:\t " << count() << endl; Index prnIdx; if (index(prnIdx)) { os << pfx << "tbl:" << endl; os << "#count count% explanation" << endl; for (int j = 0; j < prnIdx.count(); ++j) { const ErrorRec *rec = prnIdx[j]; Assert(rec); os << setw(9) << rec->count() << ' ' << setw(6) << Percent(rec->count(), count()) << ' ' << '"'; rec->print(os) << '"' << endl; } os << endl; } return os; }