/* 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 #include "base/ErrorRec.h" #include "base/ILog.h" #include "base/OLog.h" #include "base/ErrorHash.h" ErrorHash::ErrorHash(int aCapacity): theHash(aCapacity), theCount(0) { theHash.count(theHash.capacity()); theHash.memset(0); } ErrorHash::~ErrorHash() { for (int i = 0; i < theHash.count(); ++i) { ErrorRec *r = theHash[i]; while (r) { ErrorRec *next = r->next(); delete r; r= next; } } } const ErrorRec *ErrorHash::find(const Error &e) const { return *findPos(e); } ErrorRec *ErrorHash::findOrAdd(const Error &e) { ErrorRec **pos = findPos(e); if (!*pos) { *pos = new ErrorRec(e); theCount++; } return *pos; } void ErrorHash::add(const ErrorHash &h) { for (ErrorHashIter i = h.iterator(); i; ++i) { ErrorRec **pos = findPos(*i); if (!*pos) { *pos = new ErrorRec(*i); theCount++; } else { (*pos)->add(*i); } } } void ErrorHash::store(OLog &ol) const { ol << theCount; for (ErrorHashIter i = iterator(); i; ++i) { i->store(ol); } } void ErrorHash::load(ILog &il) { Assert(!theCount); il >> theCount; for (int i = 0; i < theCount; ++i) { ErrorRec *r = new ErrorRec; r->load(il); ErrorRec **pos = findPos(*r); Assert(!*pos); *pos = r; } } ErrorHashIter ErrorHash::iterator() const { return ErrorHashIter(this); } int ErrorHash::hash(const Error &e) const { return abs(e.no()) % theHash.capacity(); } ErrorRec **ErrorHash::findPos(const Error &e) { ErrorRec **pos = &theHash[hash(e)]; while (*pos && (*pos)->no() != e.no()) pos = &(*pos)->next(); return pos; } ErrorRec *const *ErrorHash::findPos(const Error &e) const { ErrorRec *const *pos = &theHash[hash(e)]; while (*pos && (*pos)->no() != e.no()) pos = &(*pos)->next(); return pos; } /* ErrorHashIter */ ErrorHashIter::ErrorHashIter(const ErrorHash *aHash): theHash(aHash), theRec(0), theBucket(-1) { Assert(theHash); next(); } void ErrorHashIter::next() { // move within a bucket if (theRec) theRec = theRec->next(); // find next non-empty bucket while (!theRec && ++theBucket < theHash->theHash.count()) theRec = theHash->theHash[theBucket]; }