#include <PastryLeafSet.h>
This module contains the LeafSet of the Pastry implementation.
Public Member Functions | |
void | initializeSet (uint numberOfLeaves, uint bitsPerDigit, double repairTimeout, const NodeHandle &owner, BasePastry *overlay) |
Initializes the leaf set. | |
virtual const NodeHandle & | getDestinationNode (const OverlayKey &destination) |
gets the final node according to the Pastry routing scheme. | |
virtual const NodeHandle & | findCloserNode (const OverlayKey &destination, bool optimize=false) |
try to find a node numerically closer to a given key with the same shared prefix as the current node in the leaf set. | |
void | findCloserNodes (const OverlayKey &destination, NodeVector *nodes) |
virtual const TransportAddress & | failedNode (const TransportAddress &failed) |
tells the leafset that a node has failed | |
virtual const TransportAddress & | repair (const PastryStateMessage *msg, const PastryStateMsgProximity &prox) |
attempt to repair the leafset using a received REPAIR message | |
bool | isClosestNode (const OverlayKey &destination) const |
checks if we are the closest node to key destination in the overlay | |
virtual void | dumpToStateMessage (PastryStateMessage *msg) const |
dump content of the set to a PastryStateMessage | |
virtual void | dumpToStateMessage (PastryLeafsetMessage *msg) const |
dump content of the set to a PastryLeafsetMessage | |
virtual const TransportAddress & | getRandomNode () |
returns a random node from the leafset | |
bool | mergeNode (const NodeHandle &node, simtime_t prox) |
merge a node into LeafSet | |
const NodeHandle & | getPredecessor (void) const |
return predecessor node for visualizing | |
const NodeHandle & | getSuccessor (void) const |
return successor node for visualizing | |
bool | isValid (void) const |
check if LeafSet knows at least one node to the left and to the right | |
virtual void | dumpToVector (std::vector< TransportAddress > &affected) const |
appends all leaf set entries to a given vector of TransportAddresses, needed to find all Nodes to be notified after joining. | |
NodeVector * | createSiblingVector (const OverlayKey &key, int numSiblings) const |
PastryNewLeafsMessage * | getNewLeafsMessage (void) |
generates a newLeafs-message if LeafSet changed since last call to this method. | |
Private Member Functions | |
virtual void | earlyInit (void) |
initialize watches etc. | |
const NodeHandle & | getBiggestNode (void) const |
return the node with the biggest key in the LeafSet or NodeHandle::UNSPECIFIED_NODE if LeafSet is empty | |
const OverlayKey & | getBiggestKey (void) const |
return the biggest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty | |
const NodeHandle & | getSmallestNode (void) const |
return the node with the smallest key in the LeafSet or NodeHandle::UNSPECIFIED_NODE if LeafSet is empty | |
const OverlayKey & | getSmallestKey (void) const |
return the smallest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty | |
bool | isLeft (const OverlayKey &key) const |
test if a given key should be placed on the left or on the right side of the leaf set | |
void | insertLeaf (std::vector< NodeHandle >::iterator &it, const NodeHandle &node) |
insert a leaf at a given position | |
bool | balanceLeafSet () |
Private Attributes | |
uint | numberOfLeaves |
double | repairTimeout |
BasePastry * | overlay |
pointer to the main pastry module | |
std::vector< NodeHandle > | leaves |
std::vector< NodeHandle >::iterator | smaller |
std::vector< NodeHandle >::iterator | bigger |
std::map< TransportAddress, PLSRepairData > | awaitingRepair |
bool | newLeafs |
bool | isFull |
bool | wasFull |
void PastryLeafSet::initializeSet | ( | uint | numberOfLeaves, | |
uint | bitsPerDigit, | |||
double | repairTimeout, | |||
const NodeHandle & | owner, | |||
BasePastry * | overlay | |||
) |
Initializes the leaf set.
This should be called on startup
numberOfLeaves | Pastry configuration parameter | |
bitsPerDigit | number of bits per digits | |
repairTimeout | Pastry configuration parameter | |
owner | the node this table belongs to | |
overlay | pointer to the pastry main module |
Referenced by BasePastry::baseChangeState().
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 // fill Set with unspecified node handles 00075 for (uint i = numberOfLeaves; i>0; i--) 00076 leaves.push_back(NodeHandle::UNSPECIFIED_NODE); 00077 00078 // initialize iterators to mark the beginning of bigger/smaller keys 00079 // in the set 00080 bigger = leaves.begin() + (numberOfLeaves >> 1); 00081 smaller = bigger - 1; 00082 00083 // reset repair marker: 00084 if (!awaitingRepair.empty()) awaitingRepair.clear(); 00085 00086 newLeafs = false; 00087 isFull = false; 00088 wasFull = false; 00089 }
const NodeHandle & PastryLeafSet::getDestinationNode | ( | const OverlayKey & | destination | ) | [virtual] |
gets the final node according to the Pastry routing scheme.
destination | the destination key |
Reimplemented from PastryStateObject.
Referenced by BasePastry::findNode().
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 // check whether destination is inside leafSet: 00115 00116 smallest = &(getSmallestKey()); 00117 biggest = &(getBiggestKey()); 00118 if (smallest->isUnspecified()) smallest = &(owner.key); 00119 if (biggest->isUnspecified()) biggest = &(owner.key); 00120 00121 if (!destination.isBetweenLR(*smallest, *biggest)) return *ret; 00122 00123 // find the closest node: 00124 00125 for (i = leaves.begin(); i != leaves.end(); i++) { 00126 if (i->isUnspecified()) continue; 00127 00128 // note for next line: 00129 // * dereferences iterator, & gets address of element. 00130 if (isCloser(*i, destination, *ret)) ret = &(*i); 00131 } 00132 00133 return *ret; 00134 }
const NodeHandle & PastryLeafSet::findCloserNode | ( | const OverlayKey & | destination, | |
bool | optimize = false | |||
) | [virtual] |
try to find a node numerically closer to a given key with the same shared prefix as the current node in the leaf set.
this method is to be called, when a regular next hop couldn't be found or wasn't reachable.
destination | the destination key | |
optimize | if set, check all nodes and return the best/closest one |
Implements PastryStateObject.
Referenced by BasePastry::findNode().
00431 { 00432 std::vector<NodeHandle>::const_iterator i; 00433 const NodeHandle* ret = &NodeHandle::UNSPECIFIED_NODE; 00434 00435 // this will only be called after getDestinationNode() returned 00436 // NodeHandle::UNSPECIFIED_NODE, so a closer Node can only be the biggest 00437 // or the smallest node in the LeafSet. 00438 00439 const NodeHandle& smallest = getSmallestNode(); 00440 const NodeHandle& biggest = getBiggestNode(); 00441 00442 if ((!smallest.isUnspecified()) && 00443 (specialCloserCondition(smallest, destination, *ret))) { 00444 if (optimize) ret = &smallest; 00445 else return smallest; 00446 } 00447 00448 if ((!biggest.isUnspecified()) && 00449 (specialCloserCondition(biggest, destination, *ret))) { 00450 if (optimize) ret = &biggest; 00451 else return biggest; 00452 } 00453 00454 return *ret; 00455 }
void PastryLeafSet::findCloserNodes | ( | const OverlayKey & | destination, | |
NodeVector * | nodes | |||
) | [virtual] |
Implements PastryStateObject.
Referenced by BasePastry::findNode().
00420 { 00421 std::vector<NodeHandle>::const_iterator it; 00422 00423 for (it = leaves.begin(); it != leaves.end(); it++) 00424 if (!it->isUnspecified()) 00425 nodes->add(*it); 00426 00427 }
const TransportAddress & PastryLeafSet::failedNode | ( | const TransportAddress & | failed | ) | [virtual] |
tells the leafset that a node has failed
failed | the failed node |
Implements PastryStateObject.
Referenced by Pastry::handleFailedNode(), and Bamboo::handleFailedNode().
00458 { 00459 std::vector<NodeHandle>::iterator i; 00460 const TransportAddress* ask; 00461 bool left = true; 00462 00463 // search failed node in leafset: 00464 for (i = leaves.begin(); i != leaves.end(); i++) { 00465 if (i == bigger) left = false; 00466 if ((! i->isUnspecified()) && (i->ip == failed.ip)) break; 00467 } 00468 00469 // failed node not in leafset: 00470 if (i == leaves.end()) return TransportAddress::UNSPECIFIED_NODE; 00471 00472 overlay->callUpdate(*i, false); 00473 00474 // remove failed node: 00475 leaves.erase(i); 00476 newLeafs = true; 00477 00478 wasFull = isFull; 00479 isFull = false; 00480 00481 // insert UNSPECIFIED_NODE at front or back and return correct node 00482 // to ask for repair: 00483 if (left) { 00484 leaves.insert(leaves.begin(), NodeHandle::UNSPECIFIED_NODE); 00485 bigger = leaves.begin() + (numberOfLeaves >> 1); 00486 smaller = bigger - 1; 00487 ask = static_cast<const TransportAddress*>(&(getSmallestNode())); 00488 } else { 00489 leaves.push_back(NodeHandle::UNSPECIFIED_NODE); 00490 bigger = leaves.begin() + (numberOfLeaves >> 1); 00491 smaller = bigger - 1; 00492 ask = static_cast<const TransportAddress*>(&(getBiggestNode())); 00493 } 00494 00495 balanceLeafSet(); 00496 LEAF_TEST(); 00497 00498 if (! ask->isUnspecified()) 00499 awaitingRepair[*ask] = PLSRepairData(simTime(), left); 00500 00501 return *ask; 00502 }
const TransportAddress & PastryLeafSet::repair | ( | const PastryStateMessage * | msg, | |
const PastryStateMsgProximity & | prox | |||
) | [virtual] |
attempt to repair the leafset using a received REPAIR message
msg | the state message of type REPAIR | |
prox | record of proximity values matching the state message |
Reimplemented from PastryStateObject.
Referenced by Pastry::handleStateMessage().
00506 { 00507 std::map<TransportAddress, PLSRepairData>::iterator it; 00508 const TransportAddress* ask; 00509 bool left; 00510 00511 simtime_t now = simTime(); 00512 00513 // first eliminate outdated entries in awaitingRepair: 00514 for (it = awaitingRepair.begin(); it != awaitingRepair.end();) { 00515 if (it->second.ts < (now - repairTimeout)) { 00516 awaitingRepair.erase(it++); 00517 } 00518 else it++; 00519 } 00520 00521 // don't expect any more repair messages: 00522 if (awaitingRepair.empty()) return TransportAddress::UNSPECIFIED_NODE; 00523 00524 // look for source node in our list: 00525 if ( (it = awaitingRepair.find(msg->getSender())) == awaitingRepair.end() ) 00526 return TransportAddress::UNSPECIFIED_NODE; 00527 00528 // which side of the LeafSet is affected: 00529 left = it->second.left; 00530 00531 // remove source node from list: 00532 awaitingRepair.erase(it); 00533 00534 // merge info from repair message: 00535 if (mergeState(msg, prox) || isFull || !wasFull) { 00536 EV << "Pastry: LeafSet repair was successful." << endl; 00537 return TransportAddress::UNSPECIFIED_NODE; 00538 } else { 00539 // repair did not succeed, try again: 00540 ask = &( left ? getSmallestNode() : getBiggestNode() ); 00541 if (ask->isUnspecified() || *ask == msg->getSender()) { 00542 EV << "Pastry: LeafSet giving up repair attempt." << endl; 00543 return TransportAddress::UNSPECIFIED_NODE; 00544 } else { 00545 awaitingRepair[*ask] = PLSRepairData(simTime(), left); 00546 } 00547 return *ask; 00548 } 00549 }
bool PastryLeafSet::isClosestNode | ( | const OverlayKey & | destination | ) | const |
checks if we are the closest node to key destination in the overlay
destination | the key to check |
Referenced by BasePastry::findNode(), and BasePastry::isSiblingFor().
00137 { 00138 // check for simple cases first 00139 if (owner.key == destination) { 00140 return true; 00141 } 00142 00143 if (bigger->isUnspecified() && smaller->isUnspecified()) { 00144 return true; 00145 } 00146 00147 // check if the next bigger or smaller node in the set is closer 00148 // than own node 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 // return true if both are not closer 00160 return ((!biggerIsCloser) && (!smallerIsCloser)); 00161 }
void PastryLeafSet::dumpToStateMessage | ( | PastryStateMessage * | msg | ) | const [virtual] |
dump content of the set to a PastryStateMessage
msg | the PastryStateMessage to be filled with entries |
Implements PastryStateObject.
Referenced by Bamboo::changeState(), BasePastry::sendLeafset(), and BasePastry::sendStateTables().
00164 { 00165 uint i = 0; 00166 std::vector<NodeHandle>::const_iterator it; 00167 00168 msg->setLeafSetArraySize(numberOfLeaves); 00169 for (it = leaves.begin(); it != leaves.end(); it++) 00170 msg->setLeafSet(i++, *it); 00171 }
void PastryLeafSet::dumpToStateMessage | ( | PastryLeafsetMessage * | msg | ) | const [virtual] |
dump content of the set to a PastryLeafsetMessage
msg | the PastryLeafsetMessage to be filled with entries |
00174 { 00175 uint i = 0; 00176 std::vector<NodeHandle>::const_iterator it; 00177 00178 msg->setLeafSetArraySize(numberOfLeaves); 00179 for (it = leaves.begin(); it != leaves.end(); it++) 00180 msg->setLeafSet(i++, *it); 00181 }
const TransportAddress & PastryLeafSet::getRandomNode | ( | ) | [virtual] |
returns a random node from the leafset
Referenced by Bamboo::doLeafsetMaintenance().
00184 { 00185 std::vector<NodeHandle>::iterator i; 00186 uint rnd; 00187 00188 rnd = intuniform(0, numberOfLeaves - 1, 0); 00189 while (rnd < leaves.size()) { 00190 if (!leaves.at(rnd).isUnspecified()) return leaves.at(rnd); 00191 else rnd++; 00192 } 00193 return TransportAddress::UNSPECIFIED_NODE; 00194 00195 }
bool PastryLeafSet::mergeNode | ( | const NodeHandle & | node, | |
simtime_t | prox | |||
) | [virtual] |
merge a node into LeafSet
node | the node to merge | |
prox | the proximity value of the node |
Implements PastryStateObject.
00239 { 00240 std::vector<NodeHandle>::iterator it, it_left, it_right; 00241 const OverlayKey* last_left = &(owner.key); 00242 const OverlayKey* last_right = &(owner.key); 00243 00244 it_left = smaller; 00245 it_right = bigger; 00246 00247 // avoid duplicates 00248 for (it = leaves.begin(); it != leaves.end(); ++it) { 00249 if (it->isUnspecified()) { 00250 isFull = false; 00251 continue; 00252 } 00253 if (it->key == node.key) return false; 00254 } 00255 00256 // look for correct position in left and right half of leafset 00257 while (true) { 00258 if(!isFull) { 00259 // both sides free 00260 if(it_left->key.isUnspecified() && 00261 it_right->key.isUnspecified()) { 00262 insertLeaf(it_left, node); 00263 return true; 00264 } 00265 if (it_left->key.isUnspecified() && 00266 !node.key.isBetween(*last_right, it_right->key)) { 00267 // end of smaller entries found 00268 insertLeaf(it_left, node); 00269 return true; 00270 } 00271 if (it_right->key.isUnspecified() && 00272 !node.key.isBetween(it_left->key, *last_left)) { 00273 // end of bigger entries found 00274 insertLeaf(it_right, node); 00275 return true; 00276 } 00277 } 00278 // left side 00279 if (node.key.isBetween(it_left->key, *last_left)) { 00280 // found correct position for inserting the new entry between 00281 // existing ones 00282 insertLeaf(it_left, node); 00283 return true; 00284 } 00285 // right side 00286 if (node.key.isBetween(*last_right, it_right->key)) { 00287 // found correct position for inserting the new entry between 00288 // existing ones 00289 insertLeaf(it_right, node); 00290 return true; 00291 } 00292 00293 last_right = &(it_right->key); 00294 ++it_right; 00295 00296 if (it_right == leaves.end()) break; 00297 00298 last_left = &(it_left->key); 00299 --it_left; 00300 } 00301 return false; 00302 }
const NodeHandle & PastryLeafSet::getPredecessor | ( | void | ) | const |
return predecessor node for visualizing
Referenced by Pastry::handleTimerEvent(), and BasePastry::updateTooltip().
00097 { 00098 return *smaller; 00099 }
const NodeHandle & PastryLeafSet::getSuccessor | ( | void | ) | const |
return successor node for visualizing
Referenced by Pastry::handleTimerEvent(), and BasePastry::updateTooltip().
00092 { 00093 return *bigger; 00094 }
bool PastryLeafSet::isValid | ( | void | ) | const |
check if LeafSet knows at least one node to the left and to the right
Referenced by createSiblingVector(), Pastry::handleFailedNode(), and Bamboo::handleFailedNode().
void PastryLeafSet::dumpToVector | ( | std::vector< TransportAddress > & | affected | ) | const [virtual] |
appends all leaf set entries to a given vector of TransportAddresses, needed to find all Nodes to be notified after joining.
affected | the vector to fill with leaf set entries |
Implements PastryStateObject.
Referenced by Pastry::changeState().
00386 { 00387 std::vector<NodeHandle>::const_iterator it; 00388 00389 for (it = leaves.begin(); it != leaves.end(); it++) 00390 if (!it->isUnspecified()) 00391 affected.push_back(*it); 00392 }
NodeVector * PastryLeafSet::createSiblingVector | ( | const OverlayKey & | key, | |
int | numSiblings | |||
) | const |
Referenced by BasePastry::findNode(), and BasePastry::isSiblingFor().
00199 { 00200 std::vector<NodeHandle>::const_iterator it; 00201 00202 // create temporary comparator 00203 KeyDistanceComparator<KeyRingMetric>* comp = 00204 new KeyDistanceComparator<KeyRingMetric>( key ); 00205 00206 // create result vector 00207 NodeVector* result = new NodeVector( numSiblings, comp ); 00208 00209 result->add(owner); 00210 00211 for (it = leaves.begin(); it != leaves.end(); it++) { 00212 if (!it->isUnspecified()) { 00213 result->add(*it); 00214 } 00215 } 00216 00217 delete comp; 00218 00219 if (!isValid()) { 00220 return result; 00221 } 00222 00223 // if the leafset is not full, we could have a very small network 00224 // => return true (FIXME hack) 00225 if (leaves.front().isUnspecified() || leaves.back().isUnspecified()) { 00226 return result; 00227 } 00228 00229 if ((result->contains(getBiggestKey())) || 00230 (result->contains(getSmallestKey()))) { 00231 delete result; 00232 return NULL; 00233 } 00234 00235 return result; 00236 }
PastryNewLeafsMessage * PastryLeafSet::getNewLeafsMessage | ( | void | ) |
generates a newLeafs-message if LeafSet changed since last call to this method.
Referenced by BasePastry::newLeafs().
00552 { 00553 std::vector<NodeHandle>::const_iterator it; 00554 PastryNewLeafsMessage* msg; 00555 uint i = 0; 00556 00557 if (! newLeafs) return NULL; 00558 newLeafs = false; 00559 00560 msg = new PastryNewLeafsMessage("PastryNewLeafs"); 00561 00562 msg->setLeafsArraySize(numberOfLeaves); 00563 for (it = leaves.begin(); it != leaves.end(); it++) 00564 msg->setLeafs(i++, *it); 00565 00566 msg->setLength(PASTRYNEWLEAFS_L(msg)); 00567 return msg; 00568 }
void PastryLeafSet::earlyInit | ( | void | ) | [private, virtual] |
const NodeHandle & PastryLeafSet::getBiggestNode | ( | void | ) | const [private] |
return the node with the biggest key in the LeafSet or NodeHandle::UNSPECIFIED_NODE if LeafSet is empty
Referenced by failedNode(), findCloserNode(), getBiggestKey(), and repair().
00407 { 00408 std::vector<NodeHandle>::const_iterator i = leaves.end()-1; 00409 while ((i->isUnspecified()) && (i != bigger)) i--; 00410 return *i; 00411 }
const OverlayKey & PastryLeafSet::getBiggestKey | ( | void | ) | const [private] |
return the biggest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty
Referenced by createSiblingVector(), and getDestinationNode().
00414 { 00415 return getBiggestNode().key; 00416 }
const NodeHandle & PastryLeafSet::getSmallestNode | ( | void | ) | const [private] |
return the node with the smallest key in the LeafSet or NodeHandle::UNSPECIFIED_NODE if LeafSet is empty
Referenced by failedNode(), findCloserNode(), getSmallestKey(), and repair().
00395 { 00396 std::vector<NodeHandle>::const_iterator i = leaves.begin(); 00397 while ((i->isUnspecified()) && (i != smaller)) i++; 00398 return *i; 00399 }
const OverlayKey & PastryLeafSet::getSmallestKey | ( | void | ) | const [private] |
return the smallest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty
Referenced by createSiblingVector(), and getDestinationNode().
00402 { 00403 return getSmallestNode().key; 00404 }
bool PastryLeafSet::isLeft | ( | const OverlayKey & | key | ) | const [private] |
test if a given key should be placed on the left or on the right side of the leaf set
key | key to test |
void PastryLeafSet::insertLeaf | ( | std::vector< NodeHandle >::iterator & | it, | |
const NodeHandle & | node | |||
) | [private] |
insert a leaf at a given position
it | iterator where to insert the new leaf | |
node | NodeHandle of new leaf |
Referenced by mergeNode().
00306 { 00307 LEAF_TEST(); 00308 bool issmaller = (it <= smaller); 00309 if (issmaller) { 00310 if (!leaves.front().isUnspecified()) { 00311 overlay->callUpdate(leaves.front(), false); 00312 } 00313 overlay->callUpdate(node, true); 00314 00315 leaves.insert(++it, node); 00316 NodeHandle& temp = leaves.front(); 00317 if (!temp.isUnspecified() && leaves.back().isUnspecified()) { 00318 leaves.back() = temp; 00319 } 00320 leaves.erase(leaves.begin()); 00321 00322 00323 } else { 00324 if (!leaves.back().isUnspecified()) { 00325 overlay->callUpdate(leaves.back(), false); 00326 } 00327 overlay->callUpdate(node, true); 00328 00329 leaves.insert(it, node); 00330 NodeHandle& temp = leaves.back(); 00331 if (!temp.isUnspecified() && leaves.front().isUnspecified()) { 00332 leaves.front() = temp; 00333 } 00334 leaves.pop_back(); 00335 } 00336 00337 if (!leaves.front().isUnspecified() && 00338 !leaves.back().isUnspecified()) { 00339 isFull = true; 00340 } else isFull = false; 00341 00342 newLeafs = true; 00343 bigger = leaves.begin() + (numberOfLeaves >> 1); 00344 smaller = bigger - 1; 00345 00346 // ensure balance in leafset 00347 if (!isFull) { 00348 balanceLeafSet(); 00349 } 00350 LEAF_TEST(); 00351 }
bool PastryLeafSet::balanceLeafSet | ( | ) | [private] |
Referenced by failedNode(), and insertLeaf().
00354 { 00355 if (isFull || 00356 (!leaves.front().isUnspecified() && 00357 !(leaves.end() - 2)->isUnspecified()) || 00358 (!leaves.back().isUnspecified() && 00359 !(leaves.begin() + 1)->isUnspecified())) 00360 return false; 00361 00362 std::vector<NodeHandle>::iterator it_left, it_right; 00363 00364 for (it_left = smaller, it_right = bigger; 00365 it_right != leaves.end(); --it_left, ++it_right) { 00366 if (it_left->isUnspecified()) { 00367 if (it_right->isUnspecified() || 00368 (it_right + 1) == leaves.end() || 00369 (it_right + 1)->isUnspecified()) return false; 00370 *it_left = *(it_right + 1); 00371 *(it_right + 1) = NodeHandle::UNSPECIFIED_NODE; 00372 return true; 00373 } else if (it_right->isUnspecified()) { 00374 00375 if (it_left == leaves.begin() || 00376 (it_left - 1)->isUnspecified()) return false; 00377 *it_right = *(it_left - 1); 00378 *(it_left - 1) = NodeHandle::UNSPECIFIED_NODE; 00379 return true; 00380 } 00381 } 00382 return false; // should not happen 00383 }
uint PastryLeafSet::numberOfLeaves [private] |
Referenced by dumpToStateMessage(), failedNode(), getNewLeafsMessage(), getRandomNode(), and insertLeaf().
double PastryLeafSet::repairTimeout [private] |
Referenced by repair().
BasePastry* PastryLeafSet::overlay [private] |
std::vector<NodeHandle> PastryLeafSet::leaves [private] |
std::vector<NodeHandle>::iterator PastryLeafSet::smaller [private] |
Referenced by balanceLeafSet(), failedNode(), getPredecessor(), getSmallestNode(), initializeSet(), insertLeaf(), isClosestNode(), isValid(), and mergeNode().
std::vector<NodeHandle>::iterator PastryLeafSet::bigger [private] |
Referenced by balanceLeafSet(), failedNode(), getBiggestNode(), getSuccessor(), initializeSet(), insertLeaf(), isClosestNode(), isValid(), and mergeNode().
std::map<TransportAddress, PLSRepairData> PastryLeafSet::awaitingRepair [private] |
Referenced by failedNode(), initializeSet(), and repair().
bool PastryLeafSet::newLeafs [private] |
Referenced by failedNode(), getNewLeafsMessage(), initializeSet(), and insertLeaf().
bool PastryLeafSet::isFull [private] |
Referenced by balanceLeafSet(), failedNode(), initializeSet(), insertLeaf(), mergeNode(), and repair().
bool PastryLeafSet::wasFull [private] |
Referenced by failedNode(), initializeSet(), and repair().