/* 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 "runtime/HostMap.h" HostMap *TheHostMap = 0; /* HostCfg */ HostCfg::HostCfg(const NetAddr &anAddr): theAddr(anAddr), theContent(0), theSslWrap(0), theServerRep(0), thePubWorld(0), theCookies(0) { } /* HostMap */ HostMap::HostMap(int aCapacity): theIndex((aCapacity + aCapacity/3 + 7) | 1), theCount(0) { HostCfg *h = 0; while (!theIndex.full()) theIndex.push(h); } HostMap::~HostMap() { while (theIndex.count()) delete theIndex.pop(); } HostCfg *HostMap::at(int idx) { return (0 <= idx && idx < capacity()) ? theIndex[idx] : 0; } HostCfg *HostMap::at(const NetAddr &addr) { int idx = -1; Assert(findIdx(addr, idx)); return theIndex[idx]; } ServerRep *HostMap::serverRepAt(int idx) { if (HostCfg *cfg = at(idx)) return cfg->theServerRep; return 0; } const SslWrap *HostMap::findSslWrap(const NetAddr &addr) const { int idx = -1; if (findIdx(addr, idx)) return theIndex[idx]->theSslWrap; return 0; } PubWorld *HostMap::findPubWorld(const NetAddr &addr) { int idx = -1; if (findIdx(addr, idx)) return theIndex[idx]->thePubWorld; return 0; } PubWorld *HostMap::findPubWorldAt(int idx) { return (0 <= idx && idx < capacity()) ? theIndex[idx]->thePubWorld : 0; } HostCfg *HostMap::find(const NetAddr &addr) { int idx = -1; return find(addr, idx); } HostCfg *HostMap::find(const NetAddr &addr, int &idx) { if (findIdx(addr, idx)) return theIndex[idx]; return 0; } bool HostMap::findIdx(const NetAddr &addr, int &idx) const { bool res = false; idx = hash0(addr); if (endSearch(addr, idx, res)) return res; // try hash1 followed by linear search idx = hash1(addr); for (int i = theIndex.capacity(); i; --i) { if (endSearch(addr, idx, res)) return res; idx++; idx %= capacity(); } Assert(false); // no empty slots left! return res; } HostCfg *HostMap::addAt(int idx, const NetAddr &addr) { Assert(addr); Assert(!theIndex[idx]); theCount++; return (theIndex[idx] = new HostCfg(addr)); } // returns true if there is no reason to search further (match or empty) bool HostMap::endSearch(const NetAddr &addr, int idx, bool &res) const { if (HostCfg *h = theIndex[idx]) { if (h->theAddr == addr) return res = true; return res = false; } // found empty slot res = false; return true; } int HostMap::hash0(const NetAddr &addr) const { return addr.hash0() % capacity(); //return abs((int)(addr.lna() + addr.port())) % capacity(); } int HostMap::hash1(const NetAddr &addr) const { return addr.hash1() % capacity(); //return abs((int)(addr.lna() ^ addr.port() + addr.net())) % capacity(); }