Classes | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | Friends

NeighborCache Class Reference

#include <NeighborCache.h>

Inheritance diagram for NeighborCache:
BaseApp BaseRpc BaseTcpSupport RpcListener

List of all members.

Classes

struct  NeighborCacheEntry
struct  WaitingContext

Public Member Functions

 ~NeighborCache ()
bool isEnabled ()
bool sendBackOwnCoords ()
const AbstractNcsgetNcsAccess () const
const NodeHandlegetOverlayThisNode ()
uint16_t getNeighborCacheSize ()
bool isEntry (const TransportAddress &node)
simtime_t getNodeAge (const TransportAddress &handle)
const NodeHandlegetNodeHandle (const TransportAddress &add)
simtime_t getNodeTimeout (const NodeHandle &node)
 Caclulation of reasonable timout value.
TransportAddress getNearestNode (uint8_t maxLayer)
double getAvgAbsPredictionError ()
void updateNode (const NodeHandle &add, simtime_t rtt, const NodeHandle &srcRoute=NodeHandle::UNSPECIFIED_NODE, AbstractNcsNodeInfo *ncsInfo=NULL)
void updateNcsInfo (const TransportAddress &node, AbstractNcsNodeInfo *ncsInfo)
void setNodeTimeout (const TransportAddress &handle)
Prox getProx (const TransportAddress &node, NeighborCacheQueryType type=NEIGHBORCACHE_AVAILABLE, int rpcId=-1, ProxListener *listener=NULL, cPolymorphic *contextPointer=NULL)
 Gets the proximity of a node.
Prox estimateProx (const TransportAddress &node)
 Estimates a Prox value of node, in relation to this node, based on information collected by the overlay.
const AbstractNcsNodeInfogetNodeCoordsInfo (const TransportAddress &node)
 Returns the coordinate information of a node.
std::pair< simtime_t, simtime_t > getMeanVarRtt (const TransportAddress &node, bool returnVar)

Protected Types

typedef UNORDERED_MAP
< TransportAddress,
NeighborCacheEntry >::iterator 
NeighborCacheIterator
typedef UNORDERED_MAP
< TransportAddress,
NeighborCacheEntry >
::const_iterator 
NeighborCacheConstIterator
typedef std::multimap
< simtime_t, TransportAddress >
::iterator 
neighborCacheExpireMapIterator

Protected Member Functions

void initializeApp (int stage)
 initializes derived class-attributes
void finishApp ()
 collects statistical data of derived app
virtual CompType getThisCompType ()
void handleReadyMessage (CompReadyMessage *readyMsg)
 method to handle ready messages from the overlay
void handleTimerEvent (cMessage *msg)
void queryProx (const TransportAddress &node, int rpcId, ProxListener *listener, cPolymorphic *contextPointer)
 Sends a pingNode call based on parameters from a getProx call.
bool handleRpcCall (BaseCallMessage *msg)
 Coord / RTT measuring rpc stuff goes here.
simtime_t getRttBasedTimeout (const NodeHandle &node)
simtime_t getNcsBasedTimeout (const NodeHandle &node)

Protected Attributes

GlobalStatisticsglobalStatistics
 pointer to GlobalStatistics module in this node
UNORDERED_MAP
< TransportAddress,
NeighborCacheEntry
neighborCache
std::multimap< simtime_t,
TransportAddress
neighborCacheExpireMap

Private Types

enum  NeighborCacheRttState { RTTSTATE_VALID, RTTSTATE_UNKNOWN, RTTSTATE_TIMEOUT, RTTSTATE_WAITING }
typedef std::vector
< WaitingContext
WaitingContexts
typedef std::pair< simtime_t,
NeighborCacheRttState
Rtt

Private Member Functions

bool cleanupCache ()
void updateEntry (const TransportAddress &address, simtime_t insertTime)
Prox getCoordinateBasedProx (const TransportAddress &node)
void calcRttError (const NodeHandle &handle, simtime_t rtt)
bool insertNodeContext (const TransportAddress &handle, cPolymorphic *context, ProxListener *rpcListener, int rpcId)
NeighborCache::WaitingContexts getNodeContexts (const TransportAddress &handle)
Rtt getNodeRtt (const TransportAddress &add)

Private Attributes

bool enableNeighborCache
bool doDiscovery
simtime_t rttExpirationTime
uint32_t maxSize
uint32_t misses
uint32_t hits
AbstractNcsncs
bool ncsSendBackOwnCoords
NeighborCacheQueryType defaultQueryType
NeighborCacheQueryType defaultQueryTypeI
NeighborCacheQueryType defaultQueryTypeQ
cMessage * landmarkTimer
std::map< TransportAddress,
std::vector< double > > 
lastAbsoluteErrorPerNode
uint32_t numMsg
double absoluteError
double relativeError
uint32_t numRttErrorToHigh
uint32_t numRttErrorToLow
uint32_t rttHistory
double timeoutAccuracyLimit

Static Private Attributes

static const std::vector< double > coordsDummy
static const double RTT_TIMEOUT_ADJUSTMENT = 1.3
static const double NCS_TIMEOUT_CONSTANT = 0.25

Friends

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

Detailed Description

Definition at line 69 of file NeighborCache.h.


Member Typedef Documentation

typedef UNORDERED_MAP<TransportAddress, NeighborCacheEntry>::const_iterator NeighborCache::NeighborCacheConstIterator [protected]

Definition at line 175 of file NeighborCache.h.

