Chord Class Reference

#include <Chord.h>

Inheritance diagram for Chord:

BaseOverlay BaseRpc RpcListener Koorde List of all members.

Detailed Description

Chord overlay module.

Implementation of the Chord KBR overlay as described in "Chord: A Scalable Peer-to-Peer Lookup Protocol for Inetnet Applications" by I. Stoica et al. published in Transactions on Networking.

Author:
Markus Mauch, Ingmar Baumgart
See also:
BaseOverlay, ChordFingerTable, ChordSuccessorList


Public Member Functions

virtual ~Chord ()
virtual void initializeOverlay (int stage)
 Initializes derived-class-attributes.
virtual void receiveChangeNotification (int category, cPolymorphic *details)
 callback-method for events at the NotificationBoard
virtual void handleTimerEvent (cMessage *msg)
 handles self-messages
virtual void handleUDPMessage (BaseOverlayMessage *msg)
 processes messages from underlay
virtual void recordOverlaySentStats (BaseOverlayMessage *msg)
 Collect overlay specific sent messages statistics.
virtual void finishOverlay ()
 collects statisticts
virtual void updateTooltip ()
 updates information shown in tk-environment

Protected Member Functions

virtual void changeState (int toState)
 changes node state
virtual void handleJoinTimerExpired (cMessage *msg)
 handle a expired join timer
virtual void handleStabilizeTimerExpired (cMessage *msg)
 handle a expired stabilize timer
virtual void handleFixFingersTimerExpired (cMessage *msg)
 handle a expired fix_fingers timer
virtual void handleNewSuccessorHint (ChordMessage *chordMsg)
 handle a received NEWSUCCESSORHINT message
virtual NodeVectorclosestPreceedingNode (const OverlayKey &key)
 looks up the finger table and returns the closest preceeding node.
virtual void findFriendModules ()
 Assigns the finger table and succesesor list module to our reference.
virtual void initializeFriendModules ()
 initializes finger table and successor list
virtual bool handleRpc (BaseCallMessage *msg)
 Processes Remote-Procedure-Call invokation messages.
NodeVectorfindNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg)
 Implements the find node call.
virtual void joinOverlay ()
 
See also:
BaseOverlay.cc

virtual bool isSiblingFor (const NodeHandle &node, const OverlayKey &key, int numSiblings, bool *err)
 
See also:
BaseOverlay.cc

int getMaxNumSiblings ()
 Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.
int getMaxNumRedundantNodes ()
 Query the maximum number of redundant next hop nodes that are returned by findNode().
void rpcFixfingers (FixfingersCall *call)
 Fixfingers Remote-Procedure-Call.
void rpcJoin (JoinCall *call)
 Join Remote-Procedure-Call.
void rpcNotify (NotifyCall *call)
 NOTIFY Remote-Procedure-Call.
void rpcStabilize (StabilizeCall *call)
 STABILIZE Remote-Procedure-Call.
virtual void handleRpcResponse (BaseResponseMessage *msg, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.
virtual void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, int rpcId)
 This method is called if an RPC timeout has been reached.
virtual void handleRpcJoinResponse (JoinResponse *joinResponse)
virtual void handleRpcNotifyResponse (NotifyResponse *notifyResponse)
virtual void handleRpcStabilizeResponse (StabilizeResponse *stabilizeResponse)
virtual void handleRpcFixfingersResponse (FixfingersResponse *fixfingersResponse, double rtt=-1)
virtual void handleRpcPingResponse (PingResponse *pingResponse, int id, double rtt)
virtual void predecessorIsDead ()
virtual void successorIsDead ()

Protected Attributes

int joinRetry
int stabilizeRetry
 // retries before neighbor considered failed
double joinDelay
double stabilizeDelay
 stabilize interval (secs)
double fixfingersDelay
int successorListSize
bool aggressiveJoinMode
 use modified (faster) JOIN protocol
bool extendedFingerTable
unsigned int numFingerCandidates
bool proximityRouting
cMessage * join_timer
cMessage * stabilize_timer
cMessage * fixfingers_timer
int joinCount
int stabilizeCount
int fixfingersCount
int notifyCount
int newsuccessorhintCount
int joinBytesSent
int stabilizeBytesSent
int notifyBytesSent
int fixfingersBytesSent
int newsuccessorhintBytesSent
int state
 current node state
int keyLength
 length of an overlay key in bits
int missingPredecessorStabRequests
 missing StabilizeCall msgs
int missingSuccessorStabResponses
 missing StabilizeResponse msgs
NodeHandle predecessorNode
 predecessor of this node
NodeHandle bootstrapNode
 node used to bootrap
ChordFingerTablefingerTable
 pointer to this node's finger table
ChordSuccessorListsuccessorList
 pointer to this node's successor list

Friends

class ChordSuccessorList


Constructor & Destructor Documentation

Chord::~Chord (  )  [virtual]

00094 {
00095     // destroy self timer messages
00096     cancelEvent(join_timer);
00097     cancelEvent(stabilize_timer);
00098     cancelEvent(fixfingers_timer);
00099 
00100     delete join_timer;
00101     delete stabilize_timer;
00102     delete fixfingers_timer;
00103 }


Member Function Documentation

void Chord::initializeOverlay ( int  stage  )  [virtual]

Initializes derived-class-attributes.


Initializes derived-class-attributes, called by BaseOverlay::initialize(). By default this method is called once. If more stages are needed one can overload numInitStages() and add more stages.

Parameters:
stage the init stage

Reimplemented from BaseOverlay.

Reimplemented in Koorde.

00039 {
00040     // because of IPAddressResolver, we need to wait until interfaces
00041     // are registered, address auto-assignment takes place etc.
00042     if(stage != MIN_STAGE_OVERLAY)
00043         return;
00044 
00045     // fetch some parameters
00046     useCommonAPIforward = par("useCommonAPIforward");
00047     successorListSize = par("successorListSize");
00048     joinRetry = par("joinRetry");
00049     stabilizeRetry = par("stabilizeRetry");
00050     joinDelay = par("joinDelay");
00051     stabilizeDelay = par("stabilizeDelay");
00052     fixfingersDelay = par("fixfingersDelay");
00053     aggressiveJoinMode = par("aggressiveJoinMode");
00054     extendedFingerTable = par("extendedFingerTable");
00055     numFingerCandidates = par("numFingerCandidates");
00056     proximityRouting = par("proximityRouting");
00057 
00058     keyLength = OverlayKey::getLength();
00059     missingPredecessorStabRequests = 0;
00060     missingSuccessorStabResponses = 0;
00061 
00062     // statistics
00063     joinCount = 0;
00064     stabilizeCount = 0;
00065     fixfingersCount = 0;
00066     notifyCount = 0;
00067     newsuccessorhintCount = 0;
00068     joinBytesSent = 0;
00069     stabilizeBytesSent = 0;
00070     notifyBytesSent = 0;
00071     fixfingersBytesSent = 0;
00072     newsuccessorhintBytesSent = 0;
00073 
00074 
00075     // find friend modules
00076     findFriendModules();
00077 
00078     // add some watches
00079     WATCH(predecessorNode);
00080     WATCH(thisNode);
00081     WATCH(bootstrapNode);
00082     WATCH(joinRetry);
00083     WATCH(missingPredecessorStabRequests);
00084     WATCH(missingSuccessorStabResponses);
00085 
00086     // self-messages
00087     join_timer = new cMessage("join_timer");
00088     stabilize_timer = new cMessage("stabilize_timer");
00089     fixfingers_timer = new cMessage("fixfingers_timer");
00090 }

void Chord::receiveChangeNotification ( int  category,
cPolymorphic *  details 
) [virtual]

callback-method for events at the NotificationBoard

Parameters:
category 
details 
Todo:
parameter description, implementation
00107 {
00108     Enter_Method_Silent();
00109     if (category == NF_HOSTPOSITION_UPDATED) {
00110         // get new ip address
00111         thisNode.ip = IPAddressResolver().addressOf(
00112                         parentModule()->parentModule()).get4();
00113 
00114         joinOverlay();
00115     }
00116 }

void Chord::handleTimerEvent ( cMessage *  msg  )  [virtual]

handles self-messages

Parameters:
msg the self-message

Reimplemented from BaseOverlay.

Reimplemented in Koorde.

00224 {
00225     // catch JOIN timer
00226     if (msg->isName("join_timer")) {
00227         handleJoinTimerExpired(msg);
00228     }
00229     // catch STABILIZE timer
00230     else if (msg->isName("stabilize_timer")) {
00231         handleStabilizeTimerExpired(msg);
00232     }
00233     // catch FIX_FINGERS timer
00234     else if (msg->isName("fixfingers_timer")) {
00235         handleFixFingersTimerExpired(msg);
00236     }
00237     // unknown self message
00238     else {
00239         error("Chord::handleTimerEvent(): received self message of "
00240               "unknown type!");
00241     }
00242 }

void Chord::handleUDPMessage ( BaseOverlayMessage *  msg  )  [virtual]

processes messages from underlay

Parameters:
msg message from UDP

Implements BaseOverlay.

Reimplemented in Koorde.

00246 {
00247     ChordMessage* chordMsg = check_and_cast<ChordMessage*>(msg);
00248     switch(chordMsg->getCommand()) {
00249     case NEWSUCCESSORHINT:
00250         handleNewSuccessorHint(chordMsg);
00251         break;
00252     default:
00253         error("handleUDPMessage(): Unknown message type!");
00254         break;
00255     }
00256 
00257     delete chordMsg;
00258 }

void Chord::recordOverlaySentStats ( BaseOverlayMessage *  msg  )  [virtual]

Collect overlay specific sent messages statistics.

This method is called from BaseOverlay::sendMessageToUDP() for every overlay message that is sent by a node. Use this to collect statistical data for overlay protocol specific message types.

Parameters:
msg The overlay message to be sent to the UDP layer

Reimplemented from BaseOverlay.

Reimplemented in Koorde.

00603 {
00604     BaseOverlayMessage* innerMsg;
00605 
00606     if (msg->getType() == OVERLAYROUTE)
00607         innerMsg = dynamic_cast<BaseOverlayMessage*>(msg->encapsulatedMsg());
00608     else
00609         innerMsg = msg;
00610 
00611     switch (innerMsg->getType()) {
00612 
00613     case OVERLAYSIGNALING: {
00614             ChordMessage* chordMsg = dynamic_cast<ChordMessage*>(innerMsg);
00615             switch(chordMsg->getCommand()) {
00616             case NEWSUCCESSORHINT:
00617                 RECORD_STATS(newsuccessorhintCount++; newsuccessorhintBytesSent +=
00618                                  msg->byteLength());
00619                 break;
00620             }
00621             break;
00622         }
00623 
00624     case RPC: {
00625             if ((dynamic_cast<StabilizeCall*>(innerMsg) != NULL) ||
00626                     (dynamic_cast<StabilizeResponse*>(innerMsg) != NULL)) {
00627                 RECORD_STATS(stabilizeCount++; stabilizeBytesSent +=
00628                                  msg->byteLength());
00629             } else if ((dynamic_cast<NotifyCall*>(innerMsg) != NULL) ||
00630                        (dynamic_cast<NotifyResponse*>(innerMsg) != NULL)) {
00631                 RECORD_STATS(notifyCount++; notifyBytesSent +=
00632                                  msg->byteLength());
00633             } else if ((dynamic_cast<FixfingersCall*>(innerMsg) != NULL) ||
00634                        (dynamic_cast<FixfingersResponse*>(innerMsg) != NULL)) {
00635                 RECORD_STATS(fixfingersCount++; fixfingersBytesSent +=
00636                                  msg->byteLength());
00637             } else if ((dynamic_cast<JoinCall*>(innerMsg) != NULL) ||
00638                        (dynamic_cast<JoinResponse*>(innerMsg) != NULL)) {
00639                 RECORD_STATS(joinCount++; joinBytesSent += msg->byteLength());
00640             }
00641             break;
00642         }
00643     }
00644 }

void Chord::finishOverlay (  )  [virtual]

collects statisticts

Reimplemented from BaseOverlay.

Reimplemented in Koorde.

00648 {
00649     // remove this node from the bootstrap list
00650     bootstrapOracle->removePeer(thisNode);
00651 
00652     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00653     if(time == 0) return;
00654 
00655     globalStatistics->addStdDev("Chord: Sent JOIN Messages/s", joinCount / time);
00656     globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Messages/s",
00657                                 newsuccessorhintCount / time);
00658     globalStatistics->addStdDev("Chord: Sent STABILIZE Messages/s", stabilizeCount / time);
00659     globalStatistics->addStdDev("Chord: Sent NOTIFY Messages/s", notifyCount / time);
00660     globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Messages/s", fixfingersCount / time);
00661     globalStatistics->addStdDev("Chord: Sent JOIN Bytes/s", joinBytesSent / time);
00662     globalStatistics->addStdDev("Chord: Sent NEWSUCCESSORHINT Bytes/s",
00663                                 newsuccessorhintBytesSent / time);
00664     globalStatistics->addStdDev("Chord: Sent STABILIZE Bytes/s", stabilizeBytesSent / time);
00665     globalStatistics->addStdDev("Chord: Sent NOTIFY Bytes/s", notifyBytesSent / time);
00666     globalStatistics->addStdDev("Chord: Sent FIX_FINGERS Bytes/s", fixfingersBytesSent / time);
00667 }

void Chord::updateTooltip (  )  [virtual]

updates information shown in tk-environment

Reimplemented in Koorde.

01097 {
01098     if (ev.isGUI()) {
01099         std::stringstream ttString;
01100 
01101         // show our predecessor and successor in tooltip
01102         ttString << predecessorNode << endl << thisNode << endl
01103         << successorList->getSuccessor();
01104 
01105         parentModule()->parentModule()->displayString().
01106         setTagArg("tt", 0, ttString.str().c_str());
01107         parentModule()->displayString().
01108         setTagArg("tt", 0, ttString.str().c_str());
01109         displayString().setTagArg("tt", 0, ttString.str().c_str());
01110 
01111         // draw an arrow to our current successor
01112         showOverlayNeighborArrow(successorList->getSuccessor(), true,
01113                                  "m=m,50,0,50,0;o=red,1");
01114         showOverlayNeighborArrow(predecessorNode, false,
01115                                  "m=m,50,100,50,100;o=green,1");
01116     }
01117 }

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

changes node state

Parameters:
toState state to change to

Reimplemented in Koorde.

00125 {
00126     //
00127     // Defines tasks to be executed when a state change occurs.
00128     //
00129 
00130     switch (toState) {
00131     case INIT:
00132         state = INIT;
00133 
00134         // remove current node handle from the bootstrap list
00135         if(!thisNode.key.isUnspecified()) {
00136             bootstrapOracle->removePeer(thisNode);
00137         }
00138 
00139         // Calculate node's id by hashing its IP address
00140         //  thisNode.key = OverlayKey::sha1(const_cast<char*>(
00141         //                      thisNode.ip.str().c_str()));
00142         // better use random numbers (our ip address might not be random)
00143         // keep old id if INIT gets called twice
00144         if (thisNode.key.isUnspecified()) {
00145             thisNode.key = OverlayKey::random();
00146             callUpdate(thisNode, true);
00147         }
00148 
00149 
00150         // initialize predecessor pointer
00151         predecessorNode = NodeHandle::UNSPECIFIED_NODE;
00152 
00153         // initialize finger table and successor list
00154         initializeFriendModules();
00155 
00156         updateTooltip();
00157 
00158         // debug message
00159         if (debugOutput) {
00160             EV << "CHORD: Node " << thisNode.ip
00161             << " entered INIT stage." << endl;
00162         }
00163         // FIXME: bubble() sometimes doesn't work
00164         parentModule()->parentModule()->bubble("Enter INIT state.");
00165         break;
00166 
00167     case BOOTSTRAP:
00168         state = BOOTSTRAP;
00169 
00170         // initiate bootstrap process
00171         cancelEvent(join_timer);
00172         // workaround: prevent notificationBoard from taking
00173         // ownership of join_timer message
00174         take(join_timer);
00175         scheduleAt(simulation.simTime(), join_timer);
00176 
00177         // debug message
00178         if (debugOutput) {
00179             EV << "CHORD: Node " << thisNode.ip
00180             << " entered BOOTSTRAP stage." << endl;
00181         }
00182         parentModule()->parentModule()->bubble("Enter BOOTSTRAP state.");
00183 
00184         // find a new bootstrap node and enroll to the bootstrap list
00185         bootstrapNode = bootstrapOracle->getBootstrapNode();
00186 
00187         // is this the first node?
00188         if (bootstrapNode.isUnspecified()) {
00189             // create new cord ring
00190             bootstrapNode = thisNode;
00191             changeState(READY);
00192             updateTooltip();
00193         }
00194         break;
00195 
00196     case READY:
00197         state = READY;
00198 
00199         bootstrapOracle->registerPeer(thisNode);
00200 
00201         // initiate stabilization protocol
00202         cancelEvent(stabilize_timer);
00203         scheduleAt(simulation.simTime() + stabilizeDelay, stabilize_timer);
00204 
00205         // initiate finger repair protocol
00206         cancelEvent(fixfingers_timer);
00207         scheduleAt(simulation.simTime() + fixfingersDelay,
00208                    fixfingers_timer);
00209 
00210         // debug message
00211         if (debugOutput) {
00212             EV << "CHORD: Node " << thisNode.ip << " entered READY stage."
00213             << endl;
00214         }
00215         parentModule()->parentModule()->bubble("Enter READY state.");
00216         break;
00217     }
00218 
00219     setReadyIcon(state == READY);
00220 }

void Chord::handleJoinTimerExpired ( cMessage *  msg  )  [protected, virtual]

handle a expired join timer

Parameters:
msg the timer self-message
00672 {
00673     // only process timer, if node is not bootstrapped yet
00674     if (state == READY)
00675         return;
00676 
00677     // enter state BOOTSTRAP
00678     if (state != BOOTSTRAP)
00679         changeState(BOOTSTRAP);
00680 
00681     // change bootstrap node from time to time
00682     joinRetry--;
00683     if (joinRetry == 0) {
00684         joinRetry = par("joinRetry");
00685         changeState(BOOTSTRAP);
00686         return;
00687     }
00688 
00689     // call JOIN RPC
00690     JoinCall* call = new JoinCall("JoinCall");
00691     call->setLength(JOINCALL_L(call));
00692 
00693     sendRpcMessage(bootstrapNode, call, NULL, thisNode.key, -1, joinDelay);
00694 
00695     // schedule next bootstrap process in the case this one fails
00696     cancelEvent(join_timer);
00697     scheduleAt(simulation.simTime() + joinDelay, msg);
00698 }

void Chord::handleStabilizeTimerExpired ( cMessage *  msg  )  [protected, virtual]

handle a expired stabilize timer

Parameters:
msg the timer self-message
00702 {
00703     if (state != READY)
00704         return;
00705 
00706     if (missingPredecessorStabRequests >= stabilizeRetry) {
00707         // predecessor node seems to be dead
00708         // remove it from the predecessor / successor lists
00709         successorList->removeSuccessor(predecessorNode);
00710         predecessorIsDead();
00711 
00712         callUpdate(predecessorNode, false);
00713         predecessorNode = NodeHandle::UNSPECIFIED_NODE;
00714 
00715         missingPredecessorStabRequests = 0;
00716         updateTooltip();
00717     }
00718 
00719     if (missingSuccessorStabResponses >= stabilizeRetry) {
00720         // successor node seems to be dead
00721         // remove it from the predecessor / successor list
00722         successorIsDead();
00723         NodeHandle successor = successorList->popSuccessor();
00724 
00725         // if we had a ring consisting of 2 nodes and our successor seems
00726         // to be dead. Remove also predecessor because the successor
00727         // and predecessor are the same node
00728         if ((!predecessorNode.isUnspecified()) &&
00729                 predecessorNode == successor) {
00730             predecessorIsDead();
00731             callUpdate(predecessorNode, false);
00732             predecessorNode = NodeHandle::UNSPECIFIED_NODE;
00733         }
00734 
00735         missingSuccessorStabResponses = 0;
00736         updateTooltip();
00737 
00738         if (successorList->isEmpty()) {
00739             changeState(INIT);
00740             changeState(BOOTSTRAP);
00741             return;
00742         }
00743     }
00744 
00745     if (!successorList->isEmpty()) {
00746         // call STABILIZE RPC
00747         StabilizeCall* call = new StabilizeCall("StabilizeCall");
00748         call->setLength(STABILIZECALL_L(call));
00749 
00750         sendRpcMessage(successorList->getSuccessor(), call);
00751 
00752         missingPredecessorStabRequests++;
00753         missingSuccessorStabResponses++;
00754     }
00755 
00756     // schedule next stabilization process
00757     cancelEvent(stabilize_timer);
00758     scheduleAt(simulation.simTime() + stabilizeDelay, msg);
00759 }

void Chord::handleFixFingersTimerExpired ( cMessage *  msg  )  [protected, virtual]

handle a expired fix_fingers timer

Parameters:
msg the timer self-message

Reimplemented in Koorde.

00763 {
00764     if ((state != READY) || successorList->isEmpty())
00765         return;
00766 
00767     for (uint nextFinger = 0; nextFinger < thisNode.key.getLength();
00768             nextFinger++) {
00769         // calculate "n + 2^(i - 1)"
00770         OverlayKey offset = OverlayKey::pow2(nextFinger);
00771         OverlayKey lookupKey = thisNode.key + offset;
00772 
00773         // send message only for non-trivial fingers
00774         if (offset > successorList->getSuccessor().key - thisNode.key) {
00775             // call FIXFINGER RPC
00776             FixfingersCall* call = new FixfingersCall("FixfingersCall");
00777             call->setFinger(nextFinger);
00778             call->setLength(FIXFINGERSCALL_L(call));
00779 
00780             sendRpcMessage(NodeHandle::UNSPECIFIED_NODE, call, NULL,
00781                            lookupKey, -1, fixfingersDelay);
00782 
00783         } else {
00784             // let trivial fingers point to the successor node
00785             fingerTable->setFinger(nextFinger, successorList->getSuccessor());
00786         }
00787     }
00788 
00789     // schedule next finger repair process
00790     cancelEvent(fixfingers_timer);
00791     scheduleAt(simulation.simTime() + fixfingersDelay, msg);
00792 }

void Chord::handleNewSuccessorHint ( ChordMessage *  chordMsg  )  [protected, virtual]

handle a received NEWSUCCESSORHINT message

Parameters:
chordMsg the message to process
00796 {
00797     NewSuccessorHintMessage* newSuccessorHintMsg =
00798         check_and_cast<NewSuccessorHintMessage*>(chordMsg);
00799 
00800     // fetch the successor's predecessor
00801     NodeHandle predecessor = newSuccessorHintMsg->getPreNode();
00802 
00803     // is the successor's predecessor a new successor for this node?
00804     if (predecessor.key.isBetween(thisNode.key,
00805                                   successorList->getSuccessor().key)
00806             || (thisNode.key == successorList->getSuccessor().key)) {
00807         // add the successor's predecessor to the successor list
00808         successorList->addSuccessor(predecessor);
00809         updateTooltip();
00810     }
00811 }

NodeVector * Chord::closestPreceedingNode ( const OverlayKey key  )  [protected, virtual]

looks up the finger table and returns the closest preceeding node.

Parameters:
key key to find the closest preceeding node for
Returns:
node vector of the closest preceeding nodes to key
00510 {
00511     NodeHandle tempHandle = NodeHandle::UNSPECIFIED_NODE;
00512 
00513     // find the closest prceeding node in the successor list
00514     for (int j = successorList->getSize() - 1; j >= 0; j--) {
00515         if(successorList->getSuccessor(j).key.isBetweenR(thisNode.key, key)) {
00516             tempHandle = successorList->getSuccessor(j);
00517             break;
00518         }
00519     }
00520 
00521     if(tempHandle.isUnspecified()) {
00522         std::stringstream temp;
00523         temp << "Error in Chord::closestPreceedingNode()!\n" << thisNode.key << "\n" << key;
00524         error("bla");
00525     }
00526 
00527     NodeVector* nextHop;
00528 
00529     for (int i = fingerTable->getSize() - 1; i >= 0; i--) {
00530         if (fingerTable->getFinger(i).key.isBetweenLR(tempHandle.key, key)) {
00531             // is there a closer preceeding node in the successor list?
00532             //for (int j = successorList->getSize() - 1; j >= 0; j--) {
00533                 if(!extendedFingerTable) {
00534                     nextHop = new NodeVector();
00535                     // if (successorList->getSuccessor(j).key.
00536 //                      isBetween(fingerTable->getFinger(i).key, key)) {
00537 //                      nextHop->push_back(successorList->getSuccessor(j));
00538 //                  }                           
00539 //                  else {
00540                         // if no, settle with the node already found
00541                         nextHop->push_back(fingerTable->getFinger(i));
00542                         //}
00543 
00544                         EV << "closestPreceedingNode: node " << thisNode
00545                            << " for key " << key << " finger " 
00546                            << fingerTable->getFinger(i).key << " better than "
00547                            << tempHandle.key << endl;
00548                     return nextHop;
00549                 }
00550                 else {
00551 //                  if (successorList->getSuccessor(j).key.
00552 //                      isBetween(fingerTable->getFinger(i, key)->begin()->key, key)) { //TODO
00553 //                      nextHop = new NodeVector();
00554 //                      nextHop->push_back(successorList->getSuccessor(j));
00555 //                      return nextHop;
00556 //                  }
00557 //                  else {
00558                         // if(*fingerTable->getFinger(i, key)->begin() != fingerTable->getFinger(i))
00559                         //      std::cout << "thisNode.key =\t" << thisNode.key
00560                         //            << "\nfinger =\t" << fingerTable->getFinger(i).key
00561                         //            << "\nused =  \t" << fingerTable->getFinger(i, key)->begin()->key
00562                         //            << "\ndestKey =\t" << key
00563                         //            << "\n" << std::endl;
00564                         return fingerTable->getFinger(i, key);
00565                         //}
00566                 }
00567                 //}
00568         }
00569     }
00570 
00571     nextHop = new NodeVector();
00572 
00573     EV << "no finger found!!!" << endl;
00574 
00575     // if no finger is found lookup the rest of the successor list
00576     for(int i = successorList->getSize() - 1; i >= 0
00577             && nextHop->size() <= numFingerCandidates ; i--) {
00578         if(successorList->getSuccessor(i).key.isBetween(thisNode.key, key)) {
00579             nextHop->push_back(successorList->getSuccessor(i));
00580             //return nextHop;
00581         }
00582     }
00583 
00584     if(nextHop->size() != 0)
00585         return nextHop;
00586 
00587     // if this is the first and only node on the ring, it is responsible
00588     if ((predecessorNode.isUnspecified()) &&
00589         (successorList->getSuccessor() == thisNode)) {
00590         nextHop->push_back(thisNode);
00591         return nextHop;
00592     }
00593 
00594     // if there is still no node found return NodeHandle::UNSPECIFIED_NODE
00595     std::stringstream temp("Error in Chord::closestPreceedingNode()!\n");
00596     temp << thisNode.key << " " << key;
00597     error(temp.str().c_str());
00598     nextHop->push_back(NodeHandle::UNSPECIFIED_NODE);
00599     return nextHop;
00600 }

void Chord::findFriendModules (  )  [protected, virtual]

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

Reimplemented in Koorde.

01076 {
01077     fingerTable = check_and_cast<ChordFingerTable*>
01078                   (parentModule()->submodule("fingerTable"));
01079 
01080     successorList = check_and_cast<ChordSuccessorList*>
01081                     (parentModule()->submodule("successorList"));
01082 }

void Chord::initializeFriendModules (  )  [protected, virtual]

initializes finger table and successor list

Reimplemented in Koorde.

01087 {
01088     // initialize finger table
01089     fingerTable->initializeTable(thisNode.key.getLength(), thisNode, this);
01090 
01091     // initialize successor list
01092     successorList->initializeList(par("successorListSize"), thisNode, this);
01093 }

bool Chord::handleRpc ( BaseCallMessage *  msg  )  [protected, virtual]

Processes Remote-Procedure-Call invokation messages.

Reimplemented from BaseRpc.

Reimplemented in Koorde.

00262 {
00263     if (state != READY) {
00264 //        delete msg;
00265 //        EV << "Chord::handleRpc(): Received RPC call "
00266 //        << "and state != READY!" << endl;
00267         return false;
00268     }
00269 
00270     // delegate messages
00271     RPC_SWITCH_START( msg )
00272     // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00273     RPC_DELEGATE( Join, rpcJoin );
00274     RPC_DELEGATE( Notify, rpcNotify );
00275     RPC_DELEGATE( Stabilize, rpcStabilize );
00276     RPC_DELEGATE( Fixfingers, rpcFixfingers );
00277     RPC_SWITCH_END( )
00278 
00279     return RPC_HANDLED;
00280 }

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

Implements the find node call.

This method simply returns the closest nodes known in the corresponding routing topology.

Parameters:
key The lookup key.
msg A pointer to the BaseRouteMessage or FindNodeCall message of this lookup.
Returns:
NodeVector with closest nodes.

Reimplemented from BaseOverlay.

Reimplemented in Koorde.

00446 {
00447     bool err;
00448     NodeVector* nextHop;
00449 
00450     if (state != READY)
00451         return new NodeVector();
00452 
00453     //     // example code for findNodeExt
00454 
00455     //      if (msg != NULL) {
00456     //          if (!msg->hasObject("findNodeExt")) {
00457     //              ChordFindNodeExtMessage *extMsg =
00458     //                  new ChordFindNodeExtMessage("findNodeExt");
00459     //                  extMsg->setLength(8*10);
00460     //              msg->addObject( extMsg );
00461     //                   }
00462     //
00463     //          ChordFindNodeExtMessage *extMsg =
00464     //              (ChordFindNodeExtMessage*) msg->getObject("findNodeExt");
00465     //
00466     //      cout << "ChordCount: " << extMsg->getChordCount() + 1 << endl;
00467     //
00468     //              extMsg->setChordCount(extMsg->getChordCount() + 1);
00469     //      }
00470 
00471     // if key is unspecified, the message is for this node
00472     if (key.isUnspecified()) {
00473         nextHop = new NodeVector();
00474         nextHop->push_back(thisNode);
00475     }
00476 
00477     // the message is destined for this node
00478     else if (isSiblingFor(thisNode, key, 1, &err)) {
00479         nextHop = new NodeVector();
00480         nextHop->push_back(thisNode);
00481         for (uint i=0; i<successorList->getSize(); i++) {
00482             nextHop->push_back(successorList->getSuccessor(i));
00483         }
00484     }
00485 
00486     // the message destined for our successor
00487     else if (key.isBetweenR(thisNode.key,
00488                             successorList->getSuccessor().key)) {
00489         nextHop = new NodeVector();
00490         nextHop->push_back(successorList->getSuccessor());
00491     }
00492 
00493     // find next hop with finger table and/or successor list
00494     else {
00495         nextHop = closestPreceedingNode(key);
00496     }
00497 
00498     if ((nextHop->size() > 0) && ((*nextHop)[0].key == thisNode.key)) {
00499         if (!isSiblingFor(thisNode, key, 1, &err)) {
00500             std::cout << "aaaaaaaaaaargh!" << endl;
00501             nextHop->clear();
00502             }
00503     }
00504 
00505     return nextHop;
00506 }

void Chord::joinOverlay (  )  [protected, virtual]

See also:
BaseOverlay.cc

Reimplemented from BaseOverlay.

00119 {
00120     changeState(INIT);
00121     changeState(BOOTSTRAP);
00122 }

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

See also:
BaseOverlay.cc

Reimplemented from BaseOverlay.

00366 {
00367     if (key.isUnspecified())
00368         error("Chord::isSiblingFor(): key is unspecified!");
00369 
00370     if (state != READY) {
00371         *err = true;
00372         return false;
00373     }
00374 
00375     if (numSiblings > getMaxNumSiblings()) {
00376         opp_error("Chord::isSiblingFor(): numSiblings too big!");
00377     }
00378     // set default number of siblings to consider
00379     if (numSiblings == -1) numSiblings = getMaxNumSiblings();
00380 
00381     // if this is the first and only node on the ring, it is responsible
00382     if ((predecessorNode.isUnspecified()) && (node == thisNode)) {
00383         if(successorList->isEmpty() || (node.key == key)) {
00384             *err = false;
00385             return true;
00386         } else {
00387             *err = true;
00388             return false;
00389         }
00390     }
00391 
00392     if (key.isBetweenR(predecessorNode.key, thisNode.key)) {
00393         *err = false;
00394         return true;
00395     }
00396 
00397 
00398     NodeHandle prevNode = predecessorNode;
00399     NodeHandle curNode;
00400 
00401     for (int i = -1; i < (int)successorList->getSize();
00402          i++, prevNode = curNode) {
00403 
00404         if (i < 0) {
00405             curNode = thisNode; 
00406         } else {
00407             curNode = successorList->getSuccessor(i);
00408         }
00409 
00410         if (node == curNode) {
00411             // is the message destined for curNode?
00412             if (key.isBetweenR(prevNode.key, curNode.key)) {
00413                 if (numSiblings <= ((int)successorList->getSize() - i)) {
00414                     *err = false;
00415                     return true;
00416                 } else {
00417                     *err = true;
00418                     return false;
00419                 }
00420             } else {
00421                 // the key doesn't directly belong to this node, but
00422                 // the node could be in the replicaSet for this key
00423                 if (numSiblings <= 1) {
00424                     *err = false;
00425                     return false;
00426                 } else {
00427                     // In Chord we don't know if we belong to the
00428                     // replicaSet of one of our predecessors
00429                     *err = true;
00430                     return false;
00431                 }
00432             }
00433         }
00434     }
00435 
00436     // node is not in our neighborSet
00437     *err = true;
00438     return false;
00439 }

int Chord::getMaxNumSiblings (  )  [protected, virtual]

Query the maximum number of siblings (nodes close to a key) that are maintained by this overlay protocol.

Returns:
int number of siblings.

Reimplemented from BaseOverlay.

00352 {
00353     return successorListSize;
00354 }

int Chord::getMaxNumRedundantNodes (  )  [protected, virtual]

Query the maximum number of redundant next hop nodes that are returned by findNode().

Returns:
int number of redundant nodes returned by findNode().

Reimplemented from BaseOverlay.

00357 {
00358     return extendedFingerTable ? numFingerCandidates : 1;
00359 }

void Chord::rpcFixfingers ( FixfingersCall *  call  )  [protected]

Fixfingers Remote-Procedure-Call.

Parameters:
call RPC Parameter Message
01022 {
01023     FixfingersResponse* fixfingersResponse =
01024         new FixfingersResponse("FixfingersResponse");
01025     
01026     fixfingersResponse->setSucNodeArraySize(1);
01027     fixfingersResponse->setSucNode(0, thisNode);
01028 
01029     if(extendedFingerTable) {
01030         fixfingersResponse->setSucNodeArraySize(((successorList->getSize() + 1 < numFingerCandidates + 1)
01031                                                  ? successorList->getSize() + 1 : numFingerCandidates + 1));
01032         for(unsigned int i = 0; i < (((successorList->getSize()) < numFingerCandidates)
01033                                      ? (successorList->getSize()) : numFingerCandidates); i++) {
01034             assert(!successorList->getSuccessor(i).isUnspecified());
01035             fixfingersResponse->setSucNode(i + 1, successorList->getSuccessor(i));
01036         }
01037     }
01038     fixfingersResponse->setFinger(call->getFinger());
01039     fixfingersResponse->setLength(FIXFINGERSRESPONSE_L(fixfingersResponse)); //TODO
01040 
01041     sendRpcResponse(call, fixfingersResponse);
01042 }

void Chord::rpcJoin ( JoinCall *  call  )  [protected]

Join Remote-Procedure-Call.

Parameters:
call RPC Parameter Message
00815 {
00816     NodeHandle requestor = joinCall->getSrcNode();
00817 
00818     // compile successor list
00819     JoinResponse* joinResponse =
00820         new JoinResponse("JoinResponse");
00821 
00822     int sucNum = successorList->getSize();
00823     joinResponse->setSucNum(sucNum);
00824     joinResponse->setSucNodeArraySize(sucNum);
00825 
00826     for (int k = 0; k < sucNum; k++) {
00827         joinResponse->setSucNode(k, successorList->getSuccessor(k));
00828     }
00829 
00830     // sent our predecessor as hint to the joining node
00831     if (predecessorNode.isUnspecified() && successorList->isEmpty()) {
00832         // we are the only node in the ring
00833         joinResponse->setPreNode(thisNode);
00834     } else {
00835         joinResponse->setPreNode(predecessorNode);
00836     }
00837 
00838     joinResponse->setLength(JOINRESPONSE_L(joinResponse));
00839 
00840     sendRpcResponse(joinCall, joinResponse);
00841 
00842     if (aggressiveJoinMode) {
00843         // aggressiveJoinMode differs from standard join operations:
00844         // 1. set our predecessor pointer to the joining node
00845         // 2. send our old predecessor as hint in JoinResponse msgs
00846         // 3. send a NEWSUCCESSORHINT to our old predecessor to update
00847         //    its successor pointer
00848 
00849         // send NEWSUCCESSORHINT to our old predecessor
00850 
00851         if (!predecessorNode.isUnspecified()) {
00852             NewSuccessorHintMessage* newSuccessorHintMsg =
00853                 new NewSuccessorHintMessage("NEWSUCCESSORHINT");
00854             newSuccessorHintMsg->setCommand(NEWSUCCESSORHINT);
00855 
00856             newSuccessorHintMsg->setSrcNode(thisNode);
00857             newSuccessorHintMsg->setPreNode(requestor);
00858             newSuccessorHintMsg->setLength(
00859                 NEWSUCCESSORHINT_L(newSuccessorHintMsg));
00860 
00861             sendMessageToUDP(predecessorNode, newSuccessorHintMsg);
00862         }
00863 
00864         if (predecessorNode.isUnspecified() || (predecessorNode != requestor)) {
00865             // send update to application if we've got a new predecessor
00866             if (!predecessorNode.isUnspecified()) {
00867                 callUpdate(predecessorNode, false);
00868             }
00869             callUpdate(requestor, true);
00870 
00871             // the requestor is our new predecessor
00872             predecessorNode = requestor;
00873         }
00874     }
00875 
00876     // if we don't have a successor, the requestor is also our new successor
00877     if (successorList->isEmpty())
00878         successorList->addSuccessor(requestor);
00879 
00880     updateTooltip();
00881 }

void Chord::rpcNotify ( NotifyCall *  call  )  [protected]

NOTIFY Remote-Procedure-Call.

Parameters:
call RPC Parameter Message

Reimplemented in Koorde.

00965 {
00966     // our predecessor seems to be alive
00967     missingPredecessorStabRequests = 0;
00968 
00969     NodeHandle newPredecessor = call->getSrcNode();
00970 
00971     // is the new predecessor closer than the current one?
00972     if (predecessorNode.isUnspecified() ||
00973             newPredecessor.key.isBetween(predecessorNode.key, thisNode.key)) {
00974 
00975         if ((predecessorNode.isUnspecified()) ||
00976             (newPredecessor != predecessorNode)) {
00977             // send update to application if we've got a new predecessor
00978             if (!predecessorNode.isUnspecified()) {
00979                 callUpdate(predecessorNode, false);
00980             }
00981             callUpdate(newPredecessor, true);
00982 
00983             // set up new predecessor
00984             predecessorNode = newPredecessor;
00985             updateTooltip();
00986         }
00987    }
00988 
00989     // compile NOTIFY response
00990     NotifyResponse* notifyResponse = new NotifyResponse("NotifyResponse");
00991 
00992     int sucNum = successorList->getSize();
00993     notifyResponse->setSucNum(sucNum);
00994     notifyResponse->setSucNodeArraySize(sucNum);
00995 
00996     for (int k = 0; k < sucNum; k++) {
00997         notifyResponse->setSucNode(k, successorList->getSuccessor(k));
00998     }
00999 
01000     notifyResponse->setLength(NOTIFYRESPONSE_L(notifyResponse));
01001 
01002     sendRpcResponse(call, notifyResponse);
01003 }

void Chord::rpcStabilize ( StabilizeCall *  call  )  [protected]

STABILIZE Remote-Procedure-Call.

Parameters:
call RPC Parameter Message
00926 {
00927     // our predecessor seems to be alive
00928     missingPredecessorStabRequests = 0;
00929 
00930     // reply with StabilizeResponse message
00931     StabilizeResponse* stabilizeResponse =
00932         new StabilizeResponse("StabilizeResponse");
00933     stabilizeResponse->setPreNode(predecessorNode);
00934     stabilizeResponse->setLength(STABILIZERESPONSE_L(stabilizeResponse));
00935 
00936     sendRpcResponse(call, stabilizeResponse);
00937 }

void Chord::handleRpcResponse ( BaseResponseMessage *  msg,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

This method is called if an RPC response has been received.

Parameters:
msg The response message.
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

Reimplemented in Koorde.

00284 {
00285     RPC_SWITCH_START(msg)
00286     RPC_ON_RESPONSE( Ping ) {
00287         handleRpcPingResponse(_PingResponse, rpcId, rtt);
00288         EV << "Ping RPC Response received: id=" << rpcId
00289            << " msg=" << *_PingResponse << " rtt=" << rtt << endl;
00290         break;
00291     }
00292     RPC_ON_RESPONSE( Join ) {
00293         handleRpcJoinResponse(_JoinResponse);
00294         EV << "Join RPC Response received: id=" << rpcId
00295            << " msg=" << *_JoinResponse << " rtt=" << rtt << endl;
00296         break;
00297     }
00298     RPC_ON_RESPONSE( Notify ) {
00299         handleRpcNotifyResponse(_NotifyResponse);
00300         EV << "Notify RPC Response received: id=" << rpcId
00301            << " msg=" << *_NotifyResponse << " rtt=" << rtt << endl;
00302         break;
00303     }
00304     RPC_ON_RESPONSE( Stabilize ) {
00305         handleRpcStabilizeResponse(_StabilizeResponse);
00306         EV << "Stabilize RPC Response received: id=" << rpcId
00307            << " msg=" << *_StabilizeResponse << " rtt=" << rtt << endl;
00308         break;
00309     }
00310     RPC_ON_RESPONSE( Fixfingers ) {
00311         handleRpcFixfingersResponse(_FixfingersResponse, rtt);
00312         EV << "Fixfingers RPC Response received: id=" << rpcId
00313            << " msg=" << *_FixfingersResponse << " rtt=" << rtt << endl;
00314         break;
00315     }
00316     RPC_SWITCH_END( )
00317 }

void Chord::handleRpcTimeout ( BaseCallMessage *  msg,
const TransportAddress dest,
int  rpcId 
) [protected, virtual]

This method is called if an RPC timeout has been reached.

Parameters:
msg The original RPC message.
dest The destination of the RPC
rpcId The RPC id.

Reimplemented from RpcListener.

00321 {
00322     RPC_SWITCH_START(msg)
00323     RPC_ON_CALL( FindNode ) {
00324         EV << "FindNode RPC Call timed out: id=" << rpcId
00325         << " msg=" << *_FindNodeCall << endl;
00326         break;
00327     }
00328     RPC_ON_CALL( Join ) {
00329         EV << "Join RPC Call timed out: id=" << rpcId
00330         << " msg=" << *_JoinCall << endl;
00331         break;
00332     }
00333     RPC_ON_CALL( Notify ) {
00334         EV << "Notify RPC Call timed out: id=" << rpcId
00335         << " msg=" << *_NotifyCall << endl;
00336         break;
00337     }
00338     RPC_ON_CALL( Stabilize ) {
00339         EV << "Stabilize RPC Call timed out: id=" << rpcId
00340         << " msg=" << *_StabilizeCall << endl;
00341         break;
00342     }
00343     RPC_ON_CALL( Fixfingers ) {
00344         EV << "Fixfingers RPC Call timed out: id=" << rpcId
00345         << " msg=" << *_FixfingersCall << endl;
00346         break;
00347     }
00348     RPC_SWITCH_END( )
00349 }

void Chord::handleRpcJoinResponse ( JoinResponse *  joinResponse  )  [protected, virtual]

Todo:
check commented out addSuccessor (Schenk)

Reimplemented in Koorde.

00884 {
00885     // determine the numer of successor nodes to add
00886     int sucNum = successorListSize - 1;
00887 
00888     if (joinResponse->getSucNum() < successorListSize - 1) {
00889         sucNum = joinResponse->getSucNum();
00890     }
00891 
00892     // add successor node(s)
00893     for (int k = 0; k < sucNum; k++) {
00894         NodeHandle successor = joinResponse->getSucNode(k);
00895         successorList->addSuccessor(successor);
00896     }
00897 
00898 // \todo {check commented out addSuccessor (Schenk)}
00899 //successorList->addSuccessor(joinResponse->getSrcNode());
00900 
00901     // the sender of this message is our new successor
00902     successorList->addSuccessor(joinResponse->getSrcNode());
00903 
00904     // in aggressiveJoinMode: use hint in JoinResponse
00905     // to set our new predecessor
00906     if (aggressiveJoinMode) {
00907         predecessorNode = joinResponse->getPreNode();
00908         callUpdate(predecessorNode, true);
00909     }
00910 
00911     updateTooltip();
00912 
00913     changeState(READY);
00914 
00915     // immediate stabilization protocol
00916     cancelEvent(stabilize_timer);
00917     scheduleAt(simulation.simTime(), stabilize_timer);
00918 
00919     // immediate finger repair protocol
00920     cancelEvent(fixfingers_timer);
00921     scheduleAt(simulation.simTime(), fixfingers_timer);
00922 }

void Chord::handleRpcNotifyResponse ( NotifyResponse *  notifyResponse  )  [protected, virtual]

Reimplemented in Koorde.

01007 {
01008     if (successorList->getSuccessor() != notifyResponse->getSrcNode()) {
01009         EV << "Chord::handleRpcNotifyResponse: The srcNode of the received "
01010         << "NotifyResponse is not our current successor!" << endl;
01011         return;
01012     }
01013 
01014     // replace our successor list by our successor's successor list
01015     successorList->updateList(notifyResponse);
01016 
01017     updateTooltip();
01018 }

void Chord::handleRpcStabilizeResponse ( StabilizeResponse *  stabilizeResponse  )  [protected, virtual]

Reimplemented in Koorde.

00940 {
00941     // our successor seems to be alive
00942     missingSuccessorStabResponses = 0;
00943 
00944     // fetch the successor's predecessor
00945     NodeHandle predecessor = stabilizeResponse->getPreNode();
00946 
00947     // is the successor's predecessor a new successor for this node?
00948     if (successorList->isEmpty() ||
00949             predecessor.key.isBetween(thisNode.key,
00950                                       successorList->getSuccessor().key)) {
00951         // add the successor's predecessor to the successor list
00952         successorList->addSuccessor(predecessor);
00953         updateTooltip();
00954     }
00955 
00956     // compile NOTIFY RPC
00957     NotifyCall* notifyCall = new NotifyCall("NotifyCall");
00958     notifyCall->setLength(NOTIFYCALL_L(notifyCall));
00959 
00960     sendRpcMessage(successorList->getSuccessor(), notifyCall);
00961 }

void Chord::handleRpcFixfingersResponse ( FixfingersResponse *  fixfingersResponse,
double  rtt = -1 
) [protected, virtual]

01046 {
01047     // set new finger pointer#
01048     if(!extendedFingerTable)
01049         fingerTable->setFinger(fixfingersResponse->getFinger(), fixfingersResponse->getSucNode(0));
01050 
01051     else {
01052         Successors successors;
01053         successors.insert(std::make_pair(rtt, fixfingersResponse->getSucNode(0)));
01054 
01055         for(unsigned int i = 1; i < fixfingersResponse->getSucNodeArraySize(); i++) {
01056             if(fixfingersResponse->getSucNode(i).isUnspecified())
01057                 continue;
01058             if(fixfingersResponse->getSucNode(i) == thisNode)
01059                 break;
01060             successors.insert(std::make_pair(DBL_MAX, fixfingersResponse->getSucNode(i)));
01061             if(proximityRouting)
01062                 pingNode(fixfingersResponse->getSucNode(i), -1, 0, NULL, NULL,
01063                          fixfingersResponse->getFinger());
01064         }
01065         fingerTable->setFinger(fixfingersResponse->getFinger(), successors);
01066     }
01067 }

void Chord::handleRpcPingResponse ( PingResponse *  pingResponse,
int  id,
double  rtt 
) [protected, virtual]

01070 {
01071     fingerTable->updateFinger(id, pingResponse->getSrcNode(), rtt);
01072 }

void Chord::predecessorIsDead (  )  [protected, virtual]

Reimplemented in Koorde.

01119 { };

void Chord::successorIsDead (  )  [protected, virtual]

Reimplemented in Koorde.

01120 { };


Friends And Related Function Documentation

friend class ChordSuccessorList [friend]


Member Data Documentation

int Chord::joinRetry [protected]

int Chord::stabilizeRetry [protected]

// retries before neighbor considered failed

double Chord::joinDelay [protected]

double Chord::stabilizeDelay [protected]

stabilize interval (secs)

double Chord::fixfingersDelay [protected]

int Chord::successorListSize [protected]

bool Chord::aggressiveJoinMode [protected]

use modified (faster) JOIN protocol

bool Chord::extendedFingerTable [protected]

unsigned int Chord::numFingerCandidates [protected]

bool Chord::proximityRouting [protected]

cMessage* Chord::join_timer [protected]

cMessage* Chord::stabilize_timer [protected]

cMessage* Chord::fixfingers_timer [protected]

int Chord::joinCount [protected]

int Chord::stabilizeCount [protected]

int Chord::fixfingersCount [protected]

int Chord::notifyCount [protected]

int Chord::newsuccessorhintCount [protected]

int Chord::joinBytesSent [protected]

int Chord::stabilizeBytesSent [protected]

int Chord::notifyBytesSent [protected]

int Chord::fixfingersBytesSent [protected]

int Chord::newsuccessorhintBytesSent [protected]

int Chord::state [protected]

current node state

int Chord::keyLength [protected]

length of an overlay key in bits

int Chord::missingPredecessorStabRequests [protected]

missing StabilizeCall msgs

int Chord::missingSuccessorStabResponses [protected]

missing StabilizeResponse msgs

NodeHandle Chord::predecessorNode [protected]

predecessor of this node

NodeHandle Chord::bootstrapNode [protected]

node used to bootrap

ChordFingerTable* Chord::fingerTable [protected]

pointer to this node's finger table

ChordSuccessorList* Chord::successorList [protected]

pointer to this node's successor list


The documentation for this class was generated from the following files:
Generated on Tue Jul 24 16:51:18 2007 for ITM OverSim by  doxygen 1.5.1