NeighborCache.h

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 // Prox stuff
00050 enum NeighborCacheQueryType {
00051     NEIGHBORCACHE_AVAILABLE,     //< RTT, timeout, or unknown (no query)
00052     NEIGHBORCACHE_EXACT,         //< RTT or query
00053     NEIGHBORCACHE_EXACT_TIMEOUT, //< RTT, timeout, or query
00054     NEIGHBORCACHE_ESTIMATED,     //< RTT or estimated
00055     NEIGHBORCACHE_QUERY,         //< only query, return unknown
00056     // default
00057     NEIGHBORCACHE_DEFAULT,       //< available, exact, exact_timeout or estimated
00058     NEIGHBORCACHE_DEFAULT_IMMEDIATELY, //< return a result immediately (available or estimated)
00059     NEIGHBORCACHE_DEFAULT_QUERY  //< do a query if needed (exact, exact_timeout, or 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     // parameters
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     //Stuff needed to calculate a mean RTT to a specific node
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     // ping context stuff
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     // getter for specific node information
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     // getter for general node information
00235     TransportAddress getNearestNode(uint8_t maxLayer);
00236     double getAvgAbsPredictionError();
00237 
00238     // setter for specific node information
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     //calculate mean RTT to a specific node
00291     //simtime_t getMeanRtt(const TransportAddress &node);
00292     //calculate variance of the RTT to a specific node
00293     //double getVarRtt(const TransportAddress &node, simtime_t &meanRtt);
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 
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3