Public Member Functions | Protected Member Functions | Protected Attributes

oversim::Koorde Class Reference

Koorde overlay module. More...

#include <Koorde.h>

Inheritance diagram for oversim::Koorde:
oversim::Chord BaseOverlay ProxListener BaseRpc BaseTcpSupport TopologyVis RpcListener

List of all members.

Public Member Functions

virtual ~Koorde ()
virtual void initializeOverlay (int stage)
virtual void handleTimerEvent (cMessage *msg)
virtual void handleUDPMessage (BaseOverlayMessage *msg)
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
virtual void finishOverlay ()
virtual void updateTooltip ()
 updates information shown in tk-environment

Protected Member Functions

virtual void changeState (int state)
 changes node state
virtual void handleDeBruijnTimerExpired ()
 handle an expired de bruijn timer
virtual bool handleRpcCall (BaseCallMessage *msg)
 handle an expired fix_fingers timer (dummy function)
virtual void handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt)
virtual void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey)
virtual void handleRpcJoinResponse (JoinResponse *joinResponse)
 handle a received JOIN response
virtual void handleRpcDeBruijnRequest (DeBruijnCall *deBruinCall)
 handle a received DEBRUIJN request
virtual void handleRpcDeBruijnResponse (DeBruijnResponse *deBruijnResponse)
 handle a received DEBRUIJN response
virtual void handleDeBruijnTimeout (DeBruijnCall *deBruijnCall)
 handle a DEBRUIJN timeout
virtual NodeHandle findDeBruijnHop (const OverlayKey &destKey, KoordeFindNodeExtMessage *findNodeExt)
 returns the NodeHandle of the next hop to destination key using the de Bruijn list
NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg)
virtual OverlayKey findStartKey (const OverlayKey &startKey, const OverlayKey &endKey, const OverlayKey &destKey, int &step)
 find a "good" routing key to destKey between startingKey and endKey with the longest matching prefix possible
virtual const NodeHandlewalkDeBruijnList (const OverlayKey &key)
 Given a key the function checks if the key falls between two nodes in the de Bruijn list.
virtual const NodeHandlewalkSuccessorList (const OverlayKey &key)
 Given a key the function checks if the key falls between two nodes in the de successor list.
virtual bool handleFailedNode (const TransportAddress &failed)
virtual void rpcJoin (JoinCall *call)
 Join Remote-Procedure-Call.
virtual void findFriendModules ()
 Assigns the finger table and successor list module to our reference.
virtual void initializeFriendModules ()
 initializes finger table and successor list

Protected Attributes

int deBruijnDelay
 number of seconds between two de bruijn calls
int deBruijnNumber
 number of current nodes in de bruijn list; depend on number of nodes in successor list
int deBruijnListSize
 maximal number of nodes in de bruijn list
int shiftingBits
 number of bits concurrently shifted in one routing step
bool useOtherLookup
 flag which is indicating that the optimization other lookup is enabled
bool useSucList
 flag which is indicating that the optimization using the successorlist is enabled
bool breakLookup
 flag is used during the recursive step when returning this node
bool setupDeBruijnBeforeJoin
 if true, first setup the de bruijn node using the bootstrap node and than join the ring
bool setupDeBruijnAtJoin
 if true, join the ring and setup the de bruijn node using the bootstrap node in parallel
int deBruijnCount
 number of de bruijn calls
int deBruijnBytesSent
 number of bytes sent during de bruijn calls
NodeHandledeBruijnNodes
 List of de Bruijn nodes.
NodeHandle deBruijnNode
 Handle to our de Bruijn node.
cMessage * deBruijn_timer
 timer for periodic de bruijn stabilization

Detailed Description

Koorde overlay module.

Implementation of the Koorde KBR overlay as described in "Koorde: A simple degree-optimal distributed hash table" by M. Kaashoek and D. Karger

Author:
Jochen Schenk
See also:
Chord, ChordSuccessorList

Definition at line 50 of file Koorde.h.


Constructor & Destructor Documentation

oversim::Koorde::~Koorde (  )  [virtual]

Definition at line 74 of file Koorde.cc.

{
    cancelAndDelete(deBruijn_timer);
}


Member Function Documentation

void oversim::Koorde::changeState ( int  state  )  [protected, virtual]

changes node state

Parameters:
state state to change to

Reimplemented from oversim::Chord.

Definition at line 79 of file Koorde.cc.

Referenced by handleDeBruijnTimeout().

