/* 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();
}
syntax highlighted by Code2HTML, v. 0.9.1