typedef std::multimap<simtime_t, TransportAddress>::iterator NeighborCache::neighborCacheExpireMapIterator [protected]

Definition at line 178 of file NeighborCache.h.

typedef UNORDERED_MAP<TransportAddress, NeighborCacheEntry>::iterator NeighborCache::NeighborCacheIterator [protected]

Definition at line 174 of file NeighborCache.h.

typedef std::pair<simtime_t, NeighborCacheRttState> NeighborCache::Rtt [private]

Definition at line 140 of file NeighborCache.h.

typedef std::vector<WaitingContext> NeighborCache::WaitingContexts [private]

Definition at line 123 of file NeighborCache.h.


Member Enumeration Documentation

Enumerator:
RTTSTATE_VALID 
RTTSTATE_UNKNOWN 
RTTSTATE_TIMEOUT 
RTTSTATE_WAITING 

Definition at line 133 of file NeighborCache.h.

                               {
        RTTSTATE_VALID,
        RTTSTATE_UNKNOWN,
        RTTSTATE_TIMEOUT,
        RTTSTATE_WAITING
    };


Constructor & Destructor Documentation

NeighborCache::~NeighborCache (  ) 

Definition at line 166 of file NeighborCache.cc.

{
    delete ncs;
}


Member Function Documentation

void NeighborCache::calcRttError ( const NodeHandle handle,
simtime_t  rtt 
) [private]

Definition at line 740 of file NeighborCache.cc.

Referenced by updateNode().

{
    if (!ncs) return;

    // Check if data collection can start
    if (!globalStatistics->isMeasuring()) return;

    Prox prox = getCoordinateBasedProx(handle);
    if (prox == Prox::PROX_UNKNOWN) return;

    //calculate absolute rtt error of the last message
    double tempRttError = prox.proximity - SIMTIME_DBL(rtt);

    if (tempRttError < 0){
        tempRttError *= -1;
        ++numRttErrorToLow;
    } else ++numRttErrorToHigh;

    numMsg++;
    absoluteError += tempRttError;
    relativeError += tempRttError / SIMTIME_DBL(rtt);

    globalStatistics->recordOutVector("NCS: absolute Rtt Error",
                                      tempRttError);
    globalStatistics->recordOutVector("NCS: relative Rtt Error",
                                      (tempRttError / SIMTIME_DBL(rtt)));
}

bool NeighborCache::cleanupCache (  )  [private]

Definition at line 416 of file NeighborCache.cc.

Referenced by insertNodeContext(), queryProx(), setNodeTimeout(), updateNcsInfo(), and updateNode().

{
    bool result = false;
    uint32_t size = neighborCache.size();

    if (size > maxSize) {
        neighborCacheExpireMapIterator it;
        for (uint32_t i = 0; i < (size - (maxSize / 2)); ++i) {
            it = neighborCacheExpireMap.begin();
            if ((neighborCache[it->second].rttState == RTTSTATE_WAITING) ||
                (neighborCache[it->second].insertTime == simTime())) {
                break;
            }
            neighborCache.erase(it->second);
            neighborCacheExpireMap.erase(it);
            result = true;
        }
    }
    assert(neighborCache.size() == neighborCacheExpireMap.size());
    return result;
}

Prox NeighborCache::estimateProx ( const TransportAddress node  ) 

Estimates a Prox value of node, in relation to this node, based on information collected by the overlay.

Parameters:
node The node whose proximity will be requested.
Returns:
The RTT value if one is found in the cache, or else a Prox estimate.

Definition at line 680 of file NeighborCache.cc.

Referenced by getProx().

{
    Enter_Method("estimateProx()");

    Rtt rtt = getNodeRtt(node);

    if (rtt.second != RTTSTATE_UNKNOWN) return rtt.first;

    if (ncs && neighborCache.count(node)) {
        return getCoordinateBasedProx(node);
    }

    return Prox::PROX_UNKNOWN;
}

void NeighborCache::finishApp (  )  [protected, virtual]

collects statistical data of derived app

Reimplemented from BaseApp.

Definition at line 143 of file NeighborCache.cc.

{
    if ((misses + hits) != 0) {
        globalStatistics
            ->addStdDev("NeighborCache: Ping hit rate",
                        ((double)hits / (double)(misses + hits)));
    }

    if (ncs && numMsg > 0) {
        globalStatistics->addStdDev("NeighborCache: NCS absolute RTT error",
                                    absoluteError / (double)numMsg);
        globalStatistics->addStdDev("NeighborCache: NCS relative RTT error",
                                    relativeError / (double)numMsg);
        globalStatistics->addStdDev("NeighborCache: number of messages/s",
                                    numMsg / SIMTIME_DBL(simTime() - creationTime));
        globalStatistics->addStdDev("NeighborCache: NCS percentage of RTT errors to high",
                                    (double)numRttErrorToHigh / (double)numMsg);
        globalStatistics->addStdDev("NeighborCache: NCS percentage of RTT errors to low",
                                    (double)numRttErrorToLow / (double)numMsg);
    }
}

double NeighborCache::getAvgAbsPredictionError (  ) 

Definition at line 481 of file NeighborCache.cc.

Referenced by SVivaldi::calcError().