{
    Chord::changeState(toState);

    switch(state) {
    case INIT:
        // init de Bruijn nodes
        deBruijnNode = NodeHandle::UNSPECIFIED_NODE;

        for (int i=0; i < deBruijnListSize; i++) {
            deBruijnNodes[i] = NodeHandle::UNSPECIFIED_NODE;
        }

        updateTooltip();
        break;
    case BOOTSTRAP:
        if (setupDeBruijnBeforeJoin) {
            // setup de bruijn node before joining the ring
            cancelEvent(join_timer);
            cancelEvent(deBruijn_timer);
            scheduleAt(simTime(), deBruijn_timer);
        } else if (setupDeBruijnAtJoin) {
            cancelEvent(deBruijn_timer);
            scheduleAt(simTime(), deBruijn_timer);
        }
        break;
    case READY:
        // init de Bruijn Protocol
        cancelEvent(deBruijn_timer);
        scheduleAt(simTime(), deBruijn_timer);

        // since we don't need the fixfingers protocol in Koorde cancel timer
        cancelEvent(fixfingers_timer);
        break;
    default:
        break;
    }

}

NodeHandle oversim::Koorde::findDeBruijnHop ( const OverlayKey destKey,
KoordeFindNodeExtMessage findNodeExt 
) [protected, virtual]

returns the NodeHandle of the next hop to destination key using the de Bruijn list

Parameters:
destKey The destination key
findNodeExt The FindNodeExtensionMessage
Returns:
next hop to destination key

Definition at line 473 of file Koorde.cc.

Referenced by findNode().

{
    if (findNodeExt->getRouteKey().isUnspecified()) {
        if (!deBruijnNode.isUnspecified()) {
            int step;
            findNodeExt->setRouteKey(findStartKey(thisNode.getKey(),
                              successorList->getSuccessor().getKey(), destKey,
                              step));
            findNodeExt->setStep(step);
        } else {
            breakLookup = true;
            return successorList->getSuccessor();
        }
    }

    // check if the route key falls in our responsibility or
    // else forward the message to our successor
    if (findNodeExt->getRouteKey().isBetweenR(thisNode.getKey(),
        successorList->getSuccessor().getKey())) {
        if ((unsigned int)findNodeExt->getStep() > destKey.getLength())
            error("Koorde::findDeBruijnHop - Bounding error: "
                  "trying to get non existing bit out of overlay key!");

        // update the route key
        OverlayKey add = OverlayKey(destKey.getBit(destKey.getLength() -
                                                   findNodeExt->getStep()));
        for (int i = 1; i < shiftingBits; i++) {
            add = (add << 1) + OverlayKey(destKey.getBit(destKey.getLength() -
                                          findNodeExt->getStep() - i));
        }

        OverlayKey routeKey = (findNodeExt->getRouteKey()<<shiftingBits) + add;
        findNodeExt->setRouteKey(routeKey);
        findNodeExt->setStep(findNodeExt->getStep() + shiftingBits);

        if (deBruijnNode.isUnspecified()) {
            breakLookup = true;
            if (useSucList)
                return walkSuccessorList(findNodeExt->getRouteKey());
            else
                return successorList->getSuccessor();
        }

        // check if the new route key falls between our
        // de Bruijn node and its successor
        if (deBruijnNumber > 0) {
            if (findNodeExt->getRouteKey().isBetweenR(deBruijnNode.getKey(),
                                                      deBruijnNodes[0].getKey())) {
                return deBruijnNode;
            } else {
                // otherwise check if the route key falls between
                // our de Bruijn successors
                NodeHandle nextHop = walkDeBruijnList(findNodeExt->
                                                      getRouteKey());
                return nextHop;
            }
        } else {
            return deBruijnNode;
        }
    } else {
        breakLookup = true;
        // if optimization is set search the successor list and
        // de bruijn node to find "good" next hop
        if (useSucList) {
            if (deBruijnNode.isUnspecified()) {
                return walkSuccessorList(findNodeExt->getRouteKey());
            } else {
                NodeHandle tmpHandle =
                    walkSuccessorList(findNodeExt->getRouteKey());

                // todo: optimization - check complete deBruijnList
                if (deBruijnNode.getKey().isBetween(tmpHandle.getKey(),
                                               findNodeExt->getRouteKey())) {
                    return deBruijnNode;
                } else {
                    return tmpHandle;
                }
            }
        } else
            return successorList->getSuccessor();
    }
}

