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 <SimpleNcs.h>
00042 #include <ProxNodeHandle.h>
00043 #include <HashFunc.h>
00044
00045 class GlobalStatistics;
00046 class TransportAddress;
00047 class RpcListener;
00048
00049
00050
00051 enum NeighborCacheQueryType {
00052 NEIGHBORCACHE_AVAILABLE,
00053 NEIGHBORCACHE_EXACT,
00054 NEIGHBORCACHE_EXACT_TIMEOUT,
00055 NEIGHBORCACHE_ESTIMATED,
00056 NEIGHBORCACHE_QUERY,
00057
00058 NEIGHBORCACHE_DEFAULT,
00059 NEIGHBORCACHE_DEFAULT_IMMEDIATELY,
00060 NEIGHBORCACHE_DEFAULT_QUERY
00061 };
00062
00063 class ProxListener {
00064 public:
00065 virtual void proxCallback(const TransportAddress& node, int rpcId,
00066 cPolymorphic *contextPointer, Prox prox) = 0;
00067 };
00068
00069 class NeighborCache : public BaseApp
00070 {
00071 friend class Nps;
00072
00073 private:
00074
00075 bool enableNeighborCache;
00076 bool doDiscovery;
00077 simtime_t rttExpirationTime;
00078 uint32_t maxSize;
00079
00080 uint32_t misses;
00081 uint32_t hits;
00082
00083 bool cleanupCache();
00084
00085 void updateEntry(const TransportAddress& address,
00086 simtime_t insertTime);
00087
00088 AbstractNcs* ncs;
00089 bool ncsSendBackOwnCoords;
00090
00091 NeighborCacheQueryType defaultQueryType;
00092 NeighborCacheQueryType defaultQueryTypeI;
00093 NeighborCacheQueryType defaultQueryTypeQ;
00094
00095 Prox getCoordinateBasedProx(const TransportAddress& node);
00096
00097 cMessage* landmarkTimer;
00098
00099 static const std::vector<double> coordsDummy;
00100
00101
00102 void calcRttError(const NodeHandle &handle, simtime_t rtt);
00103 std::map<TransportAddress, std::vector<double> > lastAbsoluteErrorPerNode;
00104 uint32_t numMsg;
00105 double absoluteError;
00106 double relativeError;
00107 uint32_t numRttErrorToHigh;
00108 uint32_t numRttErrorToLow;
00109 uint32_t rttHistory;
00110 double timeoutAccuracyLimit;
00111
00112 struct WaitingContext
00113 {
00114 WaitingContext() { proxListener = NULL; proxContext = NULL; };
00115 WaitingContext(ProxListener* listener,
00116 cPolymorphic* context,
00117 uint32_t id)
00118 : proxListener(listener), proxContext(context), id(id) { };
00119 ProxListener* proxListener;
00120 cPolymorphic* proxContext;
00121 uint32_t id;
00122 };
00123 typedef std::vector<WaitingContext> WaitingContexts;
00124
00125
00126 bool insertNodeContext(const TransportAddress& handle,
00127 cPolymorphic* context,
00128 ProxListener* rpcListener,
00129 int rpcId);
00130
00131 NeighborCache::WaitingContexts getNodeContexts(const TransportAddress& handle);
00132
00133 enum NeighborCacheRttState {
00134 RTTSTATE_VALID,
00135 RTTSTATE_UNKNOWN,
00136 RTTSTATE_TIMEOUT,
00137 RTTSTATE_WAITING
00138 };
00139
00140 typedef std::pair<simtime_t, NeighborCacheRttState> Rtt;
00141
00142 Rtt getNodeRtt(const TransportAddress& add);
00143
00144 static const double RTT_TIMEOUT_ADJUSTMENT = 1.3;
00145 static const double NCS_TIMEOUT_CONSTANT = 0.25;
00146
00147 protected:
00148 GlobalStatistics* globalStatistics;
00149
00150 struct NeighborCacheEntry {
00151 NeighborCacheEntry() { insertTime = simTime();
00152 rttState = RTTSTATE_UNKNOWN;
00153 coordsInfo = NULL; };
00154
00155 ~NeighborCacheEntry() {
00156 delete coordsInfo;
00157 for (uint16_t i = 0; i < waitingContexts.size(); ++i) {
00158 delete waitingContexts[i].proxContext;
00159 }
00160 };
00161
00162 simtime_t insertTime;
00163 simtime_t rtt;
00164 NeighborCacheRttState rttState;
00165 std::deque<simtime_t> lastRtts;
00166 NodeHandle nodeRef;
00167 NodeHandle srcRoute;
00168 AbstractNcsNodeInfo* coordsInfo;
00169
00170 WaitingContexts waitingContexts;
00171 };
00172
00173 UNORDERED_MAP<TransportAddress, NeighborCacheEntry> neighborCache;
00174 typedef UNORDERED_MAP<TransportAddress, NeighborCacheEntry>::iterator NeighborCacheIterator;
00175 typedef UNORDERED_MAP<TransportAddress, NeighborCacheEntry>::const_iterator NeighborCacheConstIterator;
00176
00177 std::multimap<simtime_t, TransportAddress> neighborCacheExpireMap;
00178 typedef std::multimap<simtime_t, TransportAddress>::iterator neighborCacheExpireMapIterator;
00179
00180 void initializeApp(int stage);
00181
00182 void finishApp();
00183
00184 virtual CompType getThisCompType() { return NEIGHBORCACHE_COMP; };
00185
00186 void handleReadyMessage(CompReadyMessage* readyMsg);
00187
00188 void handleTimerEvent(cMessage* msg);
00189
00196 void queryProx(const TransportAddress &node,
00197 int rpcId,
00198 ProxListener *listener,
00199 cPolymorphic *contextPointer);
00200
00204 bool handleRpcCall(BaseCallMessage* msg);
00205
00206 simtime_t getRttBasedTimeout(const NodeHandle &node);
00207 simtime_t getNcsBasedTimeout(const NodeHandle &node);
00208
00209 public:
00210 ~NeighborCache();
00211
00212 inline bool isEnabled() { return enableNeighborCache; };
00213
00214 bool sendBackOwnCoords() { return (ncsSendBackOwnCoords && ncs != NULL); };
00215
00216 const AbstractNcs& getNcsAccess() const {
00217 if (!ncs) throw cRuntimeError("No NCS activated");
00218 else return *ncs;
00219 };
00220
00221 const NodeHandle& getOverlayThisNode() { return overlay->getThisNode(); };
00222
00223 uint16_t getNeighborCacheSize() { return neighborCache.size(); };
00224
00225
00226 bool isEntry(const TransportAddress& node);
00227 simtime_t getNodeAge(const TransportAddress& handle);
00228 const NodeHandle& getNodeHandle(const TransportAddress &add);
00229
00236 simtime_t getNodeTimeout(const NodeHandle &node);
00237
00238
00239 TransportAddress getNearestNode(uint8_t maxLayer);
00240 double getAvgAbsPredictionError();
00241
00242
00243 void updateNode(const NodeHandle &add, simtime_t rtt,
00244 const NodeHandle& srcRoute = NodeHandle::UNSPECIFIED_NODE,
00245 AbstractNcsNodeInfo* ncsInfo = NULL);
00246 void updateNcsInfo(const TransportAddress& node,
00247 AbstractNcsNodeInfo* ncsInfo);
00248 void setNodeTimeout(const TransportAddress& handle);
00249
00271 Prox getProx(const TransportAddress &node,
00272 NeighborCacheQueryType type = NEIGHBORCACHE_AVAILABLE,
00273 int rpcId = -1,
00274 ProxListener *listener = NULL,
00275 cPolymorphic *contextPointer = NULL);
00276
00284 Prox estimateProx(const TransportAddress &node);
00285
00292 const AbstractNcsNodeInfo* getNodeCoordsInfo(const TransportAddress &node);
00293
00294
00295
00296
00297
00298
00299 std::pair<simtime_t, simtime_t> getMeanVarRtt(const TransportAddress &node,
00300 bool returnVar);
00301
00302 friend std::ostream& operator<<(std::ostream& os,
00303 const NeighborCacheEntry& entry);
00304 };
00305
00306 #endif
00307