{
    /*
    //TODO retain and consider the last measured RTTs not the last error(s)
    double absoluteDiff = 0.0;
    uint32_t numNeighbors = 0;

    for (std::map<TransportAddress, std::vector<double> >::iterator it =
        lastAbsoluteErrorPerNode.begin(); it != lastAbsoluteErrorPerNode.end();
        it++) {
        double tempAbsoluteDiff = 0.0;
        for (uint32_t i = 0; i < it->second.size(); i++) {
            tempAbsoluteDiff += it->second.at(i);
        }
        absoluteDiff += (tempAbsoluteDiff / it->second.size());
        numNeighbors++;
    }

    absoluteDiff /= numNeighbors;
    return (absoluteDiff > 1.0) ? 1.0 : absoluteDiff;
     */

    // old version
    //if (neighborCache.size() < 2 || sampleSize == 0) return 1.0;

    double absoluteDiff = 0;
    uint32_t numNeighbors = 0;
    uint32_t sampleSize = 32; //test

    for (std::map<simtime_t, TransportAddress>::reverse_iterator it =
         neighborCacheExpireMap.rbegin();
         it != neighborCacheExpireMap.rend() &&
         numNeighbors < sampleSize; ++it) {
        NeighborCacheEntry& cacheEntry = neighborCache[it->second];

        double dist = ncs->getOwnNcsInfo().getDistance(*cacheEntry.coordsInfo);

        if (dist != 0 && cacheEntry.rttState == RTTSTATE_VALID) {
            double predictionError = fabs(dist - SIMTIME_DBL(cacheEntry.rtt));

            //test: error weighted
            //if (it->second.coordErr < 1) {
            //    predictionError /= it->second.coordErr;
            //}
            //test: age weighted
            //if ((simTime() - it->second.insertTime) > 1) {
            //    predictionError /= (simTime() - it->second.insertTime);
            //}

            numNeighbors++;
            absoluteDiff += predictionError;
        }
    }
    assert(numNeighbors != 0);
    absoluteDiff /= numNeighbors;

    return (absoluteDiff > 1.0) ? 1.0 : absoluteDiff;
}

Prox NeighborCache::getCoordinateBasedProx ( const TransportAddress node  )  [private]

Definition at line 720 of file NeighborCache.cc.

Referenced by calcRttError(), and estimateProx().

{
    if (ncs && isEntry(node)) {
        const AbstractNcsNodeInfo* temp = getNodeCoordsInfo(node);
        if (temp) return ncs->getCoordinateBasedProx(*temp);
    }
    return Prox::PROX_UNKNOWN;
}

std::pair< simtime_t, simtime_t > NeighborCache::getMeanVarRtt ( const TransportAddress node,
bool  returnVar 
)

Definition at line 769 of file NeighborCache.cc.

Referenced by getRttBasedTimeout().

{
    if (neighborCache.count(node) == 0) {
        throw cRuntimeError("NeighborCache.cc: getMeanVarRtt was asked for"
                            "a non-existent node reference.");
    }

    uint16_t size = neighborCache[node].lastRtts.size();
    if (size == 0) return std::make_pair(-1.0,-1.0);

    simtime_t rttSum = 0;
    for (int i = 0; i < size; i++){
        rttSum += neighborCache[node].lastRtts[i];
    }
    simtime_t meanRtt = rttSum / size;
    if (!returnVar) {
        return std::make_pair(meanRtt, -1.0);
    }
    if (size == 1) {
        return std::make_pair(meanRtt, 0.0);
    }

    double sum = 0.0;
    for (int i = 0; i < size; i++){
        simtime_t tempRtt = neighborCache[node].lastRtts.at(i) - meanRtt;
        sum += (SIMTIME_DBL(tempRtt) * SIMTIME_DBL(tempRtt));
    }

    return std::make_pair(meanRtt, (sum / size));
}

const AbstractNcs& NeighborCache::getNcsAccess (  )  const [inline]

Definition at line 216 of file NeighborCache.h.

Referenced by Landmark::finishApp(), CBRDHT::handleGetCAPIRequest(), Landmark::initializeApp(), BaseRpc::internalHandleRpcMessage(), and BaseRpc::sendRpcResponse().

                                            {
        if (!ncs) throw cRuntimeError("No NCS activated");
        else return *ncs;
    };

simtime_t NeighborCache::getNcsBasedTimeout ( const NodeHandle node  )  [protected]

Definition at line 838 of file NeighborCache.cc.

Referenced by getNodeTimeout().

{
    double timeout = -1;
    Prox prox = Prox::PROX_UNKNOWN;

    // check if an entry is available in NeighborCache
    if (isEntry(node)) {
        prox = getProx(node, NEIGHBORCACHE_ESTIMATED);

        if (prox != Prox::PROX_UNKNOWN  && prox != Prox::PROX_TIMEOUT &&
            prox.proximity > 0 && prox.accuracy > timeoutAccuracyLimit) {
            timeout = prox.proximity + (6 * (1 - prox.accuracy));
            timeout += NCS_TIMEOUT_CONSTANT;
        } else return -1;

        if (/*timeout > SIMTIME_DBL(defaultTimeout) ||*/ timeout < 0)
            return -1;
    }
    return timeout;
}

TransportAddress NeighborCache::getNearestNode ( uint8_t  maxLayer  ) 

Definition at line 452 of file NeighborCache.cc.

{
    TransportAddress nearestNode = TransportAddress::UNSPECIFIED_NODE;
    simtime_t nearestNodeRtt = MAXTIME;
    NeighborCacheIterator it;

    for(it = neighborCache.begin(); it != neighborCache.end(); it++ ) {
        if (it->second.rtt < nearestNodeRtt &&
            it->second.rtt > 0 /*&&
            it->second.coordsInfo.npsLayer < maxLayer+1 &&
            it->second.coordsInfo.npsLayer > 0*/) {
            nearestNode.setIp(it->first.getIp());
            nearestNodeRtt = it->second.rtt;
            nearestNode.setPort(it->second.nodeRef.getPort());
        }
    }

    return nearestNode;
}