void oversim::Koorde::findFriendModules (  )  [protected, virtual]

Assigns the finger table and successor list module to our reference.

Reimplemented from oversim::Chord.

Definition at line 764 of file Koorde.cc.

{
    successorList = check_and_cast<ChordSuccessorList*>
                    (getParentModule()->getSubmodule("successorList"));
}

NodeVector * oversim::Koorde::findNode ( const OverlayKey key,
int  numRedundantNodes,
int  numSiblings,
BaseOverlayMessage msg 
) [protected]

Reimplemented from oversim::Chord.

Definition at line 405 of file Koorde.cc.

{
    // TODO: return redundant nodes for iterative routing
    // TODO: try to always calculate optimal routing key (if e.g.
    //       the originator didn't have its deBruijnNode set already, the
    //       routing key may be very far away on the ring)
    NodeVector* nextHop = new NodeVector();
    KoordeFindNodeExtMessage *findNodeExt = NULL;

    if (state != READY)
        return nextHop;

    if (msg != NULL) {
        if (!msg->hasObject("findNodeExt")) {
            findNodeExt = new KoordeFindNodeExtMessage("findNodeExt");
            findNodeExt->setRouteKey(OverlayKey::UNSPECIFIED_KEY);
            findNodeExt->setStep(1);
            findNodeExt->setBitLength(KOORDEFINDNODEEXTMESSAGE_L);
            msg->addObject( findNodeExt );
        }

        findNodeExt = (KoordeFindNodeExtMessage*) msg->getObject("findNodeExt");
    }

    if (key.isUnspecified()) {
        error("Koorde::findNode() - direct Messaging is no longer in use.");
    } else if (key.isBetweenR(predecessorNode.getKey(), thisNode.getKey())) {
        // the message is destined for this node
        nextHop->push_back(thisNode);
    } else if (key.isBetweenR(thisNode.getKey(),
                              successorList->getSuccessor().getKey())){
        // the message destined for our successor
        nextHop->push_back(successorList->getSuccessor());
    } else {
        // if useOtherLookup is enabled we try to use
        // our successor list to get to the key
        if (useOtherLookup) {
            NodeHandle tmpNode = walkSuccessorList(key);
            if (tmpNode !=
                  successorList->getSuccessor(successorList->getSize() - 1)) {
                nextHop->push_back(tmpNode);
            } else {
                NodeHandle tmpHandle = findDeBruijnHop(key, findNodeExt);
                if (tmpHandle != thisNode || breakLookup) {
                    nextHop->push_back(tmpHandle);
                    breakLookup = false;
                } else {
                    return findNode(key, numRedundantNodes, numSiblings, msg);
                }
            }
        } else {
            // find next hop using either the de Bruijn node and
            // its successors or our own successors
            NodeHandle tmpHandle = findDeBruijnHop(key, findNodeExt);
            if (tmpHandle != thisNode || breakLookup) {
                nextHop->push_back(tmpHandle);
                breakLookup = false;
            } else {
                return findNode(key, numRedundantNodes, numSiblings, msg);
            }
        }
    }
    return nextHop;
}

OverlayKey oversim::Koorde::findStartKey ( const OverlayKey startKey,
const OverlayKey endKey,
const OverlayKey destKey,
int &  step 
) [protected, virtual]

find a "good" routing key to destKey between startingKey and endKey with the longest matching prefix possible

Parameters:
startKey begin of the (key) interval
endKey end of the (key) interval
destKey destination key - should be matched as good as possible
step reference to return the bit position
Returns:
a "good" routing key to start from

Definition at line 664 of file Koorde.cc.

Referenced by findDeBruijnHop().

{
    OverlayKey diffKey, newStart, tmpDest, newKey, powKey;
    int nBits;

    if (startKey == endKey)
        return startKey;

    diffKey = endKey - startKey;
    nBits = diffKey.log_2();

    if (nBits < 0) {
        nBits = 0;
    }

    while ((startKey.getLength() - nBits) % shiftingBits != 0) {
       nBits--;
   }

    step = nBits + 1;

#if 0
    // TODO: work in progress to find better start key
    uint shared;
    for (shared = 0; shared < (startKey.getLength() - nBits); shared += shiftingBits) {
        if (destKey.sharedPrefixLength(startKey << shared) >= (startKey.getLength() - nBits - shared)) {
             break;
         }
    }

    uint nBits2 = startKey.getLength() - shared;

    newStart = (startKey >> nBits2) << nBits2;

    tmpDest = destKey >> (destKey.getLength() - nBits2);
    newKey = tmpDest + newStart;

    std::cout << "startKey: " << startKey.toString(2) << endl
              << "endKey  : " << endKey.toString(2) << endl
              << "diff    : " << (endKey-startKey).toString(2) << endl
              << "newKey  : " << newKey.toString(2) << endl
              << "destKey : " << destKey.toString(2) << endl
              << "nbits   : " << nBits << endl
              << "nbits2  : " << nBits2 << endl;

    // is the new constructed route key bigger than our start key return it
    if (newKey.isBetweenR(startKey, endKey)) {
        std::cout << "HIT" << endl;
        return newKey;
    } else {
        nBits2 -= shiftingBits;
        newStart = (startKey >> nBits2) << nBits2;

        tmpDest = destKey >> (destKey.getLength() - nBits2);
        newKey = tmpDest + newStart;

        if (newKey.isBetweenR(startKey, endKey)) {
            std::cout << "startKey: " << startKey.toString(2) << endl
                      << "endKey  : " << endKey.toString(2) << endl
                      << "diff    : " << (endKey-startKey).toString(2) << endl
                      << "newKey  : " << newKey.toString(2) << endl
                      << "destKey : " << destKey.toString(2) << endl
                      << "nbits   : " << nBits << endl
                      << "nbits2  : " << nBits2 << endl;
            std::cout << "HIT2" << endl;
            return newKey;
        }
    }

    std::cout << "MISS" << endl;
#endif

    newStart = (startKey >> nBits) << nBits;

    tmpDest = destKey >> (destKey.getLength() - nBits);
    newKey = tmpDest + newStart;

    // is the new constructed route key bigger than our start key return it
    if (newKey.isBetweenR(startKey, endKey)) {
        return newKey;
    }

    // If the part of the destination key smaller than the one of
    // the original key add pow(nBits) (this is the first bit where
    // the start key and end key differ) to the new constructed key
    // and check if it's between start and end key.
    newKey += powKey.pow2(nBits);

    if (newKey.isBetweenR(startKey, endKey)) {
        return newKey;
    } else {
        // this part should not be called
        throw cRuntimeError("Koorde::findStartKey(): Invalid start key");
        return OverlayKey::UNSPECIFIED_KEY;
    }
}

void oversim::Koorde::finishOverlay (  )  [virtual]

Reimplemented from oversim::Chord.

Definition at line 626 of file Koorde.cc.

{
    // statistics
    simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);

    if (time >= GlobalStatistics::MIN_MEASURED) {
        globalStatistics->addStdDev("Koorde: Sent DEBRUIJN Messages/s",
                                    deBruijnCount / time);
        globalStatistics->addStdDev("Koorde: Sent DEBRUIJN Bytes/s",
                                    deBruijnBytesSent / time);
    }

    Chord::finishOverlay();
}

void oversim::Koorde::handleDeBruijnTimeout ( DeBruijnCall deBruijnCall  )  [protected, virtual]

handle a DEBRUIJN timeout

Parameters:
deBruijnCall the message which timed out

Definition at line 392 of file Koorde.cc.

Referenced by handleRpcTimeout().

{
    if (setupDeBruijnBeforeJoin && (state == BOOTSTRAP)) {
        // failed to set initial de bruijn node
        // -> get a new bootstrap node and try again
        changeState(BOOTSTRAP);
        return;
    }

    cancelEvent(deBruijn_timer);
    scheduleAt(simTime(), deBruijn_timer);
}

void oversim::Koorde::handleDeBruijnTimerExpired (  )  [protected, virtual]

handle an expired de bruijn timer

Definition at line 164 of file Koorde.cc.

Referenced by handleTimerEvent(), and rpcJoin().

{
    OverlayKey lookup = thisNode.getKey() << shiftingBits;

    if (state == READY) {
        if (successorList->getSize() > 0) {
            // look for some nodes before our actual de-bruijn key
            // to have redundancy if our de-bruijn node fails
            lookup -= (successorList->getSuccessor(successorList->getSize() /
                                              2).getKey() - thisNode.getKey());
        }

        if (lookup.isBetweenR(thisNode.getKey(),
                              successorList->getSuccessor().getKey())
                || successorList->isEmpty()) {

            int sucNum = successorList->getSize();
            if (sucNum > deBruijnListSize)
                sucNum = deBruijnListSize;

            deBruijnNode = thisNode;
            for (int i = 0; i < sucNum; i++) {
                deBruijnNodes[i] = successorList->getSuccessor(i);
                deBruijnNumber = i+1;
            }

            updateTooltip();
        } else if (lookup.isBetweenR(predecessorNode.getKey(),
                                     thisNode.getKey())) {
            int sucNum = successorList->getSize();
            if ((sucNum + 1) > deBruijnListSize)
                sucNum = deBruijnListSize - 1;

            deBruijnNode = predecessorNode;
            deBruijnNodes[0] = thisNode;
            for (int i = 0; i < sucNum; i++) {
                deBruijnNodes[i+1] = successorList->getSuccessor(i);
                deBruijnNumber = i+2;
            }

            updateTooltip();
        } else {
            DeBruijnCall* call = new DeBruijnCall("DeBruijnCall");
            call->setDestKey(lookup);
            call->setBitLength(DEBRUIJNCALL_L(call));

            sendRouteRpcCall(OVERLAY_COMP, deBruijnNode,
                             call->getDestKey(), call, NULL,
                             DEFAULT_ROUTING);
        }

        cancelEvent(deBruijn_timer);
        scheduleAt(simTime() + deBruijnDelay, deBruijn_timer);
    } else {
        if (setupDeBruijnBeforeJoin || setupDeBruijnAtJoin) {
            DeBruijnCall* call = new DeBruijnCall("DeBruijnCall");
            call->setDestKey(lookup);
            call->setBitLength(DEBRUIJNCALL_L(call));

            sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, call->getDestKey(),
                             call, NULL, DEFAULT_ROUTING);

            scheduleAt(simTime() + deBruijnDelay, deBruijn_timer);
        }
    }
}

bool oversim::Koorde::handleFailedNode ( const TransportAddress failed  )  [protected, virtual]

Reimplemented from oversim::Chord.

Definition at line 130 of file Koorde.cc.

{
    if (!deBruijnNode.isUnspecified()) {
        if (failed == deBruijnNode) {
            deBruijnNode = deBruijnNodes[0];
            for (int i = 0; i < deBruijnNumber - 1; i++) {
                deBruijnNodes[i] = deBruijnNodes[i+1];
            }

            if (deBruijnNumber > 0) {
                deBruijnNodes[deBruijnNumber - 1] = NodeHandle::UNSPECIFIED_NODE;
                --deBruijnNumber;
            }
        } else {
            bool removed = false;
            for (int i = 0; i < deBruijnNumber - 1; i++) {
                if ((!deBruijnNodes[i].isUnspecified()) &&
                        (failed == deBruijnNodes[i])) {
                    removed = true;
                }
                if (removed ||
                        ((!deBruijnNodes[deBruijnNumber - 1].isUnspecified())
                          && failed == deBruijnNodes[deBruijnNumber - 1])) {
                    deBruijnNodes[deBruijnNumber - 1] =
                            NodeHandle::UNSPECIFIED_NODE;
                    --deBruijnNumber;
                }
            }
        }
    }

    return Chord::handleFailedNode(failed);
}

bool oversim::Koorde::handleRpcCall ( BaseCallMessage msg  )  [protected, virtual]

handle an expired fix_fingers timer (dummy function)

Parameters:
msg the timer self-message

Reimplemented from oversim::Chord.

Definition at line 245 of file Koorde.cc.

{
    if (state == READY) {
        // delegate messages
        RPC_SWITCH_START( msg )
        RPC_DELEGATE( DeBruijn, handleRpcDeBruijnRequest );
        RPC_SWITCH_END( )

        if (RPC_HANDLED) return true;
    } else {
        EV << "[Koorde::handleRpcCall() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    Received RPC call and state != READY!"
           << endl;
    }

    return Chord::handleRpcCall(msg);
}

void oversim::Koorde::handleRpcDeBruijnRequest ( DeBruijnCall deBruinCall  )  [protected, virtual]

handle a received DEBRUIJN request

Parameters:
deBruinCall the message to process

Definition at line 328 of file Koorde.cc.

Referenced by handleRpcCall().

{
    // The key lies between thisNode and its predecessor and
    // because routing the message to the predecessor of a key
    // is near to impossible we set the deBruijnNodes here
    // and the information is as actual as the predecessor pointer.
    //
    // If this is the only node in the ring, it is the temporary de bruijn
    // node for the joining node.
    if ((predecessorNode.isUnspecified() && successorList->isEmpty())
            || deBruijnCall->getDestKey().isBetweenR(predecessorNode.getKey(),
                                              thisNode.getKey())) {
        DeBruijnResponse* deBruijnResponse =
            new DeBruijnResponse("DeBruijnResponse");

        if (predecessorNode.isUnspecified()) {
            deBruijnResponse->setDBNode(thisNode);
        } else {
            deBruijnResponse->setDBNode(predecessorNode);
        }

        int sucNum = successorList->getSize() + 1;
        deBruijnResponse->setSucNum(sucNum);
        deBruijnResponse->setSucNodeArraySize(sucNum);

        deBruijnResponse->setSucNode(0, thisNode);
        for (int k = 1; k < sucNum; k++) {
            deBruijnResponse->setSucNode(k, successorList->getSuccessor(k-1));
        }
        deBruijnResponse->setBitLength(DEBRUIJNRESPONSE_L(deBruijnResponse));

        sendRpcResponse(deBruijnCall, deBruijnResponse);
    } else if (deBruijnCall->getDestKey().isBetweenR(thisNode.getKey(),
               successorList->getSuccessor().getKey())) {
        error("Koorde::handleRpcDeBruijnRequest() - unknown error.");
    } else {
        error("Koorde::handleRpcDeBruijnRequest() - "
              "Request couldn't be delivered!");
    }
}

void oversim::Koorde::handleRpcDeBruijnResponse ( DeBruijnResponse deBruijnResponse  )  [protected, virtual]

handle a received DEBRUIJN response

Parameters:
deBruijnResponse the message to process

Definition at line 369 of file Koorde.cc.

Referenced by handleRpcResponse().

{
    int sucNum = deBruijnResponse->getSucNum();
    if (sucNum > deBruijnListSize)
        sucNum = deBruijnListSize;

    for (int i = 0; i < sucNum; i++) {
        deBruijnNodes[i] = deBruijnResponse->getSucNode(i);
        deBruijnNumber = i+1;
    }

    deBruijnNode = deBruijnResponse->getDBNode();

    updateTooltip();

    if (setupDeBruijnBeforeJoin && (state == BOOTSTRAP)) {
        // now that we have a valid de bruijn node it's time to join the ring
        if (!join_timer->isScheduled()) {
            scheduleAt(simTime(), join_timer);
        }
    }
}

void oversim::Koorde::handleRpcJoinResponse ( JoinResponse joinResponse  )  [protected, virtual]

handle a received JOIN response

Parameters:
joinResponse the message to process

Reimplemented from oversim::Chord.

Definition at line 304 of file Koorde.cc.

{
    Chord::handleRpcJoinResponse(joinResponse);

    // has to be canceled in Koorde
    cancelEvent(fixfingers_timer);

    // immediate deBruijn protocol
    cancelEvent(deBruijn_timer);
    scheduleAt(simTime(), deBruijn_timer);
}

void oversim::Koorde::handleRpcResponse ( BaseResponseMessage msg,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

Reimplemented from oversim::Chord.

Definition at line 264 of file Koorde.cc.

{
    Chord::handleRpcResponse(msg, context, rpcId, rtt);

    RPC_SWITCH_START( msg )
    RPC_ON_RESPONSE( DeBruijn ) {
        handleRpcDeBruijnResponse(_DeBruijnResponse);
        EV << "[Koorde::handleRpcResponse() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    DeBruijn RPC Response received: id=" << rpcId
           << "\n    msg=" << *_DeBruijnResponse << " rtt=" << rtt
           << endl;
        break;
    }
    RPC_SWITCH_END( )
}

void oversim::Koorde::handleRpcTimeout ( BaseCallMessage msg,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId,
const OverlayKey destKey 
) [protected, virtual]

Reimplemented from oversim::Chord.

Definition at line 283 of file Koorde.cc.

{
    Chord::handleRpcTimeout(msg, dest, context, rpcId, destKey);

    RPC_SWITCH_START( msg )
    RPC_ON_CALL( DeBruijn ) {
        handleDeBruijnTimeout(_DeBruijnCall);
        EV << "[Koorde::handleRpcTimeout() @ " << thisNode.getIp()
           << " (" << thisNode.getKey().toString(16) << ")]\n"
           << "    DeBruijn RPC Call timed out: id=" << rpcId
           << "\n    msg=" << *_DeBruijnCall
           << endl;
        break;
    }
    RPC_SWITCH_END( )
}

void oversim::Koorde::handleTimerEvent ( cMessage *  msg  )  [virtual]

Reimplemented from oversim::Chord.

Definition at line 119 of file Koorde.cc.

{
    if (msg->isName("deBruijn_timer")) {
        handleDeBruijnTimerExpired();
    } else if (msg->isName("fixfingers_timer")) {
        handleFixFingersTimerExpired(msg);
    } else {
        Chord::handleTimerEvent(msg);
    }
}

void oversim::Koorde::handleUDPMessage ( BaseOverlayMessage msg  )  [virtual]

Reimplemented from oversim::Chord.

Definition at line 239 of file Koorde.cc.

void oversim::Koorde::initializeFriendModules (  )  [protected, virtual]

initializes finger table and successor list

Reimplemented from oversim::Chord.

Definition at line 770 of file Koorde.cc.

{
    // initialize successor list
    successorList->initializeList(par("successorListSize"), thisNode, this);
}

void oversim::Koorde::initializeOverlay ( int  stage  )  [virtual]

Reimplemented from oversim::Chord.

Definition at line 37 of file Koorde.cc.

{
    // because of IPAddressResolver, we need to wait until interfaces
    // are registered, address auto-assignment takes place etc.
    if (stage != MIN_STAGE_OVERLAY)
        return;

    // fetch some parameters
    deBruijnDelay = par("deBruijnDelay");
    deBruijnListSize = par("deBruijnListSize");
    shiftingBits = par("shiftingBits");
    useOtherLookup = par("useOtherLookup");
    useSucList = par("useSucList");
    setupDeBruijnBeforeJoin = par("setupDeBruijnBeforeJoin");
    setupDeBruijnAtJoin = par("setupDeBruijnAtJoin");

    // init flags
    breakLookup = false;

    // some local variables
    deBruijnNumber = 0;
    deBruijnNodes = new NodeHandle[deBruijnListSize];

    // statistics
    deBruijnCount = 0;
    deBruijnBytesSent = 0;

    // add some watches
    WATCH(deBruijnNumber);
    WATCH(deBruijnNode);

    // timer messages
    deBruijn_timer = new cMessage("deBruijn_timer");

    Chord::initializeOverlay(stage);
}

void oversim::Koorde::recordOverlaySentStats ( BaseOverlayMessage msg  )  [virtual]

Reimplemented from oversim::Chord.

Definition at line 641 of file Koorde.cc.

{
    Chord::recordOverlaySentStats(msg);

    BaseOverlayMessage* innerMsg = msg;
    while (innerMsg->getType() != APPDATA &&
           innerMsg->getEncapsulatedPacket() != NULL) {
        innerMsg =
            static_cast<BaseOverlayMessage*>(innerMsg->getEncapsulatedPacket());
    }

    switch (innerMsg->getType()) {
        case RPC: {
            if ((dynamic_cast<DeBruijnCall*>(innerMsg) != NULL) ||
                (dynamic_cast<DeBruijnResponse*>(innerMsg) != NULL)) {
                RECORD_STATS(deBruijnCount++; deBruijnBytesSent +=
                                 msg->getByteLength());
            }
        break;
        }
    }
}

void oversim::Koorde::rpcJoin ( JoinCall call  )  [protected, virtual]

Join Remote-Procedure-Call.

Parameters:
call RPC Parameter Message

Reimplemented from oversim::Chord.

Definition at line 317 of file Koorde.cc.

{
    Chord::rpcJoin(joinCall);

    if (predecessorNode == successorList->getSuccessor()) {
        // second node join -> need to setup our de bruijn node
        handleDeBruijnTimerExpired();
    }
}

void oversim::Koorde::updateTooltip (  )  [virtual]

updates information shown in tk-environment

Reimplemented from oversim::Chord.

Definition at line 584 of file Koorde.cc.

Referenced by changeState(), handleDeBruijnTimerExpired(), and handleRpcDeBruijnResponse().

{
    //
    // Updates the tooltip display strings.
    //

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

        // show our predecessor, successor and de Bruijn node in tooltip
        ttString << "Pred "<< predecessorNode << endl << "This  "
                 << thisNode << endl
                 << "Suc   " << successorList->getSuccessor() << endl
                 << "DeBr " << deBruijnNode << endl;
        ttString << "List ";

        for (unsigned int i = 0; i < successorList->getSize(); i++) {
            ttString << successorList->getSuccessor(i).getIp() << " ";
        }

        ttString << endl;
        ttString << "DList ";

        for (int i = 0; i < deBruijnNumber; i++) {
            ttString << deBruijnNodes[i].getIp() << " ";
        }

        ttString << endl;

        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 an arrow to our current successor
        showOverlayNeighborArrow(successorList->getSuccessor(), true,
                                 "m=m,50,0,50,0;ls=red,1");
    }
}

const NodeHandle & oversim::Koorde::walkDeBruijnList ( const OverlayKey key  )  [protected, virtual]

Given a key the function checks if the key falls between two nodes in the de Bruijn list.

If no match is found the last node in the de Bruijn list is returned.

Parameters:
key the key to check
Returns:
either the node directly preceding key or the node which has the shortest distance to the key

Definition at line 558 of file Koorde.cc.

Referenced by findDeBruijnHop().

{
    if (deBruijnNumber == 0)
        return NodeHandle::UNSPECIFIED_NODE;

    for (int i = 0; i < deBruijnNumber-1; i++) {
        if (key.isBetweenR(deBruijnNodes[i].getKey(),deBruijnNodes[i+1].getKey())) {
            return deBruijnNodes[i];
        }
    }

    return deBruijnNodes[deBruijnNumber-1];
}

const NodeHandle & oversim::Koorde::walkSuccessorList ( const OverlayKey key  )  [protected, virtual]

Given a key the function checks if the key falls between two nodes in the de successor list.

If no match is found the last node in the de successor list is returned.

Parameters:
key the key to check
Returns:
either the node directly preceding key or the node which has the shortest distance to the key

Definition at line 572 of file Koorde.cc.

Referenced by findDeBruijnHop(), and findNode().

{
    for (unsigned int i = 0; i < successorList->getSize()-1; i++) {
        if (key.isBetweenR(successorList->getSuccessor(i).getKey(),
                           successorList->getSuccessor(i+1).getKey())) {
            return successorList->getSuccessor(i);
        }
    }

    return successorList->getSuccessor(successorList->getSize()-1);
}


Member Data Documentation

bool oversim::Koorde::breakLookup [protected]

flag is used during the recursive step when returning this node

Definition at line 83 of file Koorde.h.

Referenced by findDeBruijnHop(), findNode(), and initializeOverlay().

cMessage* oversim::Koorde::deBruijn_timer [protected]

timer for periodic de bruijn stabilization

Definition at line 96 of file Koorde.h.

Referenced by changeState(), handleDeBruijnTimeout(), handleDeBruijnTimerExpired(), handleRpcJoinResponse(), initializeOverlay(), and ~Koorde().

number of bytes sent during de bruijn calls

Definition at line 89 of file Koorde.h.

Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().

number of de bruijn calls

Definition at line 88 of file Koorde.h.

Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().

number of seconds between two de bruijn calls

Definition at line 77 of file Koorde.h.

Referenced by handleDeBruijnTimerExpired(), and initializeOverlay().

maximal number of nodes in de bruijn list

Definition at line 79 of file Koorde.h.

Referenced by changeState(), handleDeBruijnTimerExpired(), handleRpcDeBruijnResponse(), and initializeOverlay().

number of current nodes in de bruijn list; depend on number of nodes in successor list

Definition at line 78 of file Koorde.h.

Referenced by findDeBruijnHop(), handleDeBruijnTimerExpired(), handleFailedNode(), handleRpcDeBruijnResponse(), initializeOverlay(), updateTooltip(), and walkDeBruijnList().

if true, join the ring and setup the de bruijn node using the bootstrap node in parallel

Definition at line 85 of file Koorde.h.

Referenced by changeState(), handleDeBruijnTimerExpired(), and initializeOverlay().

if true, first setup the de bruijn node using the bootstrap node and than join the ring

Definition at line 84 of file Koorde.h.

Referenced by changeState(), handleDeBruijnTimeout(), handleDeBruijnTimerExpired(), handleRpcDeBruijnResponse(), and initializeOverlay().

number of bits concurrently shifted in one routing step

Definition at line 80 of file Koorde.h.

Referenced by findDeBruijnHop(), findStartKey(), handleDeBruijnTimerExpired(), and initializeOverlay().

flag which is indicating that the optimization other lookup is enabled

Definition at line 81 of file Koorde.h.

Referenced by findNode(), and initializeOverlay().

bool oversim::Koorde::useSucList [protected]

flag which is indicating that the optimization using the successorlist is enabled

Definition at line 82 of file Koorde.h.

Referenced by findDeBruijnHop(), and initializeOverlay().


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