#include <NeighborCache.h>
Public Member Functions | |
~NeighborCache () | |
bool | isEnabled () |
bool | insertPingedNode (const TransportAddress &handle, cPolymorphic *context, RpcListener *rpcListener, int rpcId) |
uint | numInhibitedPings (const TransportAddress &handle) |
WaitingContexts * | getWaitingContexts (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 |
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 }
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] |
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 }
std::ostream& operator<< | ( | std::ostream & | os, | |
const NeighborCacheEntry & | p | |||
) | [friend] |
bool NeighborCache::enableNeighborCache [private] |
Referenced by addressTimeout(), getAddressRtt(), getWaitingContexts(), initialize(), insertAddressRtt(), insertPingedNode(), and isEnabled().
simtime_t NeighborCache::rttExpirationTime [private] |
Referenced by getAddressRtt(), and initialize().
uint NeighborCache::maxSize [private] |
Referenced by cleanupCache(), and initialize().
std::map<TransportAddress, NeighborCacheEntry> NeighborCache::neighborCache [protected] |
std::multimap<simtime_t, TransportAddress> NeighborCache::neighborCacheExpireMap [protected] |
Referenced by addressTimeout(), cleanupCache(), insertAddressRtt(), insertPingedNode(), and updateEntry().