NeighborCache Class Reference

#include <NeighborCache.h>

List of all members.

Public Member Functions

 ~NeighborCache ()
bool isEnabled ()
bool insertPingedNode (const TransportAddress &handle, cPolymorphic *context, RpcListener *rpcListener, int rpcId)
uint numInhibitedPings (const TransportAddress &handle)
WaitingContextsgetWaitingContexts (const TransportAddress &handle)
void insertAddressRtt (const NodeHandle &add, simtime_t time)
void addressTimeout (const TransportAddress &handle)
simtime_t getAddressRtt (const TransportAddress &add)
NodeHandle getNodeHandle (const TransportAddress &add)

Protected Member Functions

void initialize ()

Protected Attributes

std::map< TransportAddress,
NeighborCacheEntry
neighborCache
std::multimap< simtime_t,
TransportAddress
neighborCacheExpireMap

Private Member Functions

bool cleanupCache ()
void updateEntry (const TransportAddress &address, simtime_t insertTime)

Private Attributes

bool enableNeighborCache
simtime_t rttExpirationTime
uint maxSize

Friends

std::ostream & operator<< (std::ostream &os, const NeighborCacheEntry &)

Classes

struct  NeighborCacheEntry


Constructor & Destructor Documentation

NeighborCache::~NeighborCache (  ) 

00057 {
00058     for (std::map<TransportAddress, NeighborCacheEntry>::iterator it =
00059         neighborCache.begin(); it != neighborCache.end(); ++it) {
00060         if (it->second.waitingContexts) {
00061             for (uint i = 0;
00062                  i < it->second.waitingContexts->pingContexts.size();
00063                  ++i) {
00064                 delete it->second.waitingContexts->pingContexts[i];
00065             }
00066 
00067             delete it->second.waitingContexts;
00068         }
00069     }
00070 }


Member Function Documentation

bool NeighborCache::cleanupCache (  )  [private]

Referenced by addressTimeout(), insertAddressRtt(), and insertPingedNode().

00225 {
00226     bool result = false;
00227     uint size = neighborCache.size();
00228     if (size > maxSize) {
00229         std::map<simtime_t, TransportAddress>::iterator it;
00230         for (uint i = 0; i < (size - (maxSize / 2)); ++i) {
00231             it = neighborCacheExpireMap.begin();
00232             if ((neighborCache[it->second].rtt == NEIGHBORSTATE_WAITING) ||
00233                 (neighborCache[it->second].insertTime == simTime())) {
00234                 break;
00235             }
00236             neighborCache.erase(it->second);
00237             neighborCacheExpireMap.erase(it);
00238             result = true;
00239         }
00240     }
00241     assert(neighborCache.size() == neighborCacheExpireMap.size());
00242     return result;
00243 }

void NeighborCache::updateEntry ( const TransportAddress address,
simtime_t  insertTime 
) [private]

Referenced by addressTimeout(), insertAddressRtt(), and insertPingedNode().

00247 {
00248     std::multimap<simtime_t, TransportAddress>::iterator it =
00249         neighborCacheExpireMap.lower_bound(insertTime);
00250     while (it->second != address) ++it;
00251     neighborCacheExpireMap.erase(it);
00252     neighborCacheExpireMap.insert(std::make_pair(simTime(), address));
00253     assert(neighborCache.size() == neighborCacheExpireMap.size());
00254 }

void NeighborCache::initialize (  )  [protected]

00047 {
00048     neighborCache.clear();
00049     WATCH_MAP(neighborCache);
00050 
00051     enableNeighborCache = par("enableNeighborCache");
00052     rttExpirationTime = par("rttExpirationTime");
00053     maxSize = par("maxSize");
00054 }

bool NeighborCache::isEnabled (  )  [inline]

Referenced by BasePastry::baseInit().

00098     {
00099         return enableNeighborCache;
00100     };

bool NeighborCache::insertPingedNode ( const TransportAddress handle,
cPolymorphic *  context,
RpcListener rpcListener,
int  rpcId 
)

Referenced by BaseRpc::pingNode().

00076 {
00077     if (!enableNeighborCache) return false;
00078     if (neighborCache.count(handle) == 0) {// || !enableNeighborCache) {
00079         NeighborCacheEntry entry;
00080 
00081         entry.insertTime = simulation.simTime();
00082         entry.rtt = NEIGHBORSTATE_WAITING;
00083         entry.nodeRef = NodeHandle::UNSPECIFIED_NODE;
00084 
00085         neighborCache[handle] = entry;
00086         neighborCacheExpireMap.insert(std::make_pair(entry.insertTime, handle));
00087 
00088         cleanupCache();
00089 
00090         assert(neighborCache.size() == neighborCacheExpireMap.size());
00091         return false;
00092     } else {
00093         NeighborCacheEntry& entry = neighborCache[handle];
00094 
00095         // waiting?
00096         if (entry.rtt == NEIGHBORSTATE_WAITING) {
00097             if (entry.waitingContexts == NULL)
00098                 entry.waitingContexts = new WaitingContexts();
00099             entry.waitingContexts->pingContexts.push_back(context);
00100             entry.waitingContexts->pingListeners.push_back(rpcListener);
00101             entry.waitingContexts->pingIds.push_back(rpcId);
00102 
00103             return true;
00104         } else {
00105             if (entry.waitingContexts != NULL &&
00106                 entry.waitingContexts->pingContexts.size() != 0) {
00107                 throw new cRuntimeError("not waiting for response,"
00108                                         " but additional contexts found!");
00109             }
00110 
00111             updateEntry(handle, entry.insertTime);
00112 
00113             entry.rtt = NEIGHBORSTATE_WAITING;
00114             entry.insertTime = simulation.simTime();
00115             entry.nodeRef = NodeHandle::UNSPECIFIED_NODE;
00116 
00117             return false;
00118         }
00119     }
00120 }

