NeighborCache.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026 #ifndef __NEIGHBORCACHE_H_
00027 #define __NEIGHBORCACHE_H_
00028
00029 #include <omnetpp.h>
00030
00031 #include <map>
00032 #include <cfloat>
00033 #include <deque>
00034
00035 #include <BaseApp.h>
00036 #include <NodeHandle.h>
00037 #include <CoordinateSystem.h>
00038 #include <Nps.h>
00039 #include <Vivaldi.h>
00040 #include <SVivaldi.h>
00041 #include <ProxNodeHandle.h>
00042 #include <HashFunc.h>
00043
00044 class GlobalStatistics;
00045 class TransportAddress;
00046 class RpcListener;
00047
00048
00049
00050 enum NeighborCacheQueryType {
00051 NEIGHBORCACHE_AVAILABLE,
00052 NEIGHBORCACHE_EXACT,
00053 NEIGHBORCACHE_EXACT_TIMEOUT,
00054 NEIGHBORCACHE_ESTIMATED,
00055 NEIGHBORCACHE_QUERY,
00056
00057 NEIGHBORCACHE_DEFAULT,
00058 NEIGHBORCACHE_DEFAULT_IMMEDIATELY,
00059 NEIGHBORCACHE_DEFAULT_QUERY
00060 };
00061
00062 class ProxListener {
00063 public:
00064 virtual void proxCallback(const TransportAddress& node, int rpcId,
00065 cPolymorphic *contextPointer, Prox prox) = 0;
00066 };
00067
00068 class NeighborCache : public BaseApp
00069 {
00070 friend class Nps;
00071
00072 private:
00073
00074 bool enableNeighborCache;
00075 bool doDiscovery;
00076 simtime_t rttExpirationTime;
00077 uint32_t maxSize;
00078
00079 uint32_t misses;
00080 uint32_t hits;
00081
00082 bool cleanupCache();
00083
00084 void updateEntry(const TransportAddress& address,
00085 simtime_t insertTime);
00086
00087 AbstractNcs* ncs;
00088
00089 NeighborCacheQueryType defaultQueryType;
00090 NeighborCacheQueryType defaultQueryTypeI;
00091 NeighborCacheQueryType defaultQueryTypeQ;
00092
00093 Prox getCoordinateBasedProx(const TransportAddress& node);
00094
00095 cMessage* landmarkTimer;
00096
00097 static const std::vector<double> coordsDummy;
00098
00099
00100 void calcRttError(const NodeHandle &handle, simtime_t rtt);
00101 std::map<TransportAddress, std::vector<double> > lastAbsoluteErrorPerNode;
00102 uint32_t numMsg;
00103 double absoluteError;
00104 double relativeError;
00105 uint32_t numRttErrorToHigh;
00106 uint32_t numRttErrorToLow;
00107 uint32_t rttHistory;
00108 double timeoutAccuracyLimit;
00109
00110 struct WaitingContext
00111 {
00112 WaitingContext() { proxListener = NULL; proxContext = NULL; };
00113 WaitingContext(ProxListener* listener,
00114 cPolymorphic* context,
00115 uint32_t id)
00116 : proxListener(listener), proxContext(context), id(id) { };
00117 ProxListener* proxListener;
00118 cPolymorphic* proxContext;
00119 uint32_t id;
00120 };
00121 typedef std::vector<WaitingContext> WaitingContexts;
00122
00123
00124 bool insertNodeContext(const TransportAddress& handle,
00125 cPolymorphic* context,
00126 ProxListener* rpcListener,
00127 int rpcId);
00128
00129 NeighborCache::WaitingContexts getNodeContexts(const TransportAddress& handle);
00130
00131 enum NeighborCacheRttState {
00132 RTTSTATE_VALID,
00133 RTTSTATE_UNKNOWN,
00134 RTTSTATE_TIMEOUT,
00135 RTTSTATE_WAITING
00136 };
00137
00138 typedef std::pair<simtime_t, NeighborCacheRttState> Rtt;
00139
00140 Rtt getNodeRtt(const TransportAddress& add);
00141
00142 static const double RTT_TIMEOUT_ADJUSTMENT = 1.3;
00143 static const double NCS_TIMEOUT_CONSTANT = 0.25;
00144
00145 protected:
00146 GlobalStatistics* globalStatistics;
00147
00148 struct NeighborCacheEntry {
00149 NeighborCacheEntry() { insertTime = simTime();
00150 rttState = RTTSTATE_UNKNOWN;
00151 coordsInfo = NULL; };
00152
00153 ~NeighborCacheEntry() {
00154 delete coordsInfo;
00155 for (uint16_t i = 0; i < waitingContexts.size(); ++i) {
00156 delete waitingContexts[i].proxContext;
00157 }
00158 };
00159
00160 simtime_t insertTime;
00161 simtime_t rtt;
00162 NeighborCacheRttState rttState;
00163 std::deque<simtime_t> lastRtts;
00164 NodeHandle nodeRef;
00165 NodeHandle srcRoute;
00166 AbstractNcsNodeInfo* coordsInfo;
00167
00168 WaitingContexts waitingContexts;
00169 };
00170
00171 UNORDERED_MAP<TransportAddress, NeighborCacheEntry> neighborCache;
00172 typedef UNORDERED_MAP<TransportAddress, NeighborCacheEntry>::iterator NeighborCacheIterator;
00173 typedef UNORDERED_MAP<TransportAddress, NeighborCacheEntry>::const_iterator NeighborCacheConstIterator;
00174
00175 std::multimap<simtime_t, TransportAddress> neighborCacheExpireMap;
00176 typedef std::multimap<simtime_t, TransportAddress>::iterator neighborCacheExpireMapIterator;
00177
00178 void initializeApp(int stage);
00179
00180 void finishApp();
00181
00182 virtual CompType getThisCompType() { return NEIGHBORCACHE_COMP; };
00183
00184 void handleReadyMessage(CompReadyMessage* readyMsg);
00185
00186 void handleTimerEvent(cMessage* msg);
00187
00194 void queryProx(const TransportAddress &node,
00195 int rpcId,
00196 ProxListener *listener,
00197 cPolymorphic *contextPointer);
00198
00202 bool handleRpcCall(BaseCallMessage* msg);
00203
00204 simtime_t getRttBasedTimeout(const NodeHandle &node);
00205 simtime_t getNcsBasedTimeout(const NodeHandle &node);
00206
00207 public:
00208 ~NeighborCache();
00209
00210 inline bool isEnabled() { return enableNeighborCache; };
00211
00212 bool adaptingNcs() { return ncs && ncs->isAdapting(); };
00213
00214 const AbstractNcs& getNcsAccess() const {
00215 if (!ncs) throw cRuntimeError("No NCS activated");
00216 else return *ncs;
00217 };
00218
00219 uint16_t getNeighborCacheSize() { return neighborCache.size(); };
00220
00221
00222 bool isEntry(const TransportAddress& node);
00223 simtime_t getNodeAge(const TransportAddress& handle);
00224 const NodeHandle& getNodeHandle(const TransportAddress &add);
00225
00232 simtime_t getNodeTimeout(const NodeHandle &node);
00233
00234
00235 TransportAddress getNearestNode(uint8_t maxLayer);
00236 double getAvgAbsPredictionError();
00237
00238
00239 void updateNode(const NodeHandle &add, simtime_t rtt,
00240 const NodeHandle& srcRoute = NodeHandle::UNSPECIFIED_NODE,
00241 AbstractNcsNodeInfo* ncsInfo = NULL);
00242 void updateNcsInfo(const TransportAddress& node,
00243 AbstractNcsNodeInfo* ncsInfo);
00244 void setNodeTimeout(const TransportAddress& handle);
00245
00267 Prox getProx(const TransportAddress &node,
00268 NeighborCacheQueryType type = NEIGHBORCACHE_AVAILABLE,
00269 int rpcId = -1,
00270 ProxListener *listener = NULL,
00271 cPolymorphic *contextPointer = NULL);
00272
00280 Prox estimateProx(const TransportAddress &node);
00281
00288 const AbstractNcsNodeInfo* getNodeCoordsInfo(const TransportAddress &node);
00289
00290
00291
00292
00293
00294
00295 std::pair<simtime_t, simtime_t> getMeanVarRtt(const TransportAddress &node,
00296 bool returnVar);
00297
00298 friend std::ostream& operator<<(std::ostream& os,
00299 const NeighborCacheEntry& entry);
00300 };
00301
00302 #endif
00303