uint16_t NeighborCache::getNeighborCacheSize (  )  [inline]

Definition at line 223 of file NeighborCache.h.

{ return neighborCache.size(); };

simtime_t NeighborCache::getNodeAge ( const TransportAddress handle  ) 
NeighborCache::WaitingContexts NeighborCache::getNodeContexts ( const TransportAddress handle  )  [private]

Definition at line 216 of file NeighborCache.cc.

Referenced by setNodeTimeout(), and updateNode().

{
    if (neighborCache.count(handle) == 0)
        throw cRuntimeError("NeighborCache error!");
    WaitingContexts temp = neighborCache[handle].waitingContexts;
    neighborCache[handle].waitingContexts.clear();

    return temp;
}

const AbstractNcsNodeInfo * NeighborCache::getNodeCoordsInfo ( const TransportAddress node  ) 

Returns the coordinate information of a node.

Parameters:
node The node whose coordinate information will be requested.
Returns:
The coordinate information.

Definition at line 730 of file NeighborCache.cc.

Referenced by Nps::coordsReqRpcResponse(), and getCoordinateBasedProx().

{
    if (neighborCache.count(node) == 0) {
        throw cRuntimeError("NeighborCache.cc: getNodeCoords was asked for "
                            "a non-existent node reference.");
    }
    return neighborCache[node].coordsInfo;
}

const NodeHandle & NeighborCache::getNodeHandle ( const TransportAddress add  ) 

Definition at line 406 of file NeighborCache.cc.

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

NeighborCache::Rtt NeighborCache::getNodeRtt ( const TransportAddress add  )  [private]

Definition at line 380 of file NeighborCache.cc.

Referenced by Nps::coordsReqRpcResponse(), estimateProx(), and getProx().

{
    // cache disabled or entry not there
    if (!enableNeighborCache ||
        add.isUnspecified() ||
        (neighborCache.count(add) == 0)) {
        misses++;
        return std::make_pair(0.0, RTTSTATE_UNKNOWN);
    }

    NeighborCacheEntry &entry = neighborCache[add];

    if (entry.rttState == RTTSTATE_WAITING ||
        entry.rttState == RTTSTATE_UNKNOWN)
        return std::make_pair(entry.rtt, entry.rttState);
    // entry expired
    if ((simTime() - entry.insertTime) >= rttExpirationTime) {
        entry.rttState = RTTSTATE_UNKNOWN;
        return std::make_pair(entry.rtt, RTTSTATE_UNKNOWN);
    }
    hits++;
    assert(!(entry.rtt == 0.0 && entry.rttState == RTTSTATE_VALID));
    return std::make_pair(entry.rtt, entry.rttState);
}

simtime_t NeighborCache::getNodeTimeout ( const NodeHandle node  ) 

Caclulation of reasonable timout value.

Parameters:
node the node an RPC is sent to
Returns:
recommended timeout value

Definition at line 802 of file NeighborCache.cc.

Referenced by BaseRpc::sendRpcCall().

{
    simtime_t timeout = getRttBasedTimeout(node);
    if (timeout == -1 && ncs) return getNcsBasedTimeout(node);
    return timeout;
}

const NodeHandle& NeighborCache::getOverlayThisNode (  )  [inline]

Definition at line 221 of file NeighborCache.h.

Referenced by SimpleNcs::init().

{ return overlay->getThisNode(); };

Prox NeighborCache::getProx ( const TransportAddress node,
NeighborCacheQueryType  type = NEIGHBORCACHE_AVAILABLE,
int  rpcId = -1,
ProxListener listener = NULL,
cPolymorphic *  contextPointer = NULL 
)

Gets the proximity of a node.

Parameters:
node The node whose proximity will be requested.
type Request type. NEIGHBORCACHE_EXACT looks in the cache, and if no value is found, sends an RTT query to the node. NEIGHBORCACHE_AVAILABLE looks in the cache, and if no value is found returns Prox::PROX_UNKNOWN. NEIGHBORCACHE_ESTIMATED looks in the cache, and if no value is found calculates an estimate based on information collected by the overlay. NEIGHBORCACHE_QUERY always sends an RTT query to the node and returns Prox::PROX_UNKNOWN.
rpcId Identifier sent to the RPC to identify the call.
listener Module to be called back when an RTT response arrives.
contextPointer Pointer sent to the RPC to identify the call. IMPORTANT: contextPointer gets deleted (only) if no Ping call is sent! So, *contextpointer may be undefined!
Returns:
The proximity value of node.

Definition at line 577 of file NeighborCache.cc.

Referenced by BasePastry::determineAliveTable(), getNcsBasedTimeout(), oversim::Chord::handleRpcFixfingersResponse(), Bamboo::lookupFinished(), BasePastry::pingNodes(), BasePastry::prePing(), and Kademlia::routingAdd().

