Koorde overlay module. More...
#include <Koorde.h>
Public Member Functions | |
virtual | ~Koorde () |
virtual void | initializeOverlay (int stage) |
Initializes derived-class-attributes. | |
virtual void | handleTimerEvent (cMessage *msg) |
virtual void | handleUDPMessage (BaseOverlayMessage *msg) |
Processes messages from underlay. | |
virtual void | recordOverlaySentStats (BaseOverlayMessage *msg) |
Collect overlay specific sent messages statistics. | |
virtual void | finishOverlay () |
collects statistical data in derived class | |
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) |
This method is called if an RPC response has been received. | |
virtual void | handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey) |
This method is called if an RPC timeout has been reached. | |
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 | |
NodeVector * | findNode (const OverlayKey &key, int numRedundantNodes, int numSiblings, BaseOverlayMessage *msg) |
Implements the find node call. | |
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 NodeHandle & | walkDeBruijnList (const OverlayKey &key) |
Given a key the function checks if the key falls between two nodes in the de Bruijn list. | |
virtual const NodeHandle & | walkSuccessorList (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) |
Handles a failed node. | |
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 | |
NodeHandle * | deBruijnNodes |
List of de Bruijn nodes. | |
NodeHandle | deBruijnNode |
Handle to our de Bruijn node. | |
cMessage * | deBruijn_timer |
timer for periodic de bruijn stabilization |
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
Definition at line 50 of file Koorde.h.
oversim::Koorde::~Koorde | ( | ) | [virtual] |
Definition at line 74 of file Koorde.cc.
00075 { 00076 cancelAndDelete(deBruijn_timer); 00077 }
void oversim::Koorde::changeState | ( | int | state | ) | [protected, virtual] |
changes node state
state | state to change to |
Reimplemented from oversim::Chord.
Definition at line 79 of file Koorde.cc.
Referenced by handleDeBruijnTimeout().
00080 { 00081 Chord::changeState(toState); 00082 00083 switch(state) { 00084 case INIT: 00085 // init de Bruijn nodes 00086 deBruijnNode = NodeHandle::UNSPECIFIED_NODE; 00087 00088 for (int i=0; i < deBruijnListSize; i++) { 00089 deBruijnNodes[i] = NodeHandle::UNSPECIFIED_NODE; 00090 } 00091 00092 updateTooltip(); 00093 break; 00094 case BOOTSTRAP: 00095 if (setupDeBruijnBeforeJoin) { 00096 // setup de bruijn node before joining the ring 00097 cancelEvent(join_timer); 00098 cancelEvent(deBruijn_timer); 00099 scheduleAt(simTime(), deBruijn_timer); 00100 } else if (setupDeBruijnAtJoin) { 00101 cancelEvent(deBruijn_timer); 00102 scheduleAt(simTime(), deBruijn_timer); 00103 } 00104 break; 00105 case READY: 00106 // init de Bruijn Protocol 00107 cancelEvent(deBruijn_timer); 00108 scheduleAt(simTime(), deBruijn_timer); 00109 00110 // since we don't need the fixfingers protocol in Koorde cancel timer 00111 cancelEvent(fixfingers_timer); 00112 break; 00113 default: 00114 break; 00115 } 00116 00117 }
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
destKey | The destination key | |
findNodeExt | The FindNodeExtensionMessage |
Definition at line 473 of file Koorde.cc.
Referenced by findNode().
00475 { 00476 if (findNodeExt->getRouteKey().isUnspecified()) { 00477 if (!deBruijnNode.isUnspecified()) { 00478 int step; 00479 findNodeExt->setRouteKey(findStartKey(thisNode.getKey(), 00480 successorList->getSuccessor().getKey(), destKey, 00481 step)); 00482 findNodeExt->setStep(step); 00483 } else { 00484 breakLookup = true; 00485 return successorList->getSuccessor(); 00486 } 00487 } 00488 00489 // check if the route key falls in our responsibility or 00490 // else forward the message to our successor 00491 if (findNodeExt->getRouteKey().isBetweenR(thisNode.getKey(), 00492 successorList->getSuccessor().getKey())) { 00493 if ((unsigned int)findNodeExt->getStep() > destKey.getLength()) 00494 error("Koorde::findDeBruijnHop - Bounding error: " 00495 "trying to get non existing bit out of overlay key!"); 00496 00497 // update the route key 00498 OverlayKey add = OverlayKey(destKey.getBit(destKey.getLength() - 00499 findNodeExt->getStep())); 00500 for (int i = 1; i < shiftingBits; i++) { 00501 add = (add << 1) + OverlayKey(destKey.getBit(destKey.getLength() - 00502 findNodeExt->getStep() - i)); 00503 } 00504 00505 OverlayKey routeKey = (findNodeExt->getRouteKey()<<shiftingBits) + add; 00506 findNodeExt->setRouteKey(routeKey); 00507 findNodeExt->setStep(findNodeExt->getStep() + shiftingBits); 00508 00509 if (deBruijnNode.isUnspecified()) { 00510 breakLookup = true; 00511 if (useSucList) 00512 return walkSuccessorList(findNodeExt->getRouteKey()); 00513 else 00514 return successorList->getSuccessor(); 00515 } 00516 00517 // check if the new route key falls between our 00518 // de Bruijn node and its successor 00519 if (deBruijnNumber > 0) { 00520 if (findNodeExt->getRouteKey().isBetweenR(deBruijnNode.getKey(), 00521 deBruijnNodes[0].getKey())) { 00522 return deBruijnNode; 00523 } else { 00524 // otherwise check if the route key falls between 00525 // our de Bruijn successors 00526 NodeHandle nextHop = walkDeBruijnList(findNodeExt-> 00527 getRouteKey()); 00528 return nextHop; 00529 } 00530 } else { 00531 return deBruijnNode; 00532 } 00533 } else { 00534 breakLookup = true; 00535 // if optimization is set search the successor list and 00536 // de bruijn node to find "good" next hop 00537 if (useSucList) { 00538 if (deBruijnNode.isUnspecified()) { 00539 return walkSuccessorList(findNodeExt->getRouteKey()); 00540 } else { 00541 NodeHandle tmpHandle = 00542 walkSuccessorList(findNodeExt->getRouteKey()); 00543 00544 // todo: optimization - check complete deBruijnList 00545 if (deBruijnNode.getKey().isBetween(tmpHandle.getKey(), 00546 findNodeExt->getRouteKey())) { 00547 return deBruijnNode; 00548 } else { 00549 return tmpHandle; 00550 } 00551 } 00552 } else 00553 return successorList->getSuccessor(); 00554 } 00555 }
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.
00765 { 00766 successorList = check_and_cast<ChordSuccessorList*> 00767 (getParentModule()->getSubmodule("successorList")); 00768 }
NodeVector * oversim::Koorde::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. If the node is a sibling for this key (isSiblingFor(key) = true), this method returns all numSiblings siblings, with the closest neighbor to the key first.
key | The lookup key. | |
numRedundantNodes | Maximum number of next hop nodes to return. | |
numSiblings | number of siblings to return | |
msg | A pointer to the BaseRouteMessage or FindNodeCall message of this lookup. |
Reimplemented from oversim::Chord.
Definition at line 405 of file Koorde.cc.
00409 { 00410 // TODO: return redundant nodes for iterative routing 00411 // TODO: try to always calculate optimal routing key (if e.g. 00412 // the originator didn't have its deBruijnNode set already, the 00413 // routing key may be very far away on the ring) 00414 NodeVector* nextHop = new NodeVector(); 00415 KoordeFindNodeExtMessage *findNodeExt = NULL; 00416 00417 if (state != READY) 00418 return nextHop; 00419 00420 if (msg != NULL) { 00421 if (!msg->hasObject("findNodeExt")) { 00422 findNodeExt = new KoordeFindNodeExtMessage("findNodeExt"); 00423 findNodeExt->setRouteKey(OverlayKey::UNSPECIFIED_KEY); 00424 findNodeExt->setStep(1); 00425 findNodeExt->setBitLength(KOORDEFINDNODEEXTMESSAGE_L); 00426 msg->addObject( findNodeExt ); 00427 } 00428 00429 findNodeExt = (KoordeFindNodeExtMessage*) msg->getObject("findNodeExt"); 00430 } 00431 00432 if (key.isUnspecified()) { 00433 error("Koorde::findNode() - direct Messaging is no longer in use."); 00434 } else if (key.isBetweenR(predecessorNode.getKey(), thisNode.getKey())) { 00435 // the message is destined for this node 00436 nextHop->push_back(thisNode); 00437 } else if (key.isBetweenR(thisNode.getKey(), 00438 successorList->getSuccessor().getKey())){ 00439 // the message destined for our successor 00440 nextHop->push_back(successorList->getSuccessor()); 00441 } else { 00442 // if useOtherLookup is enabled we try to use 00443 // our successor list to get to the key 00444 if (useOtherLookup) { 00445 NodeHandle tmpNode = walkSuccessorList(key); 00446 if (tmpNode != 00447 successorList->getSuccessor(successorList->getSize() - 1)) { 00448 nextHop->push_back(tmpNode); 00449 } else { 00450 NodeHandle tmpHandle = findDeBruijnHop(key, findNodeExt); 00451 if (tmpHandle != thisNode || breakLookup) { 00452 nextHop->push_back(tmpHandle); 00453 breakLookup = false; 00454 } else { 00455 return findNode(key, numRedundantNodes, numSiblings, msg); 00456 } 00457 } 00458 } else { 00459 // find next hop using either the de Bruijn node and 00460 // its successors or our own successors 00461 NodeHandle tmpHandle = findDeBruijnHop(key, findNodeExt); 00462 if (tmpHandle != thisNode || breakLookup) { 00463 nextHop->push_back(tmpHandle); 00464 breakLookup = false; 00465 } else { 00466 return findNode(key, numRedundantNodes, numSiblings, msg); 00467 } 00468 } 00469 } 00470 return nextHop; 00471 }
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
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 |
Definition at line 664 of file Koorde.cc.
Referenced by findDeBruijnHop().
00668 { 00669 OverlayKey diffKey, newStart, tmpDest, newKey, powKey; 00670 int nBits; 00671 00672 if (startKey == endKey) 00673 return startKey; 00674 00675 diffKey = endKey - startKey; 00676 nBits = diffKey.log_2(); 00677 00678 if (nBits < 0) { 00679 nBits = 0; 00680 } 00681 00682 while ((startKey.getLength() - nBits) % shiftingBits != 0) { 00683 nBits--; 00684 } 00685 00686 step = nBits + 1; 00687 00688 #if 0 00689 // TODO: work in progress to find better start key 00690 uint shared; 00691 for (shared = 0; shared < (startKey.getLength() - nBits); shared += shiftingBits) { 00692 if (destKey.sharedPrefixLength(startKey << shared) >= (startKey.getLength() - nBits - shared)) { 00693 break; 00694 } 00695 } 00696 00697 uint nBits2 = startKey.getLength() - shared; 00698 00699 newStart = (startKey >> nBits2) << nBits2; 00700 00701 tmpDest = destKey >> (destKey.getLength() - nBits2); 00702 newKey = tmpDest + newStart; 00703 00704 std::cout << "startKey: " << startKey.toString(2) << endl 00705 << "endKey : " << endKey.toString(2) << endl 00706 << "diff : " << (endKey-startKey).toString(2) << endl 00707 << "newKey : " << newKey.toString(2) << endl 00708 << "destKey : " << destKey.toString(2) << endl 00709 << "nbits : " << nBits << endl 00710 << "nbits2 : " << nBits2 << endl; 00711 00712 // is the new constructed route key bigger than our start key return it 00713 if (newKey.isBetweenR(startKey, endKey)) { 00714 std::cout << "HIT" << endl; 00715 return newKey; 00716 } else { 00717 nBits2 -= shiftingBits; 00718 newStart = (startKey >> nBits2) << nBits2; 00719 00720 tmpDest = destKey >> (destKey.getLength() - nBits2); 00721 newKey = tmpDest + newStart; 00722 00723 if (newKey.isBetweenR(startKey, endKey)) { 00724 std::cout << "startKey: " << startKey.toString(2) << endl 00725 << "endKey : " << endKey.toString(2) << endl 00726 << "diff : " << (endKey-startKey).toString(2) << endl 00727 << "newKey : " << newKey.toString(2) << endl 00728 << "destKey : " << destKey.toString(2) << endl 00729 << "nbits : " << nBits << endl 00730 << "nbits2 : " << nBits2 << endl; 00731 std::cout << "HIT2" << endl; 00732 return newKey; 00733 } 00734 } 00735 00736 std::cout << "MISS" << endl; 00737 #endif 00738 00739 newStart = (startKey >> nBits) << nBits; 00740 00741 tmpDest = destKey >> (destKey.getLength() - nBits); 00742 newKey = tmpDest + newStart; 00743 00744 // is the new constructed route key bigger than our start key return it 00745 if (newKey.isBetweenR(startKey, endKey)) { 00746 return newKey; 00747 } 00748 00749 // If the part of the destination key smaller than the one of 00750 // the original key add pow(nBits) (this is the first bit where 00751 // the start key and end key differ) to the new constructed key 00752 // and check if it's between start and end key. 00753 newKey += powKey.pow2(nBits); 00754 00755 if (newKey.isBetweenR(startKey, endKey)) { 00756 return newKey; 00757 } else { 00758 // this part should not be called 00759 throw cRuntimeError("Koorde::findStartKey(): Invalid start key"); 00760 return OverlayKey::UNSPECIFIED_KEY; 00761 } 00762 }
void oversim::Koorde::finishOverlay | ( | ) | [virtual] |
collects statistical data in derived class
Reimplemented from oversim::Chord.
Definition at line 626 of file Koorde.cc.
00627 { 00628 // statistics 00629 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime); 00630 00631 if (time >= GlobalStatistics::MIN_MEASURED) { 00632 globalStatistics->addStdDev("Koorde: Sent DEBRUIJN Messages/s", 00633 deBruijnCount / time); 00634 globalStatistics->addStdDev("Koorde: Sent DEBRUIJN Bytes/s", 00635 deBruijnBytesSent / time); 00636 } 00637 00638 Chord::finishOverlay(); 00639 }
void oversim::Koorde::handleDeBruijnTimeout | ( | DeBruijnCall * | deBruijnCall | ) | [protected, virtual] |
handle a DEBRUIJN timeout
deBruijnCall | the message which timed out |
Definition at line 392 of file Koorde.cc.
Referenced by handleRpcTimeout().
00393 { 00394 if (setupDeBruijnBeforeJoin && (state == BOOTSTRAP)) { 00395 // failed to set initial de bruijn node 00396 // -> get a new bootstrap node and try again 00397 changeState(BOOTSTRAP); 00398 return; 00399 } 00400 00401 cancelEvent(deBruijn_timer); 00402 scheduleAt(simTime(), deBruijn_timer); 00403 }
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().
00165 { 00166 OverlayKey lookup = thisNode.getKey() << shiftingBits; 00167 00168 if (state == READY) { 00169 if (successorList->getSize() > 0) { 00170 // look for some nodes before our actual de-bruijn key 00171 // to have redundancy if our de-bruijn node fails 00172 lookup -= (successorList->getSuccessor(successorList->getSize() / 00173 2).getKey() - thisNode.getKey()); 00174 } 00175 00176 if (lookup.isBetweenR(thisNode.getKey(), 00177 successorList->getSuccessor().getKey()) 00178 || successorList->isEmpty()) { 00179 00180 int sucNum = successorList->getSize(); 00181 if (sucNum > deBruijnListSize) 00182 sucNum = deBruijnListSize; 00183 00184 deBruijnNode = thisNode; 00185 for (int i = 0; i < sucNum; i++) { 00186 deBruijnNodes[i] = successorList->getSuccessor(i); 00187 deBruijnNumber = i+1; 00188 } 00189 00190 updateTooltip(); 00191 } else if (lookup.isBetweenR(predecessorNode.getKey(), 00192 thisNode.getKey())) { 00193 int sucNum = successorList->getSize(); 00194 if ((sucNum + 1) > deBruijnListSize) 00195 sucNum = deBruijnListSize - 1; 00196 00197 deBruijnNode = predecessorNode; 00198 deBruijnNodes[0] = thisNode; 00199 for (int i = 0; i < sucNum; i++) { 00200 deBruijnNodes[i+1] = successorList->getSuccessor(i); 00201 deBruijnNumber = i+2; 00202 } 00203 00204 updateTooltip(); 00205 } else { 00206 DeBruijnCall* call = new DeBruijnCall("DeBruijnCall"); 00207 call->setDestKey(lookup); 00208 call->setBitLength(DEBRUIJNCALL_L(call)); 00209 00210 sendRouteRpcCall(OVERLAY_COMP, deBruijnNode, 00211 call->getDestKey(), call, NULL, 00212 DEFAULT_ROUTING); 00213 } 00214 00215 cancelEvent(deBruijn_timer); 00216 scheduleAt(simTime() + deBruijnDelay, deBruijn_timer); 00217 } else { 00218 if (setupDeBruijnBeforeJoin || setupDeBruijnAtJoin) { 00219 DeBruijnCall* call = new DeBruijnCall("DeBruijnCall"); 00220 call->setDestKey(lookup); 00221 call->setBitLength(DEBRUIJNCALL_L(call)); 00222 00223 sendRouteRpcCall(OVERLAY_COMP, bootstrapNode, call->getDestKey(), 00224 call, NULL, DEFAULT_ROUTING); 00225 00226 scheduleAt(simTime() + deBruijnDelay, deBruijn_timer); 00227 } 00228 } 00229 }
bool oversim::Koorde::handleFailedNode | ( | const TransportAddress & | failed | ) | [protected, virtual] |
Handles a failed node.
This method is called whenever a node given by findNode() was unreachable. The default implementation does nothing at all.
failed | the failed node |
Reimplemented from oversim::Chord.
Definition at line 130 of file Koorde.cc.
00131 { 00132 if (!deBruijnNode.isUnspecified()) { 00133 if (failed == deBruijnNode) { 00134 deBruijnNode = deBruijnNodes[0]; 00135 for (int i = 0; i < deBruijnNumber - 1; i++) { 00136 deBruijnNodes[i] = deBruijnNodes[i+1]; 00137 } 00138 00139 if (deBruijnNumber > 0) { 00140 deBruijnNodes[deBruijnNumber - 1] = NodeHandle::UNSPECIFIED_NODE; 00141 --deBruijnNumber; 00142 } 00143 } else { 00144 bool removed = false; 00145 for (int i = 0; i < deBruijnNumber - 1; i++) { 00146 if ((!deBruijnNodes[i].isUnspecified()) && 00147 (failed == deBruijnNodes[i])) { 00148 removed = true; 00149 } 00150 if (removed || 00151 ((!deBruijnNodes[deBruijnNumber - 1].isUnspecified()) 00152 && failed == deBruijnNodes[deBruijnNumber - 1])) { 00153 deBruijnNodes[deBruijnNumber - 1] = 00154 NodeHandle::UNSPECIFIED_NODE; 00155 --deBruijnNumber; 00156 } 00157 } 00158 } 00159 } 00160 00161 return Chord::handleFailedNode(failed); 00162 }
bool oversim::Koorde::handleRpcCall | ( | BaseCallMessage * | msg | ) | [protected, virtual] |
handle an expired fix_fingers timer (dummy function)
msg | the timer self-message |
Reimplemented from oversim::Chord.
Definition at line 245 of file Koorde.cc.
00246 { 00247 if (state == READY) { 00248 // delegate messages 00249 RPC_SWITCH_START( msg ) 00250 RPC_DELEGATE( DeBruijn, handleRpcDeBruijnRequest ); 00251 RPC_SWITCH_END( ) 00252 00253 if (RPC_HANDLED) return true; 00254 } else { 00255 EV << "[Koorde::handleRpcCall() @ " << thisNode.getAddress() 00256 << " (" << thisNode.getKey().toString(16) << ")]\n" 00257 << " Received RPC call and state != READY!" 00258 << endl; 00259 } 00260 00261 return Chord::handleRpcCall(msg); 00262 }
void oversim::Koorde::handleRpcDeBruijnRequest | ( | DeBruijnCall * | deBruinCall | ) | [protected, virtual] |
handle a received DEBRUIJN request
deBruinCall | the message to process |
Definition at line 328 of file Koorde.cc.
Referenced by handleRpcCall().
00329 { 00330 // The key lies between thisNode and its predecessor and 00331 // because routing the message to the predecessor of a key 00332 // is near to impossible we set the deBruijnNodes here 00333 // and the information is as actual as the predecessor pointer. 00334 // 00335 // If this is the only node in the ring, it is the temporary de bruijn 00336 // node for the joining node. 00337 if ((predecessorNode.isUnspecified() && successorList->isEmpty()) 00338 || deBruijnCall->getDestKey().isBetweenR(predecessorNode.getKey(), 00339 thisNode.getKey())) { 00340 DeBruijnResponse* deBruijnResponse = 00341 new DeBruijnResponse("DeBruijnResponse"); 00342 00343 if (predecessorNode.isUnspecified()) { 00344 deBruijnResponse->setDBNode(thisNode); 00345 } else { 00346 deBruijnResponse->setDBNode(predecessorNode); 00347 } 00348 00349 int sucNum = successorList->getSize() + 1; 00350 deBruijnResponse->setSucNum(sucNum); 00351 deBruijnResponse->setSucNodeArraySize(sucNum); 00352 00353 deBruijnResponse->setSucNode(0, thisNode); 00354 for (int k = 1; k < sucNum; k++) { 00355 deBruijnResponse->setSucNode(k, successorList->getSuccessor(k-1)); 00356 } 00357 deBruijnResponse->setBitLength(DEBRUIJNRESPONSE_L(deBruijnResponse)); 00358 00359 sendRpcResponse(deBruijnCall, deBruijnResponse); 00360 } else if (deBruijnCall->getDestKey().isBetweenR(thisNode.getKey(), 00361 successorList->getSuccessor().getKey())) { 00362 error("Koorde::handleRpcDeBruijnRequest() - unknown error."); 00363 } else { 00364 error("Koorde::handleRpcDeBruijnRequest() - " 00365 "Request couldn't be delivered!"); 00366 } 00367 }
void oversim::Koorde::handleRpcDeBruijnResponse | ( | DeBruijnResponse * | deBruijnResponse | ) | [protected, virtual] |
handle a received DEBRUIJN response
deBruijnResponse | the message to process |
Definition at line 369 of file Koorde.cc.
Referenced by handleRpcResponse().
00370 { 00371 int sucNum = deBruijnResponse->getSucNum(); 00372 if (sucNum > deBruijnListSize) 00373 sucNum = deBruijnListSize; 00374 00375 for (int i = 0; i < sucNum; i++) { 00376 deBruijnNodes[i] = deBruijnResponse->getSucNode(i); 00377 deBruijnNumber = i+1; 00378 } 00379 00380 deBruijnNode = deBruijnResponse->getDBNode(); 00381 00382 updateTooltip(); 00383 00384 if (setupDeBruijnBeforeJoin && (state == BOOTSTRAP)) { 00385 // now that we have a valid de bruijn node it's time to join the ring 00386 if (!join_timer->isScheduled()) { 00387 scheduleAt(simTime(), join_timer); 00388 } 00389 } 00390 }
void oversim::Koorde::handleRpcJoinResponse | ( | JoinResponse * | joinResponse | ) | [protected, virtual] |
handle a received JOIN response
joinResponse | the message to process |
Reimplemented from oversim::Chord.
Definition at line 304 of file Koorde.cc.
00305 { 00306 Chord::handleRpcJoinResponse(joinResponse); 00307 00308 // has to be canceled in Koorde 00309 cancelEvent(fixfingers_timer); 00310 00311 // immediate deBruijn protocol 00312 cancelEvent(deBruijn_timer); 00313 scheduleAt(simTime(), deBruijn_timer); 00314 }
void oversim::Koorde::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
cPolymorphic * | context, | |||
int | rpcId, | |||
simtime_t | rtt | |||
) | [protected, virtual] |
This method is called if an RPC response has been received.
msg | The response message. | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
rtt | The Round-Trip-Time of this RPC |
Reimplemented from oversim::Chord.
Definition at line 264 of file Koorde.cc.
00267 { 00268 Chord::handleRpcResponse(msg, context, rpcId, rtt); 00269 00270 RPC_SWITCH_START( msg ) 00271 RPC_ON_RESPONSE( DeBruijn ) { 00272 handleRpcDeBruijnResponse(_DeBruijnResponse); 00273 EV << "[Koorde::handleRpcResponse() @ " << thisNode.getAddress() 00274 << " (" << thisNode.getKey().toString(16) << ")]\n" 00275 << " DeBruijn RPC Response received: id=" << rpcId 00276 << "\n msg=" << *_DeBruijnResponse << " rtt=" << rtt 00277 << endl; 00278 break; 00279 } 00280 RPC_SWITCH_END( ) 00281 }
void oversim::Koorde::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
cPolymorphic * | context, | |||
int | rpcId, | |||
const OverlayKey & | destKey | |||
) | [protected, virtual] |
This method is called if an RPC timeout has been reached.
msg | The original RPC message. | |
dest | The destination node | |
context | Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code | |
rpcId | The RPC id. | |
destKey | the destination OverlayKey |
Reimplemented from oversim::Chord.
Definition at line 283 of file Koorde.cc.
00287 { 00288 Chord::handleRpcTimeout(msg, dest, context, rpcId, destKey); 00289 00290 RPC_SWITCH_START( msg ) 00291 RPC_ON_CALL( DeBruijn ) { 00292 handleDeBruijnTimeout(_DeBruijnCall); 00293 EV << "[Koorde::handleRpcTimeout() @ " << thisNode.getAddress() 00294 << " (" << thisNode.getKey().toString(16) << ")]\n" 00295 << " DeBruijn RPC Call timed out: id=" << rpcId 00296 << "\n msg=" << *_DeBruijnCall 00297 << endl; 00298 break; 00299 } 00300 RPC_SWITCH_END( ) 00301 }
void oversim::Koorde::handleTimerEvent | ( | cMessage * | msg | ) | [virtual] |
Reimplemented from oversim::Chord.
Definition at line 119 of file Koorde.cc.
00120 { 00121 if (msg->isName("deBruijn_timer")) { 00122 handleDeBruijnTimerExpired(); 00123 } else if (msg->isName("fixfingers_timer")) { 00124 handleFixFingersTimerExpired(msg); 00125 } else { 00126 Chord::handleTimerEvent(msg); 00127 } 00128 }
void oversim::Koorde::handleUDPMessage | ( | BaseOverlayMessage * | msg | ) | [virtual] |
Processes messages from underlay.
msg | Message from UDP |
Reimplemented from oversim::Chord.
Definition at line 239 of file Koorde.cc.
00240 { 00241 Chord::handleUDPMessage(msg); 00242 }
void oversim::Koorde::initializeFriendModules | ( | ) | [protected, virtual] |
initializes finger table and successor list
Reimplemented from oversim::Chord.
Definition at line 770 of file Koorde.cc.
00771 { 00772 // initialize successor list 00773 successorList->initializeList(par("successorListSize"), thisNode, this); 00774 }
void oversim::Koorde::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.
stage | the init stage |
Reimplemented from oversim::Chord.
Definition at line 37 of file Koorde.cc.
00038 { 00039 // because of IPAddressResolver, we need to wait until interfaces 00040 // are registered, address auto-assignment takes place etc. 00041 if (stage != MIN_STAGE_OVERLAY) 00042 return; 00043 00044 // fetch some parameters 00045 deBruijnDelay = par("deBruijnDelay"); 00046 deBruijnListSize = par("deBruijnListSize"); 00047 shiftingBits = par("shiftingBits"); 00048 useOtherLookup = par("useOtherLookup"); 00049 useSucList = par("useSucList"); 00050 setupDeBruijnBeforeJoin = par("setupDeBruijnBeforeJoin"); 00051 setupDeBruijnAtJoin = par("setupDeBruijnAtJoin"); 00052 00053 // init flags 00054 breakLookup = false; 00055 00056 // some local variables 00057 deBruijnNumber = 0; 00058 deBruijnNodes = new NodeHandle[deBruijnListSize]; 00059 00060 // statistics 00061 deBruijnCount = 0; 00062 deBruijnBytesSent = 0; 00063 00064 // add some watches 00065 WATCH(deBruijnNumber); 00066 WATCH(deBruijnNode); 00067 00068 // timer messages 00069 deBruijn_timer = new cMessage("deBruijn_timer"); 00070 00071 Chord::initializeOverlay(stage); 00072 }
void oversim::Koorde::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.
msg | The overlay message to be sent to the UDP layer |
Reimplemented from oversim::Chord.
Definition at line 641 of file Koorde.cc.
00642 { 00643 Chord::recordOverlaySentStats(msg); 00644 00645 BaseOverlayMessage* innerMsg = msg; 00646 while (innerMsg->getType() != APPDATA && 00647 innerMsg->getEncapsulatedPacket() != NULL) { 00648 innerMsg = 00649 static_cast<BaseOverlayMessage*>(innerMsg->getEncapsulatedPacket()); 00650 } 00651 00652 switch (innerMsg->getType()) { 00653 case RPC: { 00654 if ((dynamic_cast<DeBruijnCall*>(innerMsg) != NULL) || 00655 (dynamic_cast<DeBruijnResponse*>(innerMsg) != NULL)) { 00656 RECORD_STATS(deBruijnCount++; deBruijnBytesSent += 00657 msg->getByteLength()); 00658 } 00659 break; 00660 } 00661 } 00662 }
void oversim::Koorde::rpcJoin | ( | JoinCall * | call | ) | [protected, virtual] |
Join Remote-Procedure-Call.
call | RPC Parameter Message |
Reimplemented from oversim::Chord.
Definition at line 317 of file Koorde.cc.
00318 { 00319 Chord::rpcJoin(joinCall); 00320 00321 if (predecessorNode == successorList->getSuccessor()) { 00322 // second node join -> need to setup our de bruijn node 00323 handleDeBruijnTimerExpired(); 00324 } 00325 }
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().
00585 { 00586 // 00587 // Updates the tooltip display strings. 00588 // 00589 00590 if (ev.isGUI()) { 00591 std::stringstream ttString; 00592 00593 // show our predecessor, successor and de Bruijn node in tooltip 00594 ttString << "Pred "<< predecessorNode << endl << "This " 00595 << thisNode << endl 00596 << "Suc " << successorList->getSuccessor() << endl 00597 << "DeBr " << deBruijnNode << endl; 00598 ttString << "List "; 00599 00600 for (unsigned int i = 0; i < successorList->getSize(); i++) { 00601 ttString << successorList->getSuccessor(i).getAddress() << " "; 00602 } 00603 00604 ttString << endl; 00605 ttString << "DList "; 00606 00607 for (int i = 0; i < deBruijnNumber; i++) { 00608 ttString << deBruijnNodes[i].getAddress() << " "; 00609 } 00610 00611 ttString << endl; 00612 00613 getParentModule()->getParentModule()-> 00614 getDisplayString().setTagArg("tt", 0, ttString.str().c_str()); 00615 getParentModule()->getDisplayString().setTagArg("tt", 0, 00616 ttString.str().c_str()); 00617 getDisplayString().setTagArg("tt", 0, ttString.str().c_str()); 00618 00619 // draw an arrow to our current successor 00620 showOverlayNeighborArrow(successorList->getSuccessor(), true, 00621 "m=m,50,0,50,0;ls=red,1"); 00622 } 00623 }
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.
key | the key to check |
Definition at line 558 of file Koorde.cc.
Referenced by findDeBruijnHop().
00559 { 00560 if (deBruijnNumber == 0) 00561 return NodeHandle::UNSPECIFIED_NODE; 00562 00563 for (int i = 0; i < deBruijnNumber-1; i++) { 00564 if (key.isBetweenR(deBruijnNodes[i].getKey(),deBruijnNodes[i+1].getKey())) { 00565 return deBruijnNodes[i]; 00566 } 00567 } 00568 00569 return deBruijnNodes[deBruijnNumber-1]; 00570 }
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.
key | the key to check |
Definition at line 572 of file Koorde.cc.
Referenced by findDeBruijnHop(), and findNode().
00573 { 00574 for (unsigned int i = 0; i < successorList->getSize()-1; i++) { 00575 if (key.isBetweenR(successorList->getSuccessor(i).getKey(), 00576 successorList->getSuccessor(i+1).getKey())) { 00577 return successorList->getSuccessor(i); 00578 } 00579 } 00580 00581 return successorList->getSuccessor(successorList->getSize()-1); 00582 }
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().
int oversim::Koorde::deBruijnBytesSent [protected] |
number of bytes sent during de bruijn calls
Definition at line 89 of file Koorde.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Koorde::deBruijnCount [protected] |
number of de bruijn calls
Definition at line 88 of file Koorde.h.
Referenced by finishOverlay(), initializeOverlay(), and recordOverlaySentStats().
int oversim::Koorde::deBruijnDelay [protected] |
number of seconds between two de bruijn calls
Definition at line 77 of file Koorde.h.
Referenced by handleDeBruijnTimerExpired(), and initializeOverlay().
int oversim::Koorde::deBruijnListSize [protected] |
maximal number of nodes in de bruijn list
Definition at line 79 of file Koorde.h.
Referenced by changeState(), handleDeBruijnTimerExpired(), handleRpcDeBruijnResponse(), and initializeOverlay().
NodeHandle oversim::Koorde::deBruijnNode [protected] |
Handle to our de Bruijn node.
Definition at line 93 of file Koorde.h.
Referenced by changeState(), findDeBruijnHop(), handleDeBruijnTimerExpired(), handleFailedNode(), handleRpcDeBruijnResponse(), initializeOverlay(), and updateTooltip().
NodeHandle* oversim::Koorde::deBruijnNodes [protected] |
List of de Bruijn nodes.
Definition at line 92 of file Koorde.h.
Referenced by changeState(), findDeBruijnHop(), handleDeBruijnTimerExpired(), handleFailedNode(), handleRpcDeBruijnResponse(), initializeOverlay(), updateTooltip(), and walkDeBruijnList().
int oversim::Koorde::deBruijnNumber [protected] |
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().
bool oversim::Koorde::setupDeBruijnAtJoin [protected] |
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().
bool oversim::Koorde::setupDeBruijnBeforeJoin [protected] |
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().
int oversim::Koorde::shiftingBits [protected] |
number of bits concurrently shifted in one routing step
Definition at line 80 of file Koorde.h.
Referenced by findDeBruijnHop(), findStartKey(), handleDeBruijnTimerExpired(), and initializeOverlay().
bool oversim::Koorde::useOtherLookup [protected] |
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().