uint NeighborCache::numInhibitedPings ( const TransportAddress handle  )  [inline]

Referenced by BaseRpc::pingRpcResponse(), and BaseRpc::pingRpcTimeout().

00108     {
00109         if (neighborCache.count(handle) == 0 || !par("enableNeighborCache") ||
00110             neighborCache[handle].waitingContexts == NULL)
00111             return 0;
00112         return neighborCache[handle].waitingContexts->pingIds.size();
00113     };

WaitingContexts* NeighborCache::getWaitingContexts ( const TransportAddress handle  )  [inline]

Referenced by BaseRpc::pingRpcResponse(), and BaseRpc::pingRpcTimeout().

00116     {
00117         if (!enableNeighborCache) return NULL;
00118         if (neighborCache.count(handle) == 0)
00119             throw new cRuntimeError("NeighborCache error!");
00120         WaitingContexts* temp = neighborCache[handle].waitingContexts;
00121         neighborCache[handle].waitingContexts = NULL;
00122         return temp;
00123     };

void NeighborCache::insertAddressRtt ( const NodeHandle add,
simtime_t  time 
)

Referenced by BaseRpc::pingRpcResponse().

00167 {
00168     if (!enableNeighborCache) return;
00169     TransportAddress ta = add;
00170     if (neighborCache.count(ta) == 0) {
00171         NeighborCacheEntry entry;
00172 
00173         entry.insertTime = simulation.simTime();
00174         entry.rtt = rtt;
00175         entry.nodeRef = add;
00176 
00177         neighborCache[ta] = entry;
00178         neighborCacheExpireMap.insert(std::make_pair(entry.insertTime, add));
00179 
00180         cleanupCache();
00181     } else {
00182         updateEntry(add, neighborCache[ta].insertTime);
00183 
00184         neighborCache[ta].insertTime = simulation.simTime();
00185         neighborCache[ta].rtt = rtt;
00186         neighborCache[ta].nodeRef = add;
00187     }
00188     assert(neighborCache.size() == neighborCacheExpireMap.size());
00189 }

void NeighborCache::addressTimeout ( const TransportAddress handle  ) 

Referenced by BaseRpc::pingRpcTimeout().

00141 {
00142     if (!enableNeighborCache) return;
00143     if (neighborCache.count(handle) == 0) {
00144         NeighborCacheEntry entry;
00145 
00146         entry.insertTime = simulation.simTime();
00147         entry.rtt = NEIGHBORSTATE_TIMEOUT;
00148         entry.nodeRef = NodeHandle::UNSPECIFIED_NODE;
00149 
00150         neighborCache[handle] = entry;
00151         neighborCacheExpireMap.insert(std::make_pair(entry.insertTime, handle));
00152 
00153         cleanupCache();
00154     } else {
00155         NeighborCacheEntry& entry = neighborCache[handle];
00156 
00157         updateEntry(handle, entry.insertTime);
00158 
00159         entry.insertTime = simulation.simTime();
00160         entry.rtt = NEIGHBORSTATE_TIMEOUT;
00161     }
00162     assert(neighborCache.size() == neighborCacheExpireMap.size());
00163 }

simtime_t NeighborCache::getAddressRtt ( const TransportAddress add  ) 

Referenced by BasePastry::determineAliveTable(), and BaseRpc::pingNode().

00192 {
00193     // cache disabled or entry not there
00194     if (!enableNeighborCache ||
00195         add.isUnspecified() ||
00196         (neighborCache.count(add) == 0)) {
00197         //std::cout << "NeighobrCache: MISS!" << std::endl;
00198         return NEIGHBORSTATE_UNKNOWN;
00199     }
00200 
00201     NeighborCacheEntry entry = neighborCache[add];
00202 
00203     if (entry.rtt == NEIGHBORSTATE_WAITING ||
00204         entry.rtt == NEIGHBORSTATE_UNKNOWN)
00205         return entry.rtt;
00206     // entry expired
00207     if ((simulation.simTime() - entry.insertTime) >= rttExpirationTime) {
00208         entry.rtt = NEIGHBORSTATE_UNKNOWN;
00209         return NEIGHBORSTATE_UNKNOWN;
00210     }
00211     //std::cout << "NeighborCache: HIT!" << std::endl;
00212     return entry.rtt;
00213 }

NodeHandle NeighborCache::getNodeHandle ( const TransportAddress add  ) 

Referenced by BaseRpc::pingNode(), and BaseRpc::pingRpcResponse().

00216 {
00217     if (neighborCache.count(add) == 0) {
00218         throw new cRuntimeError("NeighborCache.cc: getNodeHandle was asked for "
00219                                 "a non-existent node reference.");
00220     }
00221     return neighborCache[add].nodeRef;
00222 }


Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  os,
const NeighborCacheEntry p 
) [friend]

00034 {
00035     os << p.rtt << " (inserted: " << p.insertTime /*<< ", #contexts: "
00036        << p.pingContexts.size() */<< ", key: "
00037        << (p.nodeRef.isUnspecified() ? "<unspec>" : p.nodeRef.key.toString(16))
00038        << ")";
00039 
00040     return os;
00041 }


Member Data Documentation

simtime_t NeighborCache::rttExpirationTime [private]

Referenced by getAddressRtt(), and initialize().

uint NeighborCache::maxSize [private]

Referenced by cleanupCache(), and initialize().

std::multimap<simtime_t, TransportAddress> NeighborCache::neighborCacheExpireMap [protected]


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:07 2008 for ITM OverSim by  doxygen 1.5.5