00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include "PastryLeafSet.h"
00025 #include "PastryTypes.h"
00026 #include "NodeVector.h"
00027
00028 #if 0
00029 #define LEAF_TEST() \
00030 do {\
00031 uint32_t count = 0;\
00032 uint32_t i = 0, j = leaves.size() - 1;\
00033 while (leaves[i].isUnspecified() && i < j) ++i;\
00034 while (leaves[j].isUnspecified() && i < j) --j;\
00035 if (i == j) break;\
00036 if (!owner.getKey().isBetween(leaves[(leaves.size() / 2) - 1].getKey(),\
00037 leaves[leaves.size() / 2].getKey()))\
00038 ASSERT2(false, "leafset broken!");\
00039 for (uint32_t ci = i + 1; ci < j; ++ci) {\
00040 if (leaves[ci - 1].getKey() >= leaves[ci].getKey()) {\
00041 count++;\
00042 }\
00043 }\
00044 if (leaves[j].getKey() >= leaves[i].getKey()) count++;\
00045 ASSERT2(count <= 1, "leafset broken!");\
00046 } while (false);
00047 #else
00048 #define LEAF_TEST() {}
00049 #endif
00050
00051 Define_Module(PastryLeafSet);
00052
00053 void PastryLeafSet::earlyInit(void)
00054 {
00055 WATCH_VECTOR(leaves);
00056 }
00057
00058 void PastryLeafSet::initializeSet(uint32_t numberOfLeaves,
00059 uint32_t bitsPerDigit,
00060 simtime_t repairTimeout,
00061 const NodeHandle& owner,
00062 BasePastry *overlay)
00063 {
00064 if (numberOfLeaves % 2) throw "numberOfLeaves must be even.";
00065
00066 this->owner = owner;
00067 this->numberOfLeaves = numberOfLeaves;
00068 this->repairTimeout = repairTimeout;
00069 this->bitsPerDigit = bitsPerDigit;
00070 this->overlay = overlay;
00071
00072 if (!leaves.empty()) leaves.clear();
00073
00074
00075 for (uint32_t i = numberOfLeaves; i>0; i--)
00076 leaves.push_back(NodeHandle::UNSPECIFIED_NODE);
00077
00078
00079
00080 bigger = leaves.begin() + (numberOfLeaves >> 1);
00081 smaller = bigger - 1;
00082
00083
00084 if (!awaitingRepair.empty()) awaitingRepair.clear();
00085
00086 newLeafs = false;
00087 isFull = false;
00088 wasFull = false;
00089 }
00090
00091 const NodeHandle& PastryLeafSet::getSuccessor(void) const
00092 {
00093 return *bigger;
00094 }
00095
00096 const NodeHandle& PastryLeafSet::getPredecessor(void) const
00097 {
00098 return *smaller;
00099 }
00100
00101 bool PastryLeafSet::isValid(void) const
00102 {
00103 return (!(smaller->isUnspecified() || bigger->isUnspecified()));
00104 }
00105
00106 const NodeHandle& PastryLeafSet::getDestinationNode(
00107 const OverlayKey& destination)
00108 {
00109 std::vector<NodeHandle>::const_iterator i;
00110 const OverlayKey* smallest;
00111 const OverlayKey* biggest;
00112 const NodeHandle* ret = &NodeHandle::UNSPECIFIED_NODE;
00113
00114
00115
00116 smallest = &(getSmallestKey());
00117 biggest = &(getBiggestKey());
00118 if (smallest->isUnspecified()) smallest = &(owner.getKey());
00119 if (biggest->isUnspecified()) biggest = &(owner.getKey());
00120
00121 if (!destination.isBetweenLR(*smallest, *biggest)) return *ret;
00122
00123
00124
00125 for (i = leaves.begin(); i != leaves.end(); i++) {
00126 if (i->isUnspecified()) continue;
00127
00128
00129
00130 if (isCloser(*i, destination, *ret)) ret = &(*i);
00131 }
00132
00133 return *ret;
00134 }
00135
00136 bool PastryLeafSet::isClosestNode(const OverlayKey& destination) const
00137 {
00138
00139 if (owner.getKey() == destination) {
00140 return true;
00141 }
00142
00143 if (bigger->isUnspecified() && smaller->isUnspecified()) {
00144 return true;
00145 }
00146
00147
00148
00149 bool biggerIsCloser = false;
00150 bool smallerIsCloser = false;
00151
00152 if (! bigger->isUnspecified()) {
00153 biggerIsCloser = isCloser(*bigger, destination);
00154 }
00155 if (! smaller->isUnspecified()) {
00156 smallerIsCloser = isCloser(*smaller, destination);
00157 }
00158
00159
00160 return ((!biggerIsCloser) && (!smallerIsCloser));
00161 }
00162
00163 void PastryLeafSet::dumpToStateMessage(PastryStateMessage* msg) const
00164 {
00165 uint32_t i = 0;
00166 uint32_t size = 0;
00167 std::vector<NodeHandle>::const_iterator it;
00168
00169 msg->setLeafSetArraySize(numberOfLeaves);
00170 for (it = leaves.begin(); it != leaves.end(); it++) {
00171 if (!it->isUnspecified()) {
00172 ++size;
00173 msg->setLeafSet(i++, *it);
00174 }
00175 }
00176 msg->setLeafSetArraySize(size);
00177 }
00178
00179
00180 void PastryLeafSet::dumpToStateMessage(PastryLeafsetMessage* msg) const
00181 {
00182 uint32_t i = 0;
00183 uint32_t size = 0;
00184 std::vector<NodeHandle>::const_iterator it;
00185
00186 msg->setLeafSetArraySize(numberOfLeaves);
00187 for (it = leaves.begin(); it != leaves.end(); it++) {
00188 if (!it->isUnspecified()) {
00189 ++size;
00190 msg->setLeafSet(i++, *it);
00191 }
00192 }
00193 msg->setLeafSetArraySize(size);
00194 }
00195
00196 const TransportAddress& PastryLeafSet::getRandomNode()
00197 {
00198
00199 uint32_t rnd;
00200 int i;
00201
00202 rnd = intuniform(0, numberOfLeaves - 1, 0);
00203 i = rnd;
00204
00205 while (i < (int)leaves.size()) {
00206 if (!leaves[i].isUnspecified()) return leaves[i];
00207 else i++;
00208 }
00209 i = rnd;
00210 while (i >= 0) {
00211 if (!leaves[i].isUnspecified()) return leaves[i];
00212 else i--;
00213 }
00214 EV << "Leafset::getRandomNode() returns UNSPECIFIED_NODE"
00215 "Leafset empty??" << endl;
00216 return TransportAddress::UNSPECIFIED_NODE;
00217
00218 }
00219
00220 NodeVector* PastryLeafSet::createSiblingVector(const OverlayKey& key,
00221 int numSiblings) const
00222 {
00223 std::vector<NodeHandle>::const_iterator it;
00224
00225
00226 KeyDistanceComparator<KeyRingMetric>* comp =
00227 new KeyDistanceComparator<KeyRingMetric>( key );
00228
00229
00230 NodeVector* result = new NodeVector( numSiblings, comp );
00231
00232 result->add(owner);
00233
00234 for (it = leaves.begin(); it != leaves.end(); it++) {
00235 if (!it->isUnspecified()) {
00236 result->add(*it);
00237 }
00238 }
00239
00240 delete comp;
00241
00242 if (!isValid()) {
00243 return result;
00244 }
00245
00246
00247
00248 if (leaves.front().isUnspecified() || leaves.back().isUnspecified()) {
00249 return result;
00250 }
00251
00252 if ((result->contains(getBiggestKey())) ||
00253 (result->contains(getSmallestKey()))) {
00254 delete result;
00255 return NULL;
00256 }
00257
00258 return result;
00259 }
00260
00261 bool PastryLeafSet::mergeNode(const NodeHandle& node, simtime_t prox)
00262 {
00263 assert(node != overlay->getThisNode());
00264
00265 std::vector<NodeHandle>::iterator it, it_left, it_right;
00266 const OverlayKey* last_left = &(owner.getKey());
00267 const OverlayKey* last_right = &(owner.getKey());
00268
00269 it_left = smaller;
00270 it_right = bigger;
00271
00272
00273 for (it = leaves.begin(); it != leaves.end(); ++it) {
00274 if (it->isUnspecified()) {
00275 isFull = false;
00276 continue;
00277 }
00278 if (it->getKey() == node.getKey()) return false;
00279 }
00280
00281
00282 while (true) {
00283 if(!isFull) {
00284
00285 if(it_left->getKey().isUnspecified() &&
00286 it_right->getKey().isUnspecified()) {
00287 insertLeaf(it_left, node);
00288 return true;
00289 }
00290 if (it_left->getKey().isUnspecified() &&
00291 !node.getKey().isBetween(*last_right, it_right->getKey())) {
00292
00293 insertLeaf(it_left, node);
00294 return true;
00295 }
00296 if (it_right->getKey().isUnspecified() &&
00297 !node.getKey().isBetween(it_left->getKey(), *last_left)) {
00298
00299 insertLeaf(it_right, node);
00300 return true;
00301 }
00302 }
00303
00304 if (node.getKey().isBetween(it_left->getKey(), *last_left)) {
00305
00306
00307 insertLeaf(it_left, node);
00308 return true;
00309 }
00310
00311 if (node.getKey().isBetween(*last_right, it_right->getKey())) {
00312
00313
00314 insertLeaf(it_right, node);
00315 return true;
00316 }
00317
00318 last_right = &(it_right->getKey());
00319 ++it_right;
00320
00321 if (it_right == leaves.end()) break;
00322
00323 last_left = &(it_left->getKey());
00324 --it_left;
00325 }
00326 return false;
00327 }
00328
00329 void PastryLeafSet::insertLeaf(std::vector<NodeHandle>::iterator& it,
00330 const NodeHandle& node)
00331 {
00332 assert(node != overlay->getThisNode());
00333
00334 LEAF_TEST();
00335 bool issmaller = (it <= smaller);
00336 if (issmaller) {
00337 if (!leaves.front().isUnspecified()) {
00338 overlay->callUpdate(leaves.front(), false);
00339 }
00340 overlay->callUpdate(node, true);
00341
00342 leaves.insert(++it, node);
00343 NodeHandle& temp = leaves.front();
00344 if (!temp.isUnspecified() && leaves.back().isUnspecified()) {
00345 leaves.back() = temp;
00346 }
00347 leaves.erase(leaves.begin());
00348
00349
00350 } else {
00351 if (!leaves.back().isUnspecified()) {
00352 overlay->callUpdate(leaves.back(), false);
00353 }
00354 overlay->callUpdate(node, true);
00355
00356 leaves.insert(it, node);
00357 NodeHandle& temp = leaves.back();
00358 if (!temp.isUnspecified() && leaves.front().isUnspecified()) {
00359 leaves.front() = temp;
00360 }
00361 leaves.pop_back();
00362 }
00363
00364 if (!leaves.front().isUnspecified() &&
00365 !leaves.back().isUnspecified()) {
00366 isFull = true;
00367 } else isFull = false;
00368
00369 newLeafs = true;
00370 bigger = leaves.begin() + (numberOfLeaves >> 1);
00371 smaller = bigger - 1;
00372
00373
00374 if (!isFull) {
00375 balanceLeafSet();
00376 }
00377 LEAF_TEST();
00378 }
00379
00380 bool PastryLeafSet::balanceLeafSet()
00381 {
00382 if (isFull ||
00383 (!leaves.front().isUnspecified() &&
00384 !(leaves.end() - 2)->isUnspecified()) ||
00385 (!leaves.back().isUnspecified() &&
00386 !(leaves.begin() + 1)->isUnspecified()))
00387 return false;
00388
00389 std::vector<NodeHandle>::iterator it_left, it_right;
00390
00391 for (it_left = smaller, it_right = bigger;
00392 it_right != leaves.end(); --it_left, ++it_right) {
00393 if (it_left->isUnspecified()) {
00394 if (it_right->isUnspecified() ||
00395 (it_right + 1) == leaves.end() ||
00396 (it_right + 1)->isUnspecified()) return false;
00397 *it_left = *(it_right + 1);
00398 *(it_right + 1) = NodeHandle::UNSPECIFIED_NODE;
00399 return true;
00400 } else if (it_right->isUnspecified()) {
00401
00402 if (it_left == leaves.begin() ||
00403 (it_left - 1)->isUnspecified()) return false;
00404 *it_right = *(it_left - 1);
00405 *(it_left - 1) = NodeHandle::UNSPECIFIED_NODE;
00406 return true;
00407 }
00408 }
00409 return false;
00410 }
00411
00412 void PastryLeafSet::dumpToVector(std::vector<TransportAddress>& affected) const
00413 {
00414 std::vector<NodeHandle>::const_iterator it;
00415
00416 for (it = leaves.begin(); it != leaves.end(); it++)
00417 if (!it->isUnspecified())
00418 affected.push_back(*it);
00419 }
00420
00421 const NodeHandle& PastryLeafSet::getSmallestNode(void) const
00422 {
00423 std::vector<NodeHandle>::const_iterator i = leaves.begin();
00424 while ((i->isUnspecified()) && (i != smaller)) i++;
00425 assert(i->isUnspecified() || *i != overlay->getThisNode());
00426 return *i;
00427 }
00428
00429 const OverlayKey& PastryLeafSet::getSmallestKey(void) const
00430 {
00431 return getSmallestNode().getKey();
00432 }
00433
00434 const NodeHandle& PastryLeafSet::getBiggestNode(void) const
00435 {
00436 std::vector<NodeHandle>::const_iterator i = leaves.end()-1;
00437 while ((i->isUnspecified()) && (i != bigger)) i--;
00438 assert(i->isUnspecified() || *i != overlay->getThisNode());
00439 return *i;
00440 }
00441
00442 const OverlayKey& PastryLeafSet::getBiggestKey(void) const
00443 {
00444 return getBiggestNode().getKey();
00445 }
00446
00447 void PastryLeafSet::findCloserNodes(const OverlayKey& destination,
00448 NodeVector* nodes)
00449 {
00450 std::vector<NodeHandle>::const_iterator it;
00451
00452 for (it = leaves.begin(); it != leaves.end(); it++)
00453 if (!it->isUnspecified())
00454 nodes->add(*it);
00455
00456 }
00457
00458 const NodeHandle& PastryLeafSet::findCloserNode(const OverlayKey& destination,
00459 bool optimize)
00460 {
00461 std::vector<NodeHandle>::const_iterator i;
00462 const NodeHandle* ret = &NodeHandle::UNSPECIFIED_NODE;
00463
00464
00465
00466
00467
00468 const NodeHandle& smallest = getSmallestNode();
00469 const NodeHandle& biggest = getBiggestNode();
00470
00471 if ((!smallest.isUnspecified()) &&
00472 (specialCloserCondition(smallest, destination, *ret))) {
00473 if (optimize) ret = &smallest;
00474 else return smallest;
00475 }
00476
00477 if ((!biggest.isUnspecified()) &&
00478 (specialCloserCondition(biggest, destination, *ret))) {
00479 if (optimize) ret = &biggest;
00480 else return biggest;
00481 }
00482
00483 return *ret;
00484 }
00485
00486 const TransportAddress& PastryLeafSet::failedNode(const TransportAddress& failed)
00487 {
00488 std::vector<NodeHandle>::iterator i;
00489 const TransportAddress* ask;
00490 bool left = true;
00491
00492
00493 for (i = leaves.begin(); i != leaves.end(); i++) {
00494 if (i == bigger) left = false;
00495 if ((! i->isUnspecified()) && (i->getAddress() == failed.getAddress())) break;
00496 }
00497
00498
00499 if (i == leaves.end()) return TransportAddress::UNSPECIFIED_NODE;
00500
00501 overlay->callUpdate(*i, false);
00502
00503
00504 leaves.erase(i);
00505 newLeafs = true;
00506
00507 wasFull = isFull;
00508 isFull = false;
00509
00510
00511
00512 if (left) {
00513 leaves.insert(leaves.begin(), NodeHandle::UNSPECIFIED_NODE);
00514 bigger = leaves.begin() + (numberOfLeaves >> 1);
00515 smaller = bigger - 1;
00516 ask = static_cast<const TransportAddress*>(&(getSmallestNode()));
00517 } else {
00518 leaves.push_back(NodeHandle::UNSPECIFIED_NODE);
00519 bigger = leaves.begin() + (numberOfLeaves >> 1);
00520 smaller = bigger - 1;
00521 ask = static_cast<const TransportAddress*>(&(getBiggestNode()));
00522 }
00523
00524 assert(ask->isUnspecified() || *ask != overlay->getThisNode());
00525
00526 balanceLeafSet();
00527 LEAF_TEST();
00528
00529 assert(ask->isUnspecified() || *ask != overlay->getThisNode());
00530
00531 if (! ask->isUnspecified())
00532 awaitingRepair[*ask] = PLSRepairData(simTime(), left);
00533
00534 return *ask;
00535 }
00536
00537 const TransportAddress& PastryLeafSet::repair(const PastryStateMessage* msg,
00538 const PastryStateMsgProximity* prox)
00539 {
00540 std::map<TransportAddress, PLSRepairData>::iterator it;
00541 const TransportAddress* ask;
00542 bool left;
00543
00544 simtime_t now = simTime();
00545
00546
00547 for (it = awaitingRepair.begin(); it != awaitingRepair.end();) {
00548 if (it->second.ts < (now - repairTimeout)) {
00549 awaitingRepair.erase(it++);
00550 }
00551 else it++;
00552 }
00553
00554
00555 if (awaitingRepair.empty()) return TransportAddress::UNSPECIFIED_NODE;
00556
00557
00558 if ( (it = awaitingRepair.find(msg->getSender())) == awaitingRepair.end() )
00559 return TransportAddress::UNSPECIFIED_NODE;
00560
00561
00562 left = it->second.left;
00563
00564
00565 awaitingRepair.erase(it);
00566
00567
00568 if (mergeState(msg, prox) || isFull || !wasFull) {
00569 EV << "[PastryLeafSet::repair()]\n"
00570 << " LeafSet repair was successful."
00571 << endl;
00572 return TransportAddress::UNSPECIFIED_NODE;
00573 } else {
00574
00575 ask = &( left ? getSmallestNode() : getBiggestNode() );
00576 if (ask->isUnspecified() || *ask == msg->getSender()) {
00577 EV << "[PastryLeafSet::repair()]\n"
00578 << " LeafSet giving up repair attempt."
00579 << endl;
00580 return TransportAddress::UNSPECIFIED_NODE;
00581 } else {
00582 awaitingRepair[*ask] = PLSRepairData(simTime(), left);
00583 }
00584 return *ask;
00585 }
00586 }
00587
00588 PastryNewLeafsMessage* PastryLeafSet::getNewLeafsMessage(void)
00589 {
00590 std::vector<NodeHandle>::const_iterator it;
00591 PastryNewLeafsMessage* msg;
00592 uint32_t i = 0;
00593
00594 if (! newLeafs) return NULL;
00595 newLeafs = false;
00596
00597 msg = new PastryNewLeafsMessage("PastryNewLeafs");
00598
00599 msg->setLeafsArraySize(numberOfLeaves);
00600 for (it = leaves.begin(); it != leaves.end(); it++)
00601 msg->setLeafs(i++, *it);
00602
00603 msg->setBitLength(PASTRYNEWLEAFS_L(msg));
00604 return msg;
00605 }