{
    Enter_Method("getProx()");

    if (!enableNeighborCache) {
        queryProx(node, rpcId, listener, contextPointer);
        return Prox::PROX_UNKNOWN;
    }

    if (node == overlay->getThisNode()) {
        delete contextPointer;
        return Prox::PROX_SELF;
    }

    bool sendQuery = false;
    Prox result = Prox::PROX_UNKNOWN;
    Rtt rtt = getNodeRtt(node);

    //countGetProxTotal++;
    if (type == NEIGHBORCACHE_DEFAULT) type = defaultQueryType;
    else if (type == NEIGHBORCACHE_DEFAULT_IMMEDIATELY) type = defaultQueryTypeI;
    else if (type == NEIGHBORCACHE_DEFAULT_QUERY) type = defaultQueryTypeQ;

    switch(type) {
        case NEIGHBORCACHE_EXACT:
            if (rtt.second == RTTSTATE_TIMEOUT) {
                // if timeout, return unknown, and send a query!
                sendQuery = true;
            } else if (rtt.second == RTTSTATE_WAITING) {
                // if a query was sent, return UNKNOWN
                sendQuery = true; //just inserting a context, no real ping is sent
            } else if (rtt.second == RTTSTATE_UNKNOWN) {
                // if no entry known, send a query and return UNKNOWN
                sendQuery = true;
            } else {
                // else, return whatever we have
                result = rtt.first;
            }
            break;
        case NEIGHBORCACHE_EXACT_TIMEOUT:
            if (rtt.second == RTTSTATE_TIMEOUT) {
                // if timeout, return that
                result = Prox::PROX_TIMEOUT;
            } else if (rtt.second == RTTSTATE_WAITING) {
                // if a query was sent, return UNKNOWN
                sendQuery = true; //just inserting a context, no real ping is sent
            } else if (rtt.second == RTTSTATE_UNKNOWN) {
                // if no entry known, send a query and return UNKNOWN
                sendQuery = true;
            } else {
                // else, return whatever we have
                result = rtt.first;
            }
            break;
        case NEIGHBORCACHE_ESTIMATED:
            if (rtt.second == RTTSTATE_TIMEOUT) {
                // if timeout, return that
                result = Prox::PROX_TIMEOUT;
            } else if (rtt.second == RTTSTATE_WAITING) {
                // if a query was sent, return an estimate
                result = estimateProx(node);
            } else if (rtt.second == RTTSTATE_UNKNOWN) {
                // if no entry known, return an estimate
                result = estimateProx(node);
            } else {
                // else return whatever we have
                result = rtt.first;
            }
            break;
        case NEIGHBORCACHE_AVAILABLE:
            if (rtt.second == RTTSTATE_TIMEOUT) {
                // if timeout, return that.
                result = Prox::PROX_TIMEOUT;
            } else if ((rtt.second == RTTSTATE_WAITING) ||
                       (rtt.second == RTTSTATE_UNKNOWN)) {
                // if a query was sent or entry unknown, return UNKNOWN
            } else {
                // else return what we have
                result = rtt.first;
            }
            break;
        case NEIGHBORCACHE_QUERY:
            // simply send a query and return UNKNOWN
            sendQuery = true;
            break;
        default:
            throw cRuntimeError("Unknown query type!");
            break;

    }
    if (sendQuery) {
        if (!insertNodeContext(node, contextPointer, listener, rpcId)) {
            queryProx(node, rpcId, listener, contextPointer);
        }
    } else delete contextPointer;

    return result;
}

simtime_t NeighborCache::getRttBasedTimeout ( const NodeHandle node  )  [protected]

Definition at line 811 of file NeighborCache.cc.

Referenced by getNodeTimeout().

{
    simtime_t timeout = -1;

    // check if an entry is available in NeighborCache
    if (isEntry(node)) {
        std::pair<simtime_t, simtime_t> temp = getMeanVarRtt(node, true);
        simtime_t meanRtt = temp.first;
        simtime_t varRtt = temp.second;

        // TODO return value even if node has timed out
        if (meanRtt == -1) return -1;
        if (varRtt > 0) {
            // like TCP
            timeout = meanRtt + 4 * varRtt;
        } else {
            // only one RTT is available
            timeout = meanRtt * 1.2;
        }
        // adjustment
        timeout *= RTT_TIMEOUT_ADJUSTMENT;
        //if (timeout > SIMTIME_DBL(defaultTimeout)) return -1;
    }
    return timeout;
}

virtual CompType NeighborCache::getThisCompType (  )  [inline, protected, virtual]

Reimplemented from BaseApp.

Definition at line 184 of file NeighborCache.h.

Referenced by Nps::sendCoordsReqCall().

{ return NEIGHBORCACHE_COMP; };

void NeighborCache::handleReadyMessage ( CompReadyMessage msg  )  [protected, virtual]

method to handle ready messages from the overlay

Parameters:
msg message to handle

Reimplemented from BaseApp.

Definition at line 541 of file NeighborCache.cc.

{
    if (readyMsg->getReady() && readyMsg->getComp() == BOOTSTRAPLIST_COMP) {
        if (doDiscovery) {
            //TODO
            // 1. ask bootstrap node for other nodes and his coordinates
            // 2. probe other nodes and optionally ask them for more nodes
            //    (try to get close as well as distant nodes)
            // sendReadyMessage();
        } else {
            sendReadyMessage();
        }
    }
    delete readyMsg;
}

bool NeighborCache::handleRpcCall ( BaseCallMessage msg  )  [protected]

Coord / RTT measuring rpc stuff goes here.

Definition at line 566 of file NeighborCache.cc.

{
    if (ncs) {
        return ncs->handleRpcCall(msg);
    }

    return false;
}

void NeighborCache::handleTimerEvent ( cMessage *  msg  )  [protected]

Definition at line 558 of file NeighborCache.cc.

{
    if (ncs) {
        ncs->handleTimerEvent(msg);
    }
}

void NeighborCache::initializeApp ( int  stage  )  [protected, virtual]

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

Definition at line 67 of file NeighborCache.cc.

{
    if (stage == MAX_STAGE_COMPONENTS) {
        neighborCache.clear();
        WATCH_UNORDERED_MAP(neighborCache);

        enableNeighborCache = par("enableNeighborCache");
        rttExpirationTime = par("rttExpirationTime");
        maxSize = par("maxSize");
        doDiscovery = par("doDiscovery");
        ncsSendBackOwnCoords = par("ncsSendBackOwnCoords");

        // set default query types
        std::string temp = par("defaultQueryType").stdstringValue();
        if (temp == "exact")
            defaultQueryType = NEIGHBORCACHE_EXACT;
        else if (temp == "exact_timeout")
            defaultQueryType = NEIGHBORCACHE_EXACT_TIMEOUT;
        else if (temp == "available")
            defaultQueryType = NEIGHBORCACHE_AVAILABLE;
        else if (temp == "estimated")
            defaultQueryType = NEIGHBORCACHE_ESTIMATED;
        else throw cRuntimeError((std::string("Wrong query type: ")
            + temp).c_str());

        temp = par("defaultQueryTypeI").stdstringValue();
        if (temp == "available")
            defaultQueryTypeI = NEIGHBORCACHE_AVAILABLE;
        else if (temp == "estimated")
            defaultQueryTypeI = NEIGHBORCACHE_ESTIMATED;
        else throw cRuntimeError((std::string("Wrong query type (I): ")
            + temp).c_str());

        temp = par("defaultQueryTypeQ").stdstringValue();
        if (temp == "exact")
            defaultQueryTypeQ = NEIGHBORCACHE_EXACT;
        else if (temp == "exact_timeout")
            defaultQueryTypeQ = NEIGHBORCACHE_EXACT_TIMEOUT;
        else if (temp == "query")
            defaultQueryTypeQ = NEIGHBORCACHE_QUERY;
        else throw cRuntimeError((std::string("Wrong query type (Q): ")
        + temp).c_str());

        temp = par("ncsType").stdstringValue();
        if (temp == "none") ncs = NULL;
        else if (temp == "vivaldi") ncs = new Vivaldi();
        else if (temp == "svivaldi") ncs = new SVivaldi();
        else if (temp == "gnp") ncs = new Nps(); //TODO
        else if (temp == "nps") ncs = new Nps();
        else if (temp == "simple") ncs = new SimpleNcs();
        else throw cRuntimeError((std::string("Wrong NCS type: ")
            + temp).c_str());

        globalStatistics = GlobalStatisticsAccess().get();

        misses = 0;
        hits = 0;

        rttHistory = par("rttHistory");
        timeoutAccuracyLimit = par("timeoutAccuracyLimit");

        numMsg = 0;
        absoluteError = 0.0;
        relativeError = 0.0;
        numRttErrorToHigh = 0;
        numRttErrorToLow = 0;
        lastAbsoluteErrorPerNode.clear();
        WATCH(absoluteError);
        WATCH(relativeError);
        WATCH(numMsg);
    } else if (stage == MIN_STAGE_TIER_1) {
        if (ncs) ncs->init(this);
    }
}

bool NeighborCache::insertNodeContext ( const TransportAddress handle,
cPolymorphic *  context,
ProxListener rpcListener,
int  rpcId 
) [private]

Definition at line 171 of file NeighborCache.cc.

Referenced by getProx().

{
    if (!enableNeighborCache) return false;
    if (neighborCache.count(handle) == 0) {
        NeighborCacheEntry& entry = neighborCache[handle];

        entry.insertTime = simTime();
        entry.rttState = RTTSTATE_WAITING;

        neighborCacheExpireMap.insert(std::make_pair(entry.insertTime,
                                                     handle));

        cleanupCache();

        assert(neighborCache.size() == neighborCacheExpireMap.size());
        return false;
    } else {
        NeighborCacheEntry& entry = neighborCache[handle];

        // waiting?
        if (entry.rttState == RTTSTATE_WAITING) {
            WaitingContext temp(rpcListener, context, rpcId);
            entry.waitingContexts.push_back(temp);

            return true;
        } else {
            if (entry.waitingContexts.size() > 0) {
                throw cRuntimeError("not waiting for response,"
                                    " but additional contexts found!");
            }

            updateEntry(handle, entry.insertTime);

            entry.rttState = RTTSTATE_WAITING;
            entry.insertTime = simTime();

            return false;
        }
    }
}

bool NeighborCache::isEnabled (  )  [inline]

Definition at line 212 of file NeighborCache.h.

Referenced by BasePastry::baseInit().

{ return enableNeighborCache; };

bool NeighborCache::isEntry ( const TransportAddress node  ) 

Definition at line 473 of file NeighborCache.cc.

Referenced by getCoordinateBasedProx(), getNcsBasedTimeout(), and getRttBasedTimeout().

{
    if (neighborCache.count(node) > 0) return true;
    return false;
}

void NeighborCache::queryProx ( const TransportAddress node,
int  rpcId,
ProxListener listener,
cPolymorphic *  contextPointer 
) [protected]

Sends a pingNode call based on parameters from a getProx call.

Parameters:
node The node to which the pingNode call will be sent.
rpcId The rpcId that was passed to getProx.
listener The listener that was passed to getProx.
contextPointer The pointer that was passed to getProx.

Definition at line 695 of file NeighborCache.cc.

Referenced by getProx().

{
    Enter_Method("queryProx()");

    WaitingContext temp(listener, contextPointer, rpcId);

    if (neighborCache.count(node) == 0) {
        NeighborCacheEntry& entry = neighborCache[node];

        entry.waitingContexts.push_back(temp);
        neighborCacheExpireMap.insert(std::make_pair(entry.insertTime, node));
        cleanupCache();
    } else {
        NeighborCacheEntry& entry = neighborCache[node];
        entry.waitingContexts.push_back(temp);
    }
    assert(neighborCache.size() == neighborCacheExpireMap.size());

    // TODO: this ping traffic is accounted application data traffic!
    pingNode(node, -1, 0, NULL, "PING");
}

bool NeighborCache::sendBackOwnCoords (  )  [inline]

Definition at line 214 of file NeighborCache.h.

Referenced by BaseRpc::sendRpcResponse().

{ return (ncsSendBackOwnCoords && ncs != NULL); };

void NeighborCache::setNodeTimeout ( const TransportAddress handle  ) 

Definition at line 227 of file NeighborCache.cc.

Referenced by BaseRpc::internalHandleRpcMessage().

{
    //if (!enableNeighborCache) return;

    if (neighborCache.count(handle) == 0) {
        NeighborCacheEntry& entry = neighborCache[handle];

        entry.insertTime = simTime();
        entry.rttState = RTTSTATE_TIMEOUT;

        neighborCacheExpireMap.insert(std::make_pair(entry.insertTime,
                                                     handle));
        cleanupCache();
    } else {
        NeighborCacheEntry& entry = neighborCache[handle];

        updateEntry(handle, entry.insertTime);

        entry.insertTime = simTime();
        entry.rttState = RTTSTATE_TIMEOUT;

        WaitingContexts waitingContexts = getNodeContexts(handle);

        for (uint32_t i = 0; i < waitingContexts.size(); ++i) {
            assert(waitingContexts[i].proxListener || !waitingContexts[i].proxContext);
            if (waitingContexts[i].proxListener) {
                waitingContexts[i].proxListener->proxCallback(handle,
                                                              waitingContexts[i].id,
                                                              waitingContexts[i].proxContext,
                                                              Prox::PROX_TIMEOUT);
            }
        }
    }
    assert(neighborCache.size() == neighborCacheExpireMap.size());
}

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

Definition at line 439 of file NeighborCache.cc.

Referenced by insertNodeContext(), setNodeTimeout(), updateNcsInfo(), and updateNode().

{
    neighborCacheExpireMapIterator it =
        neighborCacheExpireMap.lower_bound(insertTime);
    while (it->second != address) ++it;
    neighborCacheExpireMap.erase(it);
    neighborCacheExpireMap.insert(std::make_pair(simTime(),
                                                 address));
    assert(neighborCache.size() == neighborCacheExpireMap.size());
}

void NeighborCache::updateNcsInfo ( const TransportAddress node,
AbstractNcsNodeInfo ncsInfo 
)

Definition at line 344 of file NeighborCache.cc.

{
    Enter_Method_Silent();

    EV << "[NeighborCache::updateNcsInfo() @ " << thisNode.getIp()
       << " (" << thisNode.getKey().toString(16) << ")]\n"
       << "    inserting new NcsInfo of node " << node.getIp()
       << endl;

    if (neighborCache.count(node) == 0) {
        NeighborCacheEntry& entry = neighborCache[node];

        entry.insertTime = simTime();
        entry.coordsInfo = ncsInfo;

        neighborCacheExpireMap.insert(std::make_pair(entry.insertTime, node));

        cleanupCache();
    } else {
        updateEntry(node, neighborCache[node].insertTime);

        NeighborCacheEntry& entry = neighborCache[node];

        if (ncsInfo) {
            if (entry.coordsInfo) {
                entry.coordsInfo->update(*ncsInfo);
                delete ncsInfo;
            } else {
                entry.coordsInfo = ncsInfo;
            }
        }
    }
}

void NeighborCache::updateNode ( const NodeHandle add,
simtime_t  rtt,
const NodeHandle srcRoute = NodeHandle::UNSPECIFIED_NODE,
AbstractNcsNodeInfo ncsInfo = NULL 
)

Definition at line 264 of file NeighborCache.cc.

Referenced by Nps::coordsReqRpcResponse(), and BaseRpc::internalHandleRpcMessage().

{
    Enter_Method_Silent();

    EV << "[NeighborCache::updateNode() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    inserting rtt(" << rtt << ") of node " << add.getIp()
           << endl;

    if (rtt <= 0) {
        delete ncsInfo;
        return; //TODO broose
    }

    bool deleteInfo = false;

    //if (enableNeighborCache) {
    if (neighborCache.count(add) == 0) {
        NeighborCacheEntry& entry = neighborCache[add];

        entry.insertTime = simTime();
        entry.rtt = rtt;
        entry.rttState = RTTSTATE_VALID;
        entry.nodeRef = add;
        entry.coordsInfo = ncsInfo;
        entry.lastRtts.push_back(rtt);

        neighborCacheExpireMap.insert(std::make_pair(entry.insertTime, add));

        cleanupCache();
    } else {
        updateEntry(add, neighborCache[add].insertTime);

        NeighborCacheEntry& entry = neighborCache[add];

        entry.insertTime = simTime();
        if (entry.rttState != RTTSTATE_VALID || entry.rtt > rtt)
            entry.rtt = rtt;
        entry.rttState = RTTSTATE_VALID;
        entry.nodeRef = add;

        entry.lastRtts.push_back(rtt);
        if (entry.lastRtts.size()  > rttHistory) {
            entry.lastRtts.pop_front();
        }

        if (ncsInfo) {
            if (entry.coordsInfo) {
                entry.coordsInfo->update(*ncsInfo);
                deleteInfo = true;
            } else {
                entry.coordsInfo = ncsInfo;
            }
        }

        WaitingContexts waitingContexts = getNodeContexts(add);

        for (uint32_t i = 0; i < waitingContexts.size(); ++i) {
            if (waitingContexts[i].proxListener) {
                waitingContexts[i].proxListener
                ->proxCallback(add,
                               waitingContexts[i].id,
                               waitingContexts[i].proxContext,
                               Prox(rtt, 1));
            }
        }
    }
    assert(neighborCache.size() == neighborCacheExpireMap.size());

    calcRttError(add, rtt);

    if (ncs) ncs->processCoordinates(rtt, *ncsInfo);

    // delete ncsInfo if old info is used
    if (deleteInfo) delete ncsInfo;
}


Friends And Related Function Documentation

friend class Nps [friend]

Definition at line 71 of file NeighborCache.h.

Referenced by initializeApp().

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

Definition at line 40 of file NeighborCache.cc.

{
    if (entry.rttState == NeighborCache::RTTSTATE_VALID) {
        os << entry.rtt;
    } else {
        if (entry.rttState == NeighborCache::RTTSTATE_TIMEOUT) os << "TIMEOUT";
        else if (entry.rttState == NeighborCache::RTTSTATE_UNKNOWN) os << "UNKNOWN";
        else if (entry.rttState == NeighborCache::RTTSTATE_WAITING) os << "WAITING";
    }
    os << " (inserted: " << entry.insertTime;

    os << ", #contexts: "
       << entry.waitingContexts.size();

    if (!entry.nodeRef.isUnspecified()) os <<  ", <KEY>";

    //TODO entry.coordsInfo

    os << ")";

    return os;
}


Member Data Documentation

double NeighborCache::absoluteError [private]

Definition at line 105 of file NeighborCache.h.

Referenced by calcRttError(), finishApp(), and initializeApp().

const std::vector< double > NeighborCache::coordsDummy [static, private]

Definition at line 99 of file NeighborCache.h.

Definition at line 91 of file NeighborCache.h.

Referenced by getProx(), and initializeApp().

Definition at line 92 of file NeighborCache.h.

Referenced by getProx(), and initializeApp().

Definition at line 93 of file NeighborCache.h.

Referenced by getProx(), and initializeApp().

Definition at line 76 of file NeighborCache.h.

Referenced by handleReadyMessage(), and initializeApp().

pointer to GlobalStatistics module in this node

Reimplemented from BaseApp.

Definition at line 148 of file NeighborCache.h.

Referenced by calcRttError(), Nps::coordsReqRpcResponse(), finishApp(), and initializeApp().

uint32_t NeighborCache::hits [private]

Definition at line 81 of file NeighborCache.h.

Referenced by finishApp(), getNodeRtt(), and initializeApp().

cMessage* NeighborCache::landmarkTimer [private]

Definition at line 97 of file NeighborCache.h.

std::map<TransportAddress, std::vector<double> > NeighborCache::lastAbsoluteErrorPerNode [private]

Definition at line 103 of file NeighborCache.h.

Referenced by initializeApp().

uint32_t NeighborCache::maxSize [private]

Definition at line 78 of file NeighborCache.h.

Referenced by cleanupCache(), and initializeApp().

uint32_t NeighborCache::misses [private]

Definition at line 80 of file NeighborCache.h.

Referenced by finishApp(), getNodeRtt(), and initializeApp().

const double NeighborCache::NCS_TIMEOUT_CONSTANT = 0.25 [static, private]

Definition at line 145 of file NeighborCache.h.

Referenced by getNcsBasedTimeout().

Definition at line 89 of file NeighborCache.h.

Referenced by initializeApp(), and sendBackOwnCoords().

uint32_t NeighborCache::numMsg [private]

Definition at line 104 of file NeighborCache.h.

Referenced by calcRttError(), finishApp(), and initializeApp().

Definition at line 107 of file NeighborCache.h.

Referenced by calcRttError(), finishApp(), and initializeApp().

uint32_t NeighborCache::numRttErrorToLow [private]

Definition at line 108 of file NeighborCache.h.

Referenced by calcRttError(), finishApp(), and initializeApp().

double NeighborCache::relativeError [private]

Definition at line 106 of file NeighborCache.h.

Referenced by calcRttError(), finishApp(), and initializeApp().

const double NeighborCache::RTT_TIMEOUT_ADJUSTMENT = 1.3 [static, private]

Definition at line 144 of file NeighborCache.h.

Referenced by getRttBasedTimeout().

simtime_t NeighborCache::rttExpirationTime [private]

Definition at line 77 of file NeighborCache.h.

Referenced by getNodeRtt(), and initializeApp().

uint32_t NeighborCache::rttHistory [private]

Definition at line 109 of file NeighborCache.h.

Referenced by initializeApp(), and updateNode().

Definition at line 110 of file NeighborCache.h.

Referenced by getNcsBasedTimeout(), and initializeApp().


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