00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #include <IPAddressResolver.h>
00024 #include <IPvXAddress.h>
00025 #include <IInterfaceTable.h>
00026 #include <IPv4InterfaceData.h>
00027 #include <GlobalStatistics.h>
00028
00029 #include "Koorde.h"
00030
00031 using namespace std;
00032
00033 namespace oversim {
00034
00035 Define_Module(Koorde);
00036
00037 void Koorde::initializeOverlay(int stage)
00038 {
00039
00040
00041 if (stage != MIN_STAGE_OVERLAY)
00042 return;
00043
00044
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
00054 breakLookup = false;
00055
00056
00057 deBruijnNumber = 0;
00058 deBruijnNodes = new NodeHandle[deBruijnListSize];
00059
00060
00061 deBruijnCount = 0;
00062 deBruijnBytesSent = 0;
00063
00064
00065 WATCH(deBruijnNumber);
00066 WATCH(deBruijnNode);
00067
00068
00069 deBruijn_timer = new cMessage("deBruijn_timer");
00070
00071 Chord::initializeOverlay(stage);
00072 }
00073
00074 Koorde::~Koorde()
00075 {
00076 cancelAndDelete(deBruijn_timer);
00077 }
00078
00079 void Koorde::changeState(int toState)
00080 {
00081 Chord::changeState(toState);
00082
00083 switch(state) {
00084 case INIT:
00085
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
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
00107 cancelEvent(deBruijn_timer);
00108 scheduleAt(simTime(), deBruijn_timer);
00109
00110
00111 cancelEvent(fixfingers_timer);
00112 break;
00113 default:
00114 break;
00115 }
00116
00117 }
00118
00119 void Koorde::handleTimerEvent(cMessage* msg)
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 }
00129
00130 bool Koorde::handleFailedNode(const TransportAddress& failed)
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 }
00163
00164 void Koorde::handleDeBruijnTimerExpired()
00165 {
00166 OverlayKey lookup = thisNode.getKey() << shiftingBits;
00167
00168 if (state == READY) {
00169 if (successorList->getSize() > 0) {
00170
00171
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 }
00230
00231 #if 0
00232 void Koorde::handleFixFingersTimerExpired(cMessage* msg)
00233 {
00234
00235 }
00236 #endif
00237
00238
00239 void Koorde::handleUDPMessage(BaseOverlayMessage* msg)
00240 {
00241 Chord::handleUDPMessage(msg);
00242 }
00243
00244
00245 bool Koorde::handleRpcCall(BaseCallMessage* msg)
00246 {
00247 if (state == READY) {
00248
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 }
00263
00264 void Koorde::handleRpcResponse(BaseResponseMessage* msg,
00265 cPolymorphic* context,
00266 int rpcId, simtime_t rtt)
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 }
00282
00283 void Koorde::handleRpcTimeout(BaseCallMessage* msg,
00284 const TransportAddress& dest,
00285 cPolymorphic* context, int rpcId,
00286 const OverlayKey& destKey)
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 }
00302
00303
00304 void Koorde::handleRpcJoinResponse(JoinResponse* joinResponse)
00305 {
00306 Chord::handleRpcJoinResponse(joinResponse);
00307
00308
00309 cancelEvent(fixfingers_timer);
00310
00311
00312 cancelEvent(deBruijn_timer);
00313 scheduleAt(simTime(), deBruijn_timer);
00314 }
00315
00316
00317 void Koorde::rpcJoin(JoinCall* joinCall)
00318 {
00319 Chord::rpcJoin(joinCall);
00320
00321 if (predecessorNode == successorList->getSuccessor()) {
00322
00323 handleDeBruijnTimerExpired();
00324 }
00325 }
00326
00327
00328 void Koorde::handleRpcDeBruijnRequest(DeBruijnCall* deBruijnCall)
00329 {
00330
00331
00332
00333
00334
00335
00336
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 }
00368
00369 void Koorde::handleRpcDeBruijnResponse(DeBruijnResponse* deBruijnResponse)
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
00386 if (!join_timer->isScheduled()) {
00387 scheduleAt(simTime(), join_timer);
00388 }
00389 }
00390 }
00391
00392 void Koorde::handleDeBruijnTimeout(DeBruijnCall* deBruijnCall)
00393 {
00394 if (setupDeBruijnBeforeJoin && (state == BOOTSTRAP)) {
00395
00396
00397 changeState(BOOTSTRAP);
00398 return;
00399 }
00400
00401 cancelEvent(deBruijn_timer);
00402 scheduleAt(simTime(), deBruijn_timer);
00403 }
00404
00405 NodeVector* Koorde::findNode(const OverlayKey& key,
00406 int numRedundantNodes,
00407 int numSiblings,
00408 BaseOverlayMessage* msg)
00409 {
00410
00411
00412
00413
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
00436 nextHop->push_back(thisNode);
00437 } else if (key.isBetweenR(thisNode.getKey(),
00438 successorList->getSuccessor().getKey())){
00439
00440 nextHop->push_back(successorList->getSuccessor());
00441 } else {
00442
00443
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
00460
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 }
00472
00473 NodeHandle Koorde::findDeBruijnHop(const OverlayKey& destKey,
00474 KoordeFindNodeExtMessage* findNodeExt)
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
00490
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
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
00518
00519 if (deBruijnNumber > 0) {
00520 if (findNodeExt->getRouteKey().isBetweenR(deBruijnNode.getKey(),
00521 deBruijnNodes[0].getKey())) {
00522 return deBruijnNode;
00523 } else {
00524
00525
00526 NodeHandle nextHop = walkDeBruijnList(findNodeExt->
00527 getRouteKey());
00528 return nextHop;
00529 }
00530 } else {
00531 return deBruijnNode;
00532 }
00533 } else {
00534 breakLookup = true;
00535
00536
00537 if (useSucList) {
00538 if (deBruijnNode.isUnspecified()) {
00539 return walkSuccessorList(findNodeExt->getRouteKey());
00540 } else {
00541 NodeHandle tmpHandle =
00542 walkSuccessorList(findNodeExt->getRouteKey());
00543
00544
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 }
00556
00557
00558 const NodeHandle& Koorde::walkDeBruijnList(const OverlayKey& key)
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 }
00571
00572 const NodeHandle& Koorde::walkSuccessorList(const OverlayKey& key)
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 }
00583
00584 void Koorde::updateTooltip()
00585 {
00586
00587
00588
00589
00590 if (ev.isGUI()) {
00591 std::stringstream ttString;
00592
00593
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
00620 showOverlayNeighborArrow(successorList->getSuccessor(), true,
00621 "m=m,50,0,50,0;ls=red,1");
00622 }
00623 }
00624
00625
00626 void Koorde::finishOverlay()
00627 {
00628
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 }
00640
00641 void Koorde::recordOverlaySentStats(BaseOverlayMessage* msg)
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 }
00663
00664 OverlayKey Koorde::findStartKey(const OverlayKey& startKey,
00665 const OverlayKey& endKey,
00666 const OverlayKey& destKey,
00667 int& step)
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
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
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
00745 if (newKey.isBetweenR(startKey, endKey)) {
00746 return newKey;
00747 }
00748
00749
00750
00751
00752
00753 newKey += powKey.pow2(nBits);
00754
00755 if (newKey.isBetweenR(startKey, endKey)) {
00756 return newKey;
00757 } else {
00758
00759 throw cRuntimeError("Koorde::findStartKey(): Invalid start key");
00760 return OverlayKey::UNSPECIFIED_KEY;
00761 }
00762 }
00763
00764 void Koorde::findFriendModules()
00765 {
00766 successorList = check_and_cast<ChordSuccessorList*>
00767 (getParentModule()->getSubmodule("successorList"));
00768 }
00769
00770 void Koorde::initializeFriendModules()
00771 {
00772
00773 successorList->initializeList(par("successorListSize"), thisNode, this);
00774 }
00775
00776 };
00777