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

BasePastry Class Reference

#include <BasePastry.h>

Inheritance diagram for BasePastry:
BaseOverlay ProxListener BaseRpc BaseTcpSupport TopologyVis RpcListener Bamboo Pastry

List of all members.

Classes

struct  PingContext

Public Member Functions

virtual ~BasePastry ()
virtual void pingResponse (PingResponse *pingResponse, cPolymorphic *context, int rpcId, simtime_t rtt)
void pingTimeout (PingCall *call, const TransportAddress &dest, cPolymorphic *context, int rpcId)
int getMaxNumSiblings ()
int getMaxNumRedundantNodes ()
virtual void handleAppMessage (BaseOverlayMessage *msg)
 processes messages from application
virtual void updateTooltip ()
 updates information shown in tk-environment
virtual NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg)
virtual void handleStateMessage (PastryStateMessage *msg)=0
 processes state messages, merging with own state tables
virtual void finishOverlay ()
void sendStateTables (const TransportAddress &destination, int type=PASTRY_STATE_STD,...)
 send a PastryStateMessage directly to a node
void sendStateDelayed (const TransportAddress &destination)
 send a standard state message with a small delay
virtual bool isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err)
virtual AbstractLookupcreateLookup (RoutingType routingType=DEFAULT_ROUTING, const BaseOverlayMessage *msg=NULL, const cObject *dummy=NULL, bool appLookup=false)
uint8_t getBitsPerDigit ()
void proxCallback (const TransportAddress &node, int rpcId, cPolymorphic *contextPointer, Prox prox)

Public Attributes

int joins
int joinTries
int joinPartial
int joinSeen
int joinBytesSeen
int joinReceived
int joinBytesReceived
int joinSent
int joinBytesSent
int stateSent
int stateBytesSent
int stateReceived
int stateBytesReceived
int repairReqSent
int repairReqBytesSent
int repairReqReceived
int repairReqBytesReceived
int stateReqSent
int stateReqBytesSent
int stateReqReceived
int stateReqBytesReceived
int totalLookups
int responsibleLookups
int routingTableLookups
int closerNodeLookups
int closerNodeLookupsFromNeighborhood
int leafsetReqSent
int leafsetReqBytesSent
int leafsetReqReceived
int leafsetReqBytesReceived
int leafsetSent
int leafsetBytesSent
int leafsetReceived
int leafsetBytesReceived
int routingTableReqSent
int routingTableReqBytesSent
int routingTableReqReceived
int routingTableReqBytesReceived
int routingTableSent
int routingTableBytesSent
int routingTableReceived
int routingTableBytesReceived
uint32_t rowToAsk

Protected Types

enum  StateObject { ROUTINGTABLE, LEAFSET, NEIGHBORHOODSET }
enum  { PING_RECEIVED_STATE = 1, PING_NEXT_HOP = 2, PING_SINGLE_NODE = 3, PING_DISCOVERY }

Protected Member Functions

virtual void changeState (int toState)
 changes node state
virtual void checkProxCache (void)=0
 checks whether proxCache is complete, takes appropriate actions depending on the protocol state
virtual void purgeVectors (void)
 delete all information/messages caching vectors, used for restarting overlay or finish()
void baseInit (void)
 initializes parameters and variables used in both Bamboo and Pastry
void baseChangeState (int)
 changes node state, but leaves specific behavour, scheduling tasks in particular, to the inheriting protocols
OverlayKey distance (const OverlayKey &x, const OverlayKey &y, bool useAlternative=false) const
virtual void iterativeJoinHook (BaseOverlayMessage *msg, bool incrHopCount)
void prePing (const PastryStateMessage *stateMsg)
 ping all nodes in a given state message.
void pingNodes (void)
 ping all nodes in the pastry state message pointed to by private member stateCache
void determineAliveTable (const PastryStateMessage *stateMsg)
 change the aliveTable to match the given stateMsg.
void sendRequest (const TransportAddress &ask, int type)
 send a request to a given node
void sendLeafset (const TransportAddress &tell, bool pull=false)
 send the leafset to a node
void sendRoutingRow (const TransportAddress &tell, int row)
 send a row of the routing table to a node
void handleRequestMessage (PastryRequestMessage *msg)
 processes state messages, merging with own state tables
void handleLeafsetMessage (PastryLeafsetMessage *msg, bool mergeSender=false)
 processes leafset messages, merging with own state tables
void newLeafs (void)
 Pastry API: send newLeafs() to application if enabled.

Protected Attributes

uint32_t bitsPerDigit
uint32_t numberOfLeaves
uint32_t numberOfNeighbors
double readyWaitAmount
double joinTimeoutAmount
double repairTimeout
bool enableNewLeafs
bool useRegularNextHop
bool alwaysSendUpdate
bool optimizeLookup
bool proximityNeighborSelection
simtime_t nearNodeRtt
uint32_t pingedNodes
bool nearNodeImproved
bool periodicMaintenance
TransportAddressleaf2ask
TransportAddress bootstrapNode
NodeHandle nearNode
simtime_t lastStateChange
PastryStateMsgHandle stateCache
 Handle for processing a single state message.
std::queue< PastryStateMsgHandlestateCacheQueue
 Queue of state messages waiting to be processed in READY state.
PastryStateMsgProximity aliveTable
 Early update of leaf set: helper structure for marking known-dead nodes.
uint32_t joinHopCount
cMessage * joinTimeout
cMessage * readyWait
cMessage * joinUpdateWait
std::vector< PastrySendState * > sendStateWait
PastryRoutingTableroutingTable
PastryLeafSetleafSet
PastryNeighborhoodSetneighborhoodSet

Friends

class PastryLeafSet

Detailed Description

Definition at line 50 of file BasePastry.h.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
PING_RECEIVED_STATE 
PING_NEXT_HOP 
PING_SINGLE_NODE 
PING_DISCOVERY 

Definition at line 295 of file BasePastry.h.

enum BasePastry::StateObject [protected]
Enumerator:
ROUTINGTABLE 
LEAFSET 
NEIGHBORHOODSET 

Definition at line 277 of file BasePastry.h.

    {
        ROUTINGTABLE,
        LEAFSET,
        NEIGHBORHOODSET
    };


Constructor & Destructor Documentation

BasePastry::~BasePastry (  )  [virtual]

Definition at line 997 of file BasePastry.cc.

{
    cancelAndDelete(joinTimeout);

    purgeVectors();
}


Member Function Documentation

void BasePastry::baseChangeState ( int  toState  )  [protected]

changes node state, but leaves specific behavour, scheduling tasks in particular, to the inheriting protocols

Definition at line 196 of file BasePastry.cc.

Referenced by Pastry::changeState(), and Bamboo::changeState().

{
    switch (toState) {
    case INIT:
        state = INIT;

        if (!thisNode.getKey().isUnspecified())
            bootstrapList->removeBootstrapNode(thisNode);

        if (joinTimeout->isScheduled()) cancelEvent(joinTimeout);

        purgeVectors();

        bootstrapNode = bootstrapList->getBootstrapNode();

        routingTable->initializeTable(bitsPerDigit, repairTimeout, thisNode);
        leafSet->initializeSet(numberOfLeaves, bitsPerDigit,
                               repairTimeout, thisNode, this);
        neighborhoodSet->initializeSet(numberOfNeighbors, bitsPerDigit,
                                       thisNode);

        updateTooltip();
        lastStateChange = simTime();

        getParentModule()->getParentModule()->bubble("entering INIT state");

        break;

    case JOINING_2:
        state = JOINING_2;

        // bootstrapNode must be obtained before calling this method,
        // for example by calling changeState(INIT)

        if (bootstrapNode.isUnspecified()) {
            // no existing pastry network -> first node of a new one
            changeState(READY);
            return;
        }

        cancelEvent(joinTimeout);
        scheduleAt(simTime() + joinTimeoutAmount, joinTimeout);

        updateTooltip();
        getParentModule()->getParentModule()->bubble("entering JOIN state");

        RECORD_STATS(joinTries++);

        break;

    case READY:
        assert(state != READY);
        state = READY;

         //bootstrapList->registerBootstrapNode(thisNode);

        // if we are the first node in the network, there's nothing else
        // to do
        if (bootstrapNode.isUnspecified()) {
            RECORD_STATS(joinTries++);
            RECORD_STATS(joins++);
            setOverlayReady(true);
            return;
        }

        getParentModule()->getParentModule()->bubble("entering READY state");
        updateTooltip();
        RECORD_STATS(joins++);

        break;

    default: // discovery
        break;
    }
    setOverlayReady(state == READY);
}

void BasePastry::baseInit ( void   )  [protected]

initializes parameters and variables used in both Bamboo and Pastry

Definition at line 66 of file BasePastry.cc.

Referenced by Pastry::initializeOverlay(), and Bamboo::initializeOverlay().

{
    bitsPerDigit = par("bitsPerDigit");
    numberOfLeaves = par("numberOfLeaves");
    numberOfNeighbors = par("numberOfNeighbors");
    joinTimeoutAmount = par("joinTimeout");
    repairTimeout = par("repairTimeout");
    enableNewLeafs = par("enableNewLeafs");
    optimizeLookup = par("optimizeLookup");
    useRegularNextHop = par("useRegularNextHop");
    alwaysSendUpdate = par("alwaysSendUpdate");
    proximityNeighborSelection = par("proximityNeighborSelection");

    if (!neighborCache->isEnabled()) {
        throw cRuntimeError("NeighborCache is disabled, which is mandatory "
                                "for Pastry/Bamboo. Activate it by setting "
                                "\"**.neighborCache.enableNeighborCache "
                                "= true\" in your omnetpp.ini!");
    }

    if (numberOfLeaves % 2) {
        EV << "[BasePastry::baseInit() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    Warning: numberOfLeaves must be even - adding 1."
           << endl;
        numberOfLeaves++;
    }

    routingTable = check_and_cast<PastryRoutingTable*>
        (getParentModule()->getSubmodule("pastryRoutingTable"));
    leafSet = check_and_cast<PastryLeafSet*>
        (getParentModule()->getSubmodule("pastryLeafSet"));
    neighborhoodSet = check_and_cast<PastryNeighborhoodSet*>
        (getParentModule()->getSubmodule("pastryNeighborhoodSet"));

    stateCache.msg = NULL;
    stateCache.prox = NULL;

    rowToAsk = 0;

    // initialize statistics
    joins = 0;
    joinTries = 0;
    joinPartial = 0;
    joinSeen = 0;
    joinReceived = 0;
    joinSent = 0;
    stateSent = 0;
    stateReceived = 0;
    repairReqSent = 0;
    repairReqReceived = 0;
    stateReqSent = 0;
    stateReqReceived = 0;

    joinBytesSeen = 0;
    joinBytesReceived = 0;
    joinBytesSent = 0;
    stateBytesSent = 0;
    stateBytesReceived = 0;
    repairReqBytesSent = 0;
    repairReqBytesReceived = 0;
    stateReqBytesSent = 0;
    stateReqBytesReceived = 0;

    totalLookups = 0;
    responsibleLookups = 0;
    routingTableLookups = 0;
    closerNodeLookups = 0;
    closerNodeLookupsFromNeighborhood = 0;

    leafsetReqSent = 0;
    leafsetReqBytesSent = 0;
    leafsetReqReceived = 0;
    leafsetReqBytesReceived = 0;
    leafsetSent = 0;
    leafsetBytesSent = 0;
    leafsetReceived = 0;
    leafsetBytesReceived = 0;

    routingTableReqSent = 0;
    routingTableReqBytesSent = 0;
    routingTableReqReceived = 0;
    routingTableReqBytesReceived = 0;
    routingTableSent = 0;
    routingTableBytesSent = 0;
    routingTableReceived = 0;
    routingTableBytesReceived = 0;

    WATCH(joins);
    WATCH(joinTries);
    WATCH(joinSeen);
    WATCH(joinBytesSeen);
    WATCH(joinReceived);
    WATCH(joinBytesReceived);
    WATCH(joinSent);
    WATCH(joinBytesSent);
    WATCH(stateSent);
    WATCH(stateBytesSent);
    WATCH(stateReceived);
    WATCH(stateBytesReceived);
    WATCH(repairReqSent);
    WATCH(repairReqBytesSent);
    WATCH(repairReqReceived);
    WATCH(repairReqBytesReceived);
    WATCH(stateReqSent);
    WATCH(stateReqBytesSent);
    WATCH(stateReqReceived);
    WATCH(stateReqBytesReceived);
    WATCH(lastStateChange);

    WATCH(leafsetReqSent);
    WATCH(leafsetReqBytesSent);
    WATCH(leafsetReqReceived);
    WATCH(leafsetReqBytesReceived);
    WATCH(leafsetSent);
    WATCH(leafsetBytesSent);
    WATCH(leafsetReceived);
    WATCH(leafsetBytesReceived);

    WATCH(routingTableReqSent);
    WATCH(routingTableReqBytesSent);
    WATCH(routingTableReqReceived);
    WATCH(routingTableReqBytesReceived);
    WATCH(routingTableSent);
    WATCH(routingTableBytesSent);
    WATCH(routingTableReceived);
    WATCH(routingTableBytesReceived);
}

void BasePastry::changeState ( int  toState  )  [protected, virtual]

changes node state

Parameters:
toState state to change to

Reimplemented in Pastry.

Definition at line 289 of file BasePastry.cc.

Referenced by baseChangeState().

{

}

virtual void BasePastry::checkProxCache ( void   )  [protected, pure virtual]

checks whether proxCache is complete, takes appropriate actions depending on the protocol state

Implemented in Pastry.

Referenced by pingNodes(), pingResponse(), pingTimeout(), and proxCallback().

AbstractLookup * BasePastry::createLookup ( RoutingType  routingType = DEFAULT_ROUTING,
const BaseOverlayMessage msg = NULL,
const cObject *  dummy = NULL,
bool  appLookup = false 
) [virtual]

Definition at line 1212 of file BasePastry.cc.

Referenced by Bamboo::doGlobalTuning().

{
    assert(dummy == NULL);
    PastryFindNodeExtData* findNodeExt =
        new PastryFindNodeExtData("findNodeExt");

    if (msg) {
        const PastryMessage* pmsg =
            dynamic_cast<const PastryMessage*>(msg->getEncapsulatedPacket());
        if ((pmsg) && (pmsg->getPastryMsgType() == PASTRY_MSG_JOIN)) {
            const PastryJoinMessage* jmsg =
                check_and_cast<const PastryJoinMessage*>(pmsg);
            findNodeExt->setSendStateTo(jmsg->getSendStateTo());
            findNodeExt->setJoinHopCount(1);
        }
    }
    findNodeExt->setBitLength(PASTRYFINDNODEEXTDATA_L);

    AbstractLookup* newLookup = BaseOverlay::createLookup(routingType,
                                                          msg, findNodeExt,
                                                          appLookup);

    delete findNodeExt;
    return newLookup;
}

void BasePastry::determineAliveTable ( const PastryStateMessage stateMsg  )  [protected]

change the aliveTable to match the given stateMsg.

each node that's knowm to be dead from our neighborCache gets a value of PASTRY_PROX_INFINITE, all other nodes just get a value of 1

Definition at line 537 of file BasePastry.cc.

Referenced by Pastry::handleStateMessage(), and Bamboo::handleStateMessage().

{
    uint32_t rt_size = stateMsg->getRoutingTableArraySize();
    aliveTable.pr_rt.clear();
    aliveTable.pr_rt.resize(rt_size, 1);

    uint32_t ls_size = stateMsg->getLeafSetArraySize();
    aliveTable.pr_ls.clear();
    aliveTable.pr_ls.resize(ls_size, 1);

    uint32_t ns_size = stateMsg->getNeighborhoodSetArraySize();
    aliveTable.pr_ns.clear();
    aliveTable.pr_ns.resize(ns_size, 1);

    for (uint32_t i = 0; i < rt_size + ls_size + ns_size; i++) {
        const TransportAddress* node;
        std::vector<simtime_t>::iterator tblPos;
        if (i < rt_size) {
            node = &(stateMsg->getRoutingTable(i));
            tblPos = aliveTable.pr_rt.begin() + i;
        } else if ( i < (rt_size + ls_size) ) {
            node = &(stateMsg->getLeafSet(i - rt_size));
            tblPos = aliveTable.pr_ls.begin() + (i - rt_size);
        } else {
            node = &(stateMsg->getNeighborhoodSet(i - rt_size - ls_size));
            tblPos = aliveTable.pr_ns.begin() + (i - rt_size - ls_size);
        }
        if (neighborCache->getProx(*node, NEIGHBORCACHE_DEFAULT_IMMEDIATELY) ==
                Prox::PROX_TIMEOUT) {
            *tblPos = PASTRY_PROX_INFINITE;
        }
    }
}

OverlayKey BasePastry::distance ( const OverlayKey x,
const OverlayKey y,
bool  useAlternative = false 
) const [protected]

Definition at line 1275 of file BasePastry.cc.

{
    if (!useAlternative) return KeyRingMetric().distance(x, y);
    return KeyPrefixMetric().distance(x, y);
}

NodeVector * BasePastry::findNode ( const OverlayKey key,
int  numRedundantNodes,
int  numSiblings,
BaseOverlayMessage msg 
) [virtual]

Definition at line 1100 of file BasePastry.cc.

{
    if ((numRedundantNodes > getMaxNumRedundantNodes()) ||
        (numSiblings > getMaxNumSiblings())) {

        opp_error("(Pastry::findNode()) numRedundantNodes or numSiblings "
                  "too big!");
    }
    RECORD_STATS(totalLookups++);

    NodeVector* nextHops = new NodeVector(numRedundantNodes);

    if (state != READY) {
        return nextHops;
    } else if (key.isUnspecified() || leafSet->isClosestNode(key)) {
        RECORD_STATS(responsibleLookups++);
        nextHops->add(thisNode);
    } else {
        const NodeHandle* next = &(leafSet->getDestinationNode(key));

        if (next->isUnspecified()) {
            next = &(routingTable->lookupNextHop(key));
            if (!next->isUnspecified()) {
                RECORD_STATS(routingTableLookups++);
            }
        } else {
            RECORD_STATS(responsibleLookups++);
        }

        if (next->isUnspecified()) {
            RECORD_STATS(closerNodeLookups++);
            // call findCloserNode() on all state objects
            if (optimizeLookup) {
                const NodeHandle* tmp;
                next = &(routingTable->findCloserNode(key, true));
                tmp = &(neighborhoodSet->findCloserNode(key, true));

                if ((! tmp->isUnspecified()) &&
                    (leafSet->isCloser(*tmp, key, *next))) {
                    RECORD_STATS(closerNodeLookupsFromNeighborhood++);
                    next = tmp;
                }

                tmp = &(leafSet->findCloserNode(key, true));
                if ((! tmp->isUnspecified()) &&
                    (leafSet->isCloser(*tmp, key, *next))) {
                    RECORD_STATS(closerNodeLookupsFromNeighborhood--);
                    next = tmp;
                }
            } else {
                next = &(routingTable->findCloserNode(key));

                if (next->isUnspecified()) {
                    RECORD_STATS(closerNodeLookupsFromNeighborhood++);
                    next = &(neighborhoodSet->findCloserNode(key));
                }

                if (next->isUnspecified()) {
                    RECORD_STATS(closerNodeLookupsFromNeighborhood--);
                    next = &(leafSet->findCloserNode(key));
                }
            }
        }

        iterativeJoinHook(msg, !next->isUnspecified());

        if (!next->isUnspecified()) {
            nextHops->add(*next);
        }
    }

    bool err;

    // if we're a sibling, return all numSiblings
    if ((numSiblings >= 0) && isSiblingFor(thisNode, key, numSiblings, &err)) {
        if (err == false) {
            delete nextHops;
            return  leafSet->createSiblingVector(key, numSiblings);
        }
    }

    if (/*(nextHops->size() > 0) &&*/ (numRedundantNodes > 1)) {

        //memleak... comp should be a ptr and deleted in NodeVector::~NodeVector()...
        //KeyDistanceComparator<KeyRingMetric>* comp =
        //    new KeyDistanceComparator<KeyRingMetric>( key );

        KeyDistanceComparator<KeyRingMetric> comp(key);
        //KeyDistanceComparator<KeyPrefixMetric> comp(key);
        NodeVector* additionalHops = new NodeVector( numRedundantNodes, &comp );

        routingTable->findCloserNodes(key, additionalHops);
        leafSet->findCloserNodes(key, additionalHops);
        neighborhoodSet->findCloserNodes(key, additionalHops);

        if (useRegularNextHop && (nextHops->size() > 0) &&
            (*additionalHops)[0] != (*nextHops)[0]) {
            for (uint32_t i = 0; i < additionalHops->size(); i++) {
                if ((*additionalHops)[i] != (*nextHops)[0])
                    nextHops->push_back((*additionalHops)[i]);
            }
            delete additionalHops;
        } else {
            delete nextHops;
            return additionalHops;
        }
    }
    return nextHops;
}

void BasePastry::finishOverlay (  )  [virtual]

Definition at line 1004 of file BasePastry.cc.

{
    // remove this node from the bootstrap list
    if (!thisNode.getKey().isUnspecified()) bootstrapList->removeBootstrapNode(thisNode);

    // collect statistics
    simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
    if (time < GlobalStatistics::MIN_MEASURED) return;

    // join statistics
    //if (joinTries > joins)
        //std::cout << thisNode << " jt:" << joinTries << " j:" << joins << " jts:"
        //          << joinTimeout->isScheduled() << " rws:" << readyWait->isScheduled()
        //          << " state:" << state << " time:" << time << std::endl;
    // join is on the way...
    if (joinTries > 0 && joinTimeout->isScheduled()) joinTries--;
    if (joinTries > 0) {
        globalStatistics->addStdDev("Pastry: join success ratio", (double)joins / (double)joinTries);
        globalStatistics->addStdDev("Pastry: join tries", joinTries);
    } else if (state == READY) {
        // nodes has joined in init-/transition-phase
        globalStatistics->addStdDev("Pastry: join success ratio", 1);
        globalStatistics->addStdDev("Pastry: join tries", 1);
    } else {
        globalStatistics->addStdDev("Pastry: join success ratio", 0);
        globalStatistics->addStdDev("Pastry: join tries", 1);
    }

    globalStatistics->addStdDev("Pastry: joins with missing replies from routing path/s",
                                joinPartial / time);
    globalStatistics->addStdDev("Pastry: JOIN Messages seen/s", joinSeen / time);
    globalStatistics->addStdDev("Pastry: bytes of JOIN Messages seen/s", joinBytesSeen / time);
    globalStatistics->addStdDev("Pastry: JOIN Messages received/s", joinReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of JOIN Messages received/s",
                                joinBytesReceived / time);
    globalStatistics->addStdDev("Pastry: JOIN Messages sent/s", joinSent / time);
    globalStatistics->addStdDev("Pastry: bytes of JOIN Messages sent/s", joinBytesSent / time);
    globalStatistics->addStdDev("Pastry: STATE Messages sent/s", stateSent / time);
    globalStatistics->addStdDev("Pastry: bytes of STATE Messages sent/s", stateBytesSent / time);
    globalStatistics->addStdDev("Pastry: STATE Messages received/s", stateReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of STATE Messages received/s",
                                stateBytesReceived / time);
    globalStatistics->addStdDev("Pastry: REPAIR Requests sent/s", repairReqSent / time);
    globalStatistics->addStdDev("Pastry: bytes of REPAIR Requests sent/s",
                                repairReqBytesSent / time);
    globalStatistics->addStdDev("Pastry: REPAIR Requests received/s", repairReqReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of REPAIR Requests received/s",
                                repairReqBytesReceived / time);
    globalStatistics->addStdDev("Pastry: STATE Requests sent/s", stateReqSent / time);
    globalStatistics->addStdDev("Pastry: bytes of STATE Requests sent/s", stateReqBytesSent / time);
    globalStatistics->addStdDev("Pastry: STATE Requests received/s", stateReqReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of STATE Requests received/s",
                                stateReqBytesReceived / time);

    globalStatistics->addStdDev("Pastry: bytes of STATE Requests received/s",
                                stateReqBytesReceived / time);

    globalStatistics->addStdDev("Pastry: total number of lookups", totalLookups);
    globalStatistics->addStdDev("Pastry: responsible lookups", responsibleLookups);
    globalStatistics->addStdDev("Pastry: lookups in routing table", routingTableLookups);
    globalStatistics->addStdDev("Pastry: lookups using closerNode()", closerNodeLookups);
    globalStatistics->addStdDev("Pastry: lookups using closerNode() with result from "
                                "neighborhood set", closerNodeLookupsFromNeighborhood);
    globalStatistics->addStdDev("Pastry: LEAFSET Requests sent/s", leafsetReqSent / time);
    globalStatistics->addStdDev("Pastry: bytes of LEAFSET Requests sent/s", leafsetReqBytesSent / time);
    globalStatistics->addStdDev("Pastry: LEAFSET Requests received/s", leafsetReqReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of LEAFSET Requests received/s",
                                leafsetReqBytesReceived / time);
    globalStatistics->addStdDev("Pastry: LEAFSET Messages sent/s", leafsetSent / time);
    globalStatistics->addStdDev("Pastry: bytes of LEAFSET Messages sent/s", leafsetBytesSent / time);
    globalStatistics->addStdDev("Pastry: LEAFSET Messages received/s", leafsetReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of LEAFSET Messages received/s",
                                leafsetBytesReceived / time);
    globalStatistics->addStdDev("Pastry: ROUTING TABLE Requests sent/s", routingTableReqSent / time);
    globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Requests sent/s", routingTableReqBytesSent / time);
    globalStatistics->addStdDev("Pastry: ROUTING TABLE Requests received/s", routingTableReqReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Requests received/s",
                                routingTableReqBytesReceived / time);
    globalStatistics->addStdDev("Pastry: ROUTING TABLE Messages sent/s", routingTableSent / time);
    globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Messages sent/s", routingTableBytesSent / time);
    globalStatistics->addStdDev("Pastry: ROUTING TABLE Messages received/s", routingTableReceived / time);
    globalStatistics->addStdDev("Pastry: bytes of ROUTING TABLE Messages received/s",
                                routingTableBytesReceived / time);

}

uint8_t BasePastry::getBitsPerDigit (  )  [inline]

Definition at line 134 of file BasePastry.h.

{ return bitsPerDigit; };

int BasePastry::getMaxNumRedundantNodes (  ) 

Definition at line 1095 of file BasePastry.cc.

Referenced by findNode().

{
    return (int)floor(numberOfLeaves);
}

int BasePastry::getMaxNumSiblings (  ) 

Definition at line 1090 of file BasePastry.cc.

Referenced by findNode().

{
    return (int)floor(numberOfLeaves / 2.0);
}

void BasePastry::handleAppMessage ( BaseOverlayMessage msg  )  [virtual]

processes messages from application

Parameters:
msg message from application

Definition at line 968 of file BasePastry.cc.

{
    delete msg;
}

void BasePastry::handleLeafsetMessage ( PastryLeafsetMessage msg,
bool  mergeSender = false 
) [protected]

processes leafset messages, merging with own state tables

Parameters:
msg the pastry state message
mergeSender should the sender also be merged

Definition at line 892 of file BasePastry.cc.

Referenced by Pastry::handleUDPMessage(), and Bamboo::handleUDPMessage().

{
    uint32_t lsSize = msg->getLeafSetArraySize();
    PastryStateMessage* stateMsg;

    stateMsg = new PastryStateMessage("STATE");
    stateMsg->setTimestamp(msg->getTimestamp());
    stateMsg->setPastryMsgType(PASTRY_MSG_STATE);
    stateMsg->setStatType(MAINTENANCE_STAT);
    stateMsg->setSender(msg->getSender());
    stateMsg->setLeafSetArraySize(lsSize);
    stateMsg->setNeighborhoodSetArraySize(0);
    stateMsg->setRoutingTableArraySize(0);

    for (uint32_t i = 0; i < lsSize; i++) {
        stateMsg->setLeafSet(i, msg->getLeafSet(i));
    }

    if (mergeSender) {
        stateMsg->setLeafSetArraySize(lsSize+1);
        stateMsg->setLeafSet(lsSize, msg->getSender());
    }

    handleStateMessage(stateMsg);
    delete msg;
}

void BasePastry::handleRequestMessage ( PastryRequestMessage msg  )  [protected]

processes state messages, merging with own state tables

Parameters:
msg the pastry state message

Definition at line 844 of file BasePastry.cc.

Referenced by Pastry::handleUDPMessage(), and Bamboo::handleUDPMessage().

{
    assert(msg->getSendStateTo() != thisNode);
    uint32_t reqtype = msg->getPastryReqType();
    if (reqtype == PASTRY_REQ_REPAIR) {
        RECORD_STATS(repairReqReceived++; repairReqBytesReceived +=
            msg->getByteLength());
        if (state == READY)
            sendStateTables(msg->getSendStateTo(),
                            PASTRY_STATE_REPAIR);
        else
            EV << "[BasePastry::handleRequestMessage() @ " << thisNode.getIp()
            << " (" << thisNode.getKey().toString(16) << ")]\n"
            << "    received repair request before reaching"
            << " READY state, dropping message!"
            << endl;
        delete msg;
    }
    else if (reqtype == PASTRY_REQ_STATE) {
        RECORD_STATS(stateReqReceived++; stateReqBytesReceived +=
            msg->getByteLength());
        if (state == READY)
            sendStateTables(msg->getSendStateTo());
        else
            EV << "[BasePastry::handleRequestMessage() @ " << thisNode.getIp()
            << " (" << thisNode.getKey().toString(16) << ")]\n"
            << "    received state request before reaching"
            << " READY state, dropping message!"
            << endl;
        delete msg;
    }
    else if (PASTRY_REQ_LEAFSET) {
        RECORD_STATS(leafsetReqReceived++; leafsetReqBytesReceived +=
            msg->getByteLength());
        if (state == READY) {
            sendLeafset(msg->getSendStateTo());
        }
        else
            EV << "[BasePastry::handleRequestMessage() @ " << thisNode.getIp()
            << " (" << thisNode.getKey().toString(16) << ")]\n"
            << "    received leafset request before reaching"
            << " READY state, dropping message!"
            << endl;
        delete msg;
    }

}

virtual void BasePastry::handleStateMessage ( PastryStateMessage msg  )  [pure virtual]

processes state messages, merging with own state tables

Parameters:
msg the pastry state message

Implemented in Pastry.

Referenced by handleLeafsetMessage().

bool BasePastry::isSiblingFor ( const NodeHandle node,
const OverlayKey key,
int  numSiblings,
bool *  err 
) [virtual]

Definition at line 919 of file BasePastry.cc.

Referenced by findNode().

{
    if (key.isUnspecified())
        error("Pastry::isSiblingFor(): key is unspecified!");

    if ((numSiblings == 1) && (node == thisNode)) {
        if (leafSet->isClosestNode(key)) {
            *err = false;
            return true;
        } else {
            *err = false;
            return false;
        }
    }

    NodeVector* result =  leafSet->createSiblingVector(key, numSiblings);

    if (result == NULL) {
        *err = true;
        return false;
    }

    if (result->contains(node.getKey())) {
        delete result;
        *err = false;
        return true;
    } else {
        delete result;
        *err = true;
        return false;
    }

    /*
      const NodeHandle& dest = leafSet->getDestinationNode(key);
      if (!dest.isUnspecified()) {
      *err = false;
      return true;
      } else {

      *err = true;
      return false;
      }
    */
}

virtual void BasePastry::iterativeJoinHook ( BaseOverlayMessage msg,
bool  incrHopCount 
) [inline, protected, virtual]

Reimplemented in Pastry.

Definition at line 274 of file BasePastry.h.

Referenced by findNode().

                                                      { };

void BasePastry::newLeafs ( void   )  [protected]

Pastry API: send newLeafs() to application if enabled.

Definition at line 274 of file BasePastry.cc.

Referenced by Pastry::handleFailedNode(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), and Pastry::mergeState().

{
    if (! enableNewLeafs) return;

    PastryNewLeafsMessage* msg = leafSet->getNewLeafsMessage();
    if (msg) {
        send(msg, "appOut");
        EV << "[BasePastry::newLeafs() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    newLeafs() called."
           << endl;
    }
}

void BasePastry::pingNodes ( void   )  [protected]

ping all nodes in the pastry state message pointed to by private member stateCache

Definition at line 472 of file BasePastry.cc.

Referenced by Bamboo::checkProxCache(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), and Pastry::processState().

{
    EV << "[BasePastry::pingNodes() @ " << thisNode.getIp()
       << " (" << thisNode.getKey().toString(16) << ")]" << endl;

    if (stateCache.msg == NULL) throw cRuntimeError("no state msg");

    assert(stateCache.prox == NULL);
    stateCache.prox = new PastryStateMsgProximity();

    uint32_t rt_size = stateCache.msg->getRoutingTableArraySize();
    stateCache.prox->pr_rt.resize(rt_size, PASTRY_PROX_UNDEF);

    uint32_t ls_size = stateCache.msg->getLeafSetArraySize();
    stateCache.prox->pr_ls.resize(ls_size, PASTRY_PROX_UNDEF);

    uint32_t ns_size = stateCache.msg->getNeighborhoodSetArraySize();
    stateCache.prox->pr_ns.resize(ns_size, PASTRY_PROX_UNDEF);

    std::vector< std::pair<const NodeHandle*, PingContext*> > nodesToPing;
    // set prox state
    for (uint32_t i = 0; i < rt_size + ls_size + ns_size; i++) {
        const NodeHandle* node;
        std::vector<simtime_t>::iterator proxPos;
        PingContext* pingContext = NULL;
        StateObject stateObject;
        uint32_t index;
        if (stateCache.msg == NULL) break;
        if (i < rt_size) {
            node = &(stateCache.msg->getRoutingTable(i));
            proxPos = stateCache.prox->pr_rt.begin() + i;
            stateObject = ROUTINGTABLE;
            index = i;
        } else if ( i < (rt_size + ls_size) ) {
            node = &(stateCache.msg->getLeafSet(i - rt_size));
            proxPos = stateCache.prox->pr_ls.begin() + (i - rt_size);
            stateObject = LEAFSET;
            index = i - rt_size;
        } else {
            node = &(stateCache.msg->getNeighborhoodSet(i - rt_size - ls_size));
            proxPos = stateCache.prox->pr_ns.begin() + (i - rt_size - ls_size);
            stateObject = NEIGHBORHOODSET;
            index = i - rt_size - ls_size;
        }
        // proximity is undefined for unspecified nodes:
        if (!node->isUnspecified()) {
            pingContext = new PingContext(stateObject, index,
                                          stateCache.nonce);

            Prox prox = neighborCache->getProx(*node, NEIGHBORCACHE_DEFAULT, -1,
                                               this, pingContext);
            if (prox == Prox::PROX_SELF) {
                *proxPos = 0;
            } else if (prox == Prox::PROX_TIMEOUT) {
                *proxPos = PASTRY_PROX_INFINITE;
            } else if (prox == Prox::PROX_UNKNOWN) {
                *proxPos = PASTRY_PROX_PENDING;
            } else {
                *proxPos = prox.proximity;
            }
        }
    }
    checkProxCache();
}

void BasePastry::pingResponse ( PingResponse pingResponse,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [virtual]

Reimplemented in Pastry.

Definition at line 295 of file BasePastry.cc.

{
    EV << "[BasePastry::pingResponse() @ " << thisNode.getIp()
       << " (" << thisNode.getKey().toString(16) << ")]\n"
       << "    Pong (or Ping-context from NeighborCache) received (from "
       << msg->getSrcNode().getIp() << ")"
       << endl;

    const NodeHandle& src = msg->getSrcNode();
    assert(!src.isUnspecified());

    // merge single pinged nodes (bamboo global tuning)
    if (rpcId == PING_SINGLE_NODE) {
        routingTable->mergeNode(src, proximityNeighborSelection ?
                                     rtt : SimTime::getMaxTime());
        return;
    }

    /*// a node with the an equal ID has responded
    if ((src.getKey() == thisNode.getKey()) && (src.getIp() != thisNode.getIp())) {
        EV << "[BasePastry::pingResponse() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    a node with the an equal ID has responded, rejoining" << endl;
        delete context;
        //joinOverlay();
        return;
    }*/

    if (context != NULL && stateCache.msg && stateCache.prox) {
        PingContext* pingContext = check_and_cast<PingContext*>(context);
        if (pingContext->nonce != stateCache.nonce) {
            delete context;
            return;
            //throw cRuntimeError("response doesn't fit stateCache");
        }
        switch (pingContext->stateObject) {
            case ROUTINGTABLE: {
                /*node = &(stateCache.msg->getRoutingTable(pingContext->index));
                if((node->isUnspecified()) || (*node != src)) {
                    std::cout << simTime() << " " << thisNode.getIp() << " rt: state from "
                              << stateCache.msg->getSender().getIp() << " *** failed: node "
                              << node->ip << " src " << src.getIp() << std::endl;
                    break;
                }*/
                *(stateCache.prox->pr_rt.begin() + pingContext->index) = rtt;
                break;
            }
            case LEAFSET: {
                /*node = &(stateCache.msg->getLeafSet(pingContext->index));
                if ((node->isUnspecified()) || (*node != src)) {
                    std::cout << simTime() << " " << thisNode.getIp() << " ls: state from "
                              << stateCache.msg->getSender().getIp() << " *** failed: node "
                              << node->ip << " src " << src.getIp() << std::endl;
                    break;
                }*/
                *(stateCache.prox->pr_ls.begin() + pingContext->index) = rtt;
                break;
            }
            case NEIGHBORHOODSET: {
                /*node = &(stateCache.msg->getNeighborhoodSet(pingContext->index));
                if((node->isUnspecified()) || (*node != src)) {
                    std::cout << simTime() << " " << thisNode.getIp() << " ns: state from "
                              << stateCache.msg->getSender().getIp() << " *** failed: node "
                              << node->ip << " src " << src.getIp() << std::endl;
                    break;
                }*/
                *(stateCache.prox->pr_ns.begin() + pingContext->index) = rtt;
                break;
            }
            default: {
                throw cRuntimeError("wrong state object type!");
            }
        }
        checkProxCache();
    }
    delete context;
}

void BasePastry::pingTimeout ( PingCall call,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId 
)

Definition at line 661 of file BasePastry.cc.

{
    EV << "[BasePastry::sendStateDelayed() @ " << thisNode.getIp()
       << " (" << thisNode.getKey().toString(16) << ")]\n"
       << "    Ping timeout occurred (" << dest.getIp() << ")"
       << endl;

    // handle failed node
    if (state == READY) {
        handleFailedNode(dest); // TODO
        updateTooltip();

        // this could initiate a re-join, exit the handler in that
        // case because all local data was erased:
        if (state != READY) {
            delete context;
            return;
        }
    }

    //TODO must be removed
    if (context && stateCache.msg && stateCache.prox &&
        rpcId == PING_RECEIVED_STATE) {
        PingContext* pingContext = check_and_cast<PingContext*>(context);
        if (pingContext->nonce != stateCache.nonce) {
            delete context;
            return;
            //std::stringstream temp;
            //temp << thisNode << " timeout/call doesn't fit stateCache";
            //throw cRuntimeError(temp.str().c_str());
        }
        //const NodeHandle* node;
        switch (pingContext->stateObject) {
            case ROUTINGTABLE: {
                /*if (pingContext->index >=
                    stateCache.msg->getRoutingTableArraySize()) {
                    std::cout << "*** FAILED ***" << std::endl;
                    break;
                }
                node = &(stateCache.msg->getRoutingTable(pingContext->index));
                if((node->isUnspecified()) || (dest != *node)) {
                    std::cout << msg->getNonce() << " " << simTime() << " " << thisNode.getIp() << " rt: state from "
                    << stateCache.msg->getSender().getIp() << " *** failed: node "
                    << node->ip << " failed dest " << dest.getIp() << std::endl;
                    break;
                }*/
                *(stateCache.prox->pr_rt.begin() + pingContext->index) =
                    PASTRY_PROX_INFINITE;
                break;
            }
            case LEAFSET: {
                /*if (pingContext->index >=
                    stateCache.msg->getLeafSetArraySize()) {
                    std::cout << "*** FAILED ***" << std::endl;
                    break;
                }
                node = &(stateCache.msg->getLeafSet(pingContext->index));
                if((node->isUnspecified()) || (dest != *node)) {
                    std::cout << msg->getNonce() << " " << simTime() << " " << thisNode.getIp() << " ls: state from "
                    << stateCache.msg->getSender().getIp() << " *** failed: node "
                    << node->ip << " failed dest " << dest.getIp() << std::endl;
                    break;
                }*/
                *(stateCache.prox->pr_ls.begin() + pingContext->index) =
                    PASTRY_PROX_INFINITE;
                break;
            }
            case NEIGHBORHOODSET: {
                /*if (pingContext->index >=
                    stateCache.msg->getNeighborhoodSetArraySize()) {
                    std::cout << "*** FAILED ***" << std::endl;
                    break;
                }
                node = &(stateCache.msg->getNeighborhoodSet(pingContext->index));
                if((node->isUnspecified()) || (dest != *node)) {
                    std::cout << msg->getNonce() << " " << simTime() << " " << thisNode.getIp() << " ns: state from "
                    << stateCache.msg->getSender().getIp() << " *** failed: node "
                    << node->ip << " failed dest " << dest.getIp() << std::endl;
                    break;
                }*/
                *(stateCache.prox->pr_ns.begin() + pingContext->index) =
                    PASTRY_PROX_INFINITE;
                break;
            }
        }
        checkProxCache();
    }

    delete context;
}

void BasePastry::prePing ( const PastryStateMessage stateMsg  )  [protected]

ping all nodes in a given state message.

this is called when a state message arrives while another one is still being processed.

Definition at line 439 of file BasePastry.cc.

Referenced by Pastry::doSecondStage(), Pastry::handleStateMessage(), and Bamboo::handleStateMessage().

{
    uint32_t rt_size = stateMsg->getRoutingTableArraySize();
    uint32_t ls_size = stateMsg->getLeafSetArraySize();
    uint32_t ns_size = stateMsg->getNeighborhoodSetArraySize();

    for (uint32_t i = 0; i < rt_size + ls_size + ns_size; i++) {
        const NodeHandle* node;
        if (i < rt_size) {
            node = &(stateMsg->getRoutingTable(i));
        }
        else if (i < (rt_size + ls_size) ) {
            node = &(stateMsg->getLeafSet(i - rt_size));
        }
        else {
            node = &(stateMsg->getNeighborhoodSet(i - rt_size - ls_size));
        }
        if ((node->isUnspecified()) || (*node == thisNode)) {
            continue;
        }
        /*if (node->key == thisNode.getKey()) {
            cerr << "Pastry Warning: Other node with same key found, "
                "restarting!" << endl;
            opp_error("TODO: Other node with same key found...");
            joinOverlay(); //segfault
            //return;
            continue;
        }*/

        neighborCache->getProx(*node, NEIGHBORCACHE_DEFAULT, PING_RECEIVED_STATE, this, NULL);
    }
}

void BasePastry::proxCallback ( const TransportAddress node,
int  rpcId,
cPolymorphic *  contextPointer,
Prox  prox 
) [virtual]

Implements ProxListener.

Definition at line 375 of file BasePastry.cc.

{
    Enter_Method("proxCallback()");

    EV << "[BasePastry::proxCallback() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    Pong received (from "
           << node.getIp() << ")"
           << endl;

    double rtt = ((prox == Prox::PROX_TIMEOUT) ? PASTRY_PROX_INFINITE
                                               : prox.proximity);

    // merge single pinged nodes (bamboo global tuning)
    if (rpcId == PING_SINGLE_NODE) {
        routingTable->mergeNode((const NodeHandle&)node,
                                proximityNeighborSelection ?
                                rtt : SimTime::getMaxTime());
        delete contextPointer;
        return;
    }

    if (contextPointer != NULL && stateCache.msg && stateCache.prox) {
        PingContext* pingContext = check_and_cast<PingContext*>(contextPointer);

        if (pingContext->nonce != stateCache.nonce) {
            delete contextPointer;
            return;
        }
        // handle failed node
        if (rtt == PASTRY_PROX_INFINITE && state== READY) {
            handleFailedNode(node); // TODO
            updateTooltip();

            // this could initiate a re-join, exit the handler in that
            // case because all local data was erased:
            if (state != READY) {
                delete contextPointer;
                return;
            }
        }
        switch (pingContext->stateObject) {
        case ROUTINGTABLE:
            *(stateCache.prox->pr_rt.begin() + pingContext->index) = rtt;
            break;

        case LEAFSET:
            *(stateCache.prox->pr_ls.begin() + pingContext->index) = rtt;
            break;

        case NEIGHBORHOODSET:
            *(stateCache.prox->pr_ns.begin() + pingContext->index) = rtt;
            break;

        default:
            throw cRuntimeError("wrong state object type!");
        }
        checkProxCache();
    }
    delete contextPointer;
}

void BasePastry::purgeVectors ( void   )  [protected, virtual]

delete all information/messages caching vectors, used for restarting overlay or finish()

Reimplemented in Pastry.

Definition at line 40 of file BasePastry.cc.

Referenced by baseChangeState(), and ~BasePastry().

{
    // purge Queue for processing multiple STATE messages:
    while (! stateCacheQueue.empty()) {
        delete stateCacheQueue.front().msg;
        delete stateCacheQueue.front().prox;
        stateCacheQueue.pop();
    }

    // delete cached state message:
    delete stateCache.msg;
    stateCache.msg = NULL;
    delete stateCache.prox;
    stateCache.prox = NULL;

    // purge vector of waiting sendState messages:
    if (! sendStateWait.empty()) {
        for (std::vector<PastrySendState*>::iterator it =
                 sendStateWait.begin(); it != sendStateWait.end(); it++) {
            if ( (*it)->isScheduled() ) cancelEvent(*it);
            delete *it;
        }
        sendStateWait.clear();
    }
}

void BasePastry::sendLeafset ( const TransportAddress tell,
bool  pull = false 
) [protected]

send the leafset to a node

Parameters:
tell the node to send to
pull true requests his leafset

Definition at line 805 of file BasePastry.cc.

Referenced by Bamboo::doLeafsetMaintenance(), handleRequestMessage(), and Bamboo::handleUDPMessage().

{
    if (tell.isUnspecified())
        opp_error("Pastry::sendLeafset(): send leafset to "
                  "unspecified node!");

    PastryLeafsetMessage* msg = new PastryLeafsetMessage("Leafset");
    if (pull) msg->setPastryMsgType(PASTRY_MSG_LEAFSET_PULL);
    else msg->setPastryMsgType(PASTRY_MSG_LEAFSET);
    msg->setTimestamp(simTime());
    msg->setStatType(MAINTENANCE_STAT);
    msg->setSender(thisNode);
    msg->setSendStateTo(thisNode);
    leafSet->dumpToStateMessage(msg);
    msg->setBitLength(PASTRYLEAFSET_L(msg));
    RECORD_STATS(leafsetSent++; leafsetBytesSent += msg->getByteLength());
    sendMessageToUDP(tell, msg);


}

void BasePastry::sendRequest ( const TransportAddress ask,
int  type 
) [protected]

send a request to a given node

Parameters:
ask request from this node
type specifies the data requested

Definition at line 755 of file BasePastry.cc.

Referenced by Pastry::changeState(), Pastry::checkProxCache(), Pastry::doSecondStage(), Pastry::handleFailedNode(), and Pastry::handleStateMessage().

{
    assert(ask != thisNode);
    std::string msgName("Req: ");
    switch (type) {
    case PASTRY_REQ_REPAIR:
        if (ask.isUnspecified())
            throw cRuntimeError("Pastry::sendRequest(): asked for repair from "
                                "unspecified node!");
        msgName += "Repair";
        break;

    case PASTRY_REQ_STATE:
        if (ask.isUnspecified())
            throw cRuntimeError("Pastry::sendRequest(): asked for state from "
                                "unspecified node!");
        msgName += "State";
        break;

    case PASTRY_REQ_LEAFSET:
        if (ask.isUnspecified())
            throw cRuntimeError("Pastry::sendRequest(): asked for leafset from "
                  "unspecified node!");
        msgName += "Leafset";
        break;
    }
    PastryRequestMessage* msg = new PastryRequestMessage(msgName.c_str());
    msg->setPastryMsgType(PASTRY_MSG_REQ);
    msg->setPastryReqType(type);
    msg->setStatType(MAINTENANCE_STAT);
    msg->setSendStateTo(thisNode);
    msg->setBitLength(PASTRYREQ_L(msg));
    sendMessageToUDP(ask, msg); //TODO RPCs

    switch (type) {
    case PASTRY_REQ_REPAIR:
        RECORD_STATS(repairReqSent++; repairReqBytesSent += msg->getByteLength());
        break;

    case PASTRY_REQ_STATE:
        RECORD_STATS(stateReqSent++; stateReqBytesSent += msg->getByteLength());
        break;

    case PASTRY_REQ_LEAFSET:
        RECORD_STATS(leafsetReqSent++; leafsetReqBytesSent += msg->getByteLength());
        break;
    }
}

void BasePastry::sendRoutingRow ( const TransportAddress tell,
int  row 
) [protected]

send a row of the routing table to a node

Parameters:
tell the node to send to
row the number of the row

Definition at line 826 of file BasePastry.cc.

Referenced by Pastry::handleUDPMessage(), and Bamboo::handleUDPMessage().

{
    if (tell.isUnspecified())
        opp_error("Pastry::sendRoutingTable(): asked for routing Table from "
                  "unspecified node!");

    PastryRoutingRowMessage* msg = new PastryRoutingRowMessage("Routing Row");
    msg->setPastryMsgType(PASTRY_MSG_RROW);
    msg->setStatType(MAINTENANCE_STAT);
    //msg->setSendStateTo(thisNode);
    msg->setSender(thisNode);
    msg->setRow(row);
    routingTable->dumpRowToMessage(msg, row);
    msg->setBitLength(PASTRYRTABLE_L(msg));
    RECORD_STATS(routingTableSent++; routingTableBytesSent += msg->getByteLength());
    sendMessageToUDP(tell, msg);
}

void BasePastry::sendStateDelayed ( const TransportAddress destination  ) 

send a standard state message with a small delay

Parameters:
destination destination node

Definition at line 653 of file BasePastry.cc.

Referenced by Pastry::checkProxCache().

{
    PastrySendState* selfMsg = new PastrySendState("sendStateWait");
    selfMsg->setDest(destination);
    sendStateWait.push_back(selfMsg);
    scheduleAt(simTime() + 0.0001, selfMsg);
}

void BasePastry::sendStateTables ( const TransportAddress destination,
int  type = PASTRY_STATE_STD,
  ... 
)

send a PastryStateMessage directly to a node

Parameters:
destination destination node
type the type of the state message to be sent
... additional arguments for some types:
PASTRY_STATE_JOIN: int hops number of hops to destination node
PASTRY_STATE_JOIN: bool last mark the state message to originate from closest node found
PASTRY_STATE_UPDATE: simtime_t* timestamp pointer use this timestamp for the uptade message

Definition at line 571 of file BasePastry.cc.

Referenced by Pastry::doJoinUpdate(), Pastry::endProcessingState(), handleRequestMessage(), Pastry::handleTimerEvent(), Pastry::handleUDPMessage(), Pastry::iterativeJoinHook(), and Pastry::recursiveRoutingHook().

{
    if (destination.getIp() == thisNode.getIp())
        opp_error("Pastry: trying to send state to self!");

    int hops = 0;
    bool last = false;
    simtime_t timestamp = 0;

    if ((type == PASTRY_STATE_JOIN) ||
        (type == PASTRY_STATE_MINJOIN) ||
        (type == PASTRY_STATE_UPDATE)) {
        // additional parameters needed:
        va_list ap;
        va_start(ap, type);
        if (type == PASTRY_STATE_JOIN || type == PASTRY_STATE_MINJOIN) {
            hops = va_arg(ap, int);
            last = static_cast<bool>(va_arg(ap, int));
        } else {
            timestamp = *va_arg(ap, simtime_t*);
        }
        va_end(ap);
    }

    // create new state msg and set special fields for some types:
    PastryStateMessage* stateMsg;
    if (type == PASTRY_STATE_JOIN || type == PASTRY_STATE_MINJOIN) {
        stateMsg = new PastryStateMessage("STATE (Join)");
        stateMsg->setJoinHopCount(hops);
        stateMsg->setLastHop(last);
        stateMsg->setTimestamp(simTime());
    } else if (type == PASTRY_STATE_UPDATE) {
        stateMsg = new PastryStateMessage("STATE (Update)");
        EV << "[BasePastry::sendStateTables() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    sending state (update) to " << destination
           << endl;
        stateMsg->setTimestamp(timestamp);
    } else if (type == PASTRY_STATE_REPAIR) {
        stateMsg = new PastryStateMessage("STATE (Repair)");
        stateMsg->setTimestamp(timestamp);
        EV << "[BasePastry::sendStateTables() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    sending state (repair) to " << destination
           << endl;
    } else {
        stateMsg = new PastryStateMessage("STATE");
        EV << "[BasePastry::sendStateTables() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    sending state (standard) to " << destination
           << endl;
    }

    // fill in standard content:
    stateMsg->setPastryMsgType(PASTRY_MSG_STATE);
    stateMsg->setStatType(MAINTENANCE_STAT);
    stateMsg->setPastryStateMsgType(type);
    stateMsg->setSender(thisNode);

    // the following part of the new join works on the assumption, that the node
    // routing the join message is close to the joining node
    // therefore its switched on together with the discovery algorithm
    if (type == PASTRY_STATE_MINJOIN) {
        //send just the needed row for new join protocol
        routingTable->dumpRowToMessage(stateMsg, hops);
        if (last) leafSet->dumpToStateMessage(stateMsg);
        else stateMsg->setLeafSetArraySize(0);
        if (hops == 1) neighborhoodSet->dumpToStateMessage(stateMsg);
        else stateMsg->setNeighborhoodSetArraySize(0);
    } else {
        routingTable->dumpToStateMessage(stateMsg);
        leafSet->dumpToStateMessage(stateMsg);
        neighborhoodSet->dumpToStateMessage(stateMsg);
    }

    // send...
    stateMsg->setBitLength(PASTRYSTATE_L(stateMsg));
    RECORD_STATS(stateSent++; stateBytesSent += stateMsg->getByteLength());
    sendMessageToUDP(destination, stateMsg);
}

void BasePastry::updateTooltip (  )  [virtual]

updates information shown in tk-environment

Definition at line 973 of file BasePastry.cc.

Referenced by baseChangeState(), Pastry::checkProxCache(), Bamboo::checkProxCache(), Pastry::doJoinUpdate(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), pingTimeout(), and proxCallback().

{
    if (ev.isGUI()) {
        std::stringstream ttString;

        // show our predecessor and successor in tooltip
        ttString << leafSet->getPredecessor() << endl << thisNode << endl
                 << leafSet->getSuccessor();

        getParentModule()->getParentModule()->getDisplayString().
            setTagArg("tt", 0, ttString.str().c_str());
        getParentModule()->getDisplayString().
            setTagArg("tt", 0, ttString.str().c_str());
        getDisplayString().setTagArg("tt", 0, ttString.str().c_str());

        // draw arrows:
        showOverlayNeighborArrow(leafSet->getSuccessor(), true,
                                 "m=m,50,0,50,0;ls=red,1");
        showOverlayNeighborArrow(leafSet->getPredecessor(), false,
                                 "m=m,50,100,50,100;ls=green,1");

    }
}


Friends And Related Function Documentation

friend class PastryLeafSet [friend]

Definition at line 366 of file BasePastry.h.


Member Data Documentation

Early update of leaf set: helper structure for marking known-dead nodes.

Definition at line 235 of file BasePastry.h.

Referenced by determineAliveTable(), Pastry::handleStateMessage(), and Bamboo::handleStateMessage().

bool BasePastry::alwaysSendUpdate [protected]

Definition at line 204 of file BasePastry.h.

Referenced by baseInit(), and Pastry::endProcessingState().

uint32_t BasePastry::bitsPerDigit [protected]

Definition at line 196 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), and Bamboo::doGlobalTuning().

Definition at line 161 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

bool BasePastry::enableNewLeafs [protected]

Definition at line 202 of file BasePastry.h.

Referenced by baseInit(), and newLeafs().

Definition at line 145 of file BasePastry.h.

Referenced by baseInit(), Pastry::changeState(), and finishOverlay().

uint32_t BasePastry::joinHopCount [protected]

Definition at line 139 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and Pastry::handleTimerEvent().

Definition at line 142 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and Pastry::handleUDPMessage().

Definition at line 134 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), and finishOverlay().

Definition at line 144 of file BasePastry.h.

Referenced by baseInit(), Pastry::changeState(), and finishOverlay().

double BasePastry::joinTimeoutAmount [protected]

Definition at line 200 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), Pastry::changeState(), and Bamboo::changeState().

Definition at line 138 of file BasePastry.h.

Referenced by baseChangeState(), baseInit(), and finishOverlay().

Definition at line 215 of file BasePastry.h.

Definition at line 165 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 164 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

simtime_t BasePastry::nearNodeRtt [protected]

Definition at line 208 of file BasePastry.h.

Referenced by Pastry::changeState(), and Pastry::pingResponse().

uint32_t BasePastry::numberOfLeaves [protected]
uint32_t BasePastry::numberOfNeighbors [protected]

Definition at line 198 of file BasePastry.h.

Referenced by baseChangeState(), and baseInit().

bool BasePastry::optimizeLookup [protected]

Definition at line 205 of file BasePastry.h.

Referenced by baseInit(), and findNode().

Definition at line 213 of file BasePastry.h.

uint32_t BasePastry::pingedNodes [protected]

Definition at line 210 of file BasePastry.h.

Referenced by Pastry::handleTimerEvent(), and Pastry::handleUDPMessage().

double BasePastry::readyWaitAmount [protected]

Definition at line 199 of file BasePastry.h.

Referenced by Pastry::handleStateMessage(), and Pastry::initializeOverlay().

Definition at line 151 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 150 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

double BasePastry::repairTimeout [protected]

Definition at line 201 of file BasePastry.h.

Referenced by baseChangeState(), and baseInit().

Definition at line 159 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 178 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRoutingRow().

Definition at line 160 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 177 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRoutingRow().

Definition at line 181 of file BasePastry.h.

Referenced by baseInit(), and Bamboo::doLocalTuning().

std::vector<PastrySendState*> BasePastry::sendStateWait [protected]

Definition at line 247 of file BasePastry.h.

Referenced by Pastry::handleTimerEvent(), purgeVectors(), and sendStateDelayed().

Definition at line 147 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendStateTables().

Queue of state messages waiting to be processed in READY state.

Definition at line 230 of file BasePastry.h.

Referenced by Bamboo::checkProxCache(), Pastry::doSecondStage(), Pastry::endProcessingState(), Pastry::handleStateMessage(), Bamboo::handleStateMessage(), and purgeVectors().

Definition at line 155 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 156 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and handleRequestMessage().

Definition at line 154 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendRequest().

Definition at line 146 of file BasePastry.h.

Referenced by baseInit(), finishOverlay(), and sendStateTables().

Definition at line 158 of file BasePastry.h.

Referenced by baseInit(), findNode(), and finishOverlay().

Definition at line 203 of file BasePastry.h.

Referenced by baseInit(), and findNode().


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