PastryLeafSet module. More...
#include <PastryLeafSet.h>
Public Member Functions | |
void | initializeSet (uint32_t numberOfLeaves, uint32_t bitsPerDigit, simtime_t 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 | |
uint32_t | numberOfLeaves |
simtime_t | 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 |
PastryLeafSet module.
This module contains the LeafSet of the Pastry implementation.
Definition at line 60 of file PastryLeafSet.h.
bool PastryLeafSet::balanceLeafSet | ( | ) | [private] |
Definition at line 380 of file PastryLeafSet.cc.
Referenced by failedNode(), and insertLeaf().
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; // should not happen 00410 }
NodeVector * PastryLeafSet::createSiblingVector | ( | const OverlayKey & | key, | |
int | numSiblings | |||
) | const |
Definition at line 220 of file PastryLeafSet.cc.
Referenced by BasePastry::findNode(), and BasePastry::isSiblingFor().
00222 { 00223 std::vector<NodeHandle>::const_iterator it; 00224 00225 // create temporary comparator 00226 KeyDistanceComparator<KeyRingMetric>* comp = 00227 new KeyDistanceComparator<KeyRingMetric>( key ); 00228 00229 // create result vector 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 // if the leafset is not full, we could have a very small network 00247 // => return true (FIXME hack) 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 }
void PastryLeafSet::dumpToStateMessage | ( | PastryLeafsetMessage * | msg | ) | const [virtual] |
dump content of the set to a PastryLeafsetMessage
msg | the PastryLeafsetMessage to be filled with entries |
Definition at line 180 of file PastryLeafSet.cc.
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 }
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.
Definition at line 163 of file PastryLeafSet.cc.
Referenced by Bamboo::changeState(), Pastry::doSecondStage(), BasePastry::sendLeafset(), and BasePastry::sendStateTables().
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 }
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.
Definition at line 412 of file PastryLeafSet.cc.
Referenced by Pastry::changeState().
void PastryLeafSet::earlyInit | ( | void | ) | [private, virtual] |
initialize watches etc.
Implements PastryStateObject.
Definition at line 53 of file PastryLeafSet.cc.
00054 { 00055 WATCH_VECTOR(leaves); 00056 }
const TransportAddress & PastryLeafSet::failedNode | ( | const TransportAddress & | failed | ) | [virtual] |
tells the leafset that a node has failed
failed | the failed node |
Implements PastryStateObject.
Definition at line 486 of file PastryLeafSet.cc.
Referenced by Pastry::handleFailedNode(), and Bamboo::handleFailedNode().
00487 { 00488 std::vector<NodeHandle>::iterator i; 00489 const TransportAddress* ask; 00490 bool left = true; 00491 00492 // search failed node in leafset: 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 // failed node not in leafset: 00499 if (i == leaves.end()) return TransportAddress::UNSPECIFIED_NODE; 00500 00501 overlay->callUpdate(*i, false); 00502 00503 // remove failed node: 00504 leaves.erase(i); 00505 newLeafs = true; 00506 00507 wasFull = isFull; 00508 isFull = false; 00509 00510 // insert UNSPECIFIED_NODE at front or back and return correct node 00511 // to ask for repair: 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 }
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.
Definition at line 458 of file PastryLeafSet.cc.
Referenced by BasePastry::findNode().
00460 { 00461 std::vector<NodeHandle>::const_iterator i; 00462 const NodeHandle* ret = &NodeHandle::UNSPECIFIED_NODE; 00463 00464 // this will only be called after getDestinationNode() returned 00465 // NodeHandle::UNSPECIFIED_NODE, so a closer Node can only be the biggest 00466 // or the smallest node in the LeafSet. 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 }
void PastryLeafSet::findCloserNodes | ( | const OverlayKey & | destination, | |
NodeVector * | nodes | |||
) | [virtual] |
Implements PastryStateObject.
Definition at line 447 of file PastryLeafSet.cc.
Referenced by BasePastry::findNode().
const OverlayKey & PastryLeafSet::getBiggestKey | ( | void | ) | const [private] |
return the biggest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty
Definition at line 442 of file PastryLeafSet.cc.
Referenced by createSiblingVector(), and getDestinationNode().
00443 { 00444 return getBiggestNode().getKey(); 00445 }
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
Definition at line 434 of file PastryLeafSet.cc.
Referenced by failedNode(), findCloserNode(), getBiggestKey(), and repair().
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 }
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.
Definition at line 106 of file PastryLeafSet.cc.
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.getKey()); 00119 if (biggest->isUnspecified()) biggest = &(owner.getKey()); 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 }
PastryNewLeafsMessage * PastryLeafSet::getNewLeafsMessage | ( | void | ) |
generates a newLeafs-message if LeafSet changed since last call to this method.
Definition at line 588 of file PastryLeafSet.cc.
Referenced by BasePastry::newLeafs().
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 }
const NodeHandle & PastryLeafSet::getPredecessor | ( | void | ) | const |
return predecessor node for visualizing
Definition at line 96 of file PastryLeafSet.cc.
Referenced by BasePastry::updateTooltip().
00097 { 00098 return *smaller; 00099 }
const TransportAddress & PastryLeafSet::getRandomNode | ( | ) | [virtual] |
returns a random node from the leafset
Definition at line 196 of file PastryLeafSet.cc.
Referenced by Bamboo::doLeafsetMaintenance().
00197 { 00198 //std::vector<NodeHandle>::iterator i; 00199 uint32_t rnd; 00200 int i; 00201 00202 rnd = intuniform(0, numberOfLeaves - 1, 0); 00203 i = rnd; 00204 //while (rnd < leaves.size()) { 00205 while (i < (int)leaves.size()) { 00206 if (!leaves[i].isUnspecified()) return leaves[i]; 00207 else i++;//rnd++; 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 }
const OverlayKey & PastryLeafSet::getSmallestKey | ( | void | ) | const [private] |
return the smallest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty
Definition at line 429 of file PastryLeafSet.cc.
Referenced by createSiblingVector(), and getDestinationNode().
00430 { 00431 return getSmallestNode().getKey(); 00432 }
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
Definition at line 421 of file PastryLeafSet.cc.
Referenced by failedNode(), findCloserNode(), getSmallestKey(), and repair().
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 }
const NodeHandle & PastryLeafSet::getSuccessor | ( | void | ) | const |
return successor node for visualizing
Definition at line 91 of file PastryLeafSet.cc.
Referenced by BasePastry::updateTooltip().
00092 { 00093 return *bigger; 00094 }
void PastryLeafSet::initializeSet | ( | uint32_t | numberOfLeaves, | |
uint32_t | bitsPerDigit, | |||
simtime_t | 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 |
Definition at line 58 of file PastryLeafSet.cc.
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 (uint32_t 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 }
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 |
Definition at line 329 of file PastryLeafSet.cc.
Referenced by mergeNode().
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 // ensure balance in leafset 00374 if (!isFull) { 00375 balanceLeafSet(); 00376 } 00377 LEAF_TEST(); 00378 }
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 |
Definition at line 136 of file PastryLeafSet.cc.
Referenced by BasePastry::findNode(), and BasePastry::isSiblingFor().
00137 { 00138 // check for simple cases first 00139 if (owner.getKey() == 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 }
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 |
bool PastryLeafSet::isValid | ( | void | ) | const |
check if LeafSet knows at least one node to the left and to the right
Definition at line 101 of file PastryLeafSet.cc.
Referenced by createSiblingVector(), Pastry::doSecondStage(), Pastry::handleFailedNode(), and Bamboo::handleFailedNode().
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.
Definition at line 261 of file PastryLeafSet.cc.
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 // avoid duplicates 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 // look for correct position in left and right half of leafset 00282 while (true) { 00283 if(!isFull) { 00284 // both sides free 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 // end of smaller entries found 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 // end of bigger entries found 00299 insertLeaf(it_right, node); 00300 return true; 00301 } 00302 } 00303 // left side 00304 if (node.getKey().isBetween(it_left->getKey(), *last_left)) { 00305 // found correct position for inserting the new entry between 00306 // existing ones 00307 insertLeaf(it_left, node); 00308 return true; 00309 } 00310 // right side 00311 if (node.getKey().isBetween(*last_right, it_right->getKey())) { 00312 // found correct position for inserting the new entry between 00313 // existing ones 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 }
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 |
Definition at line 537 of file PastryLeafSet.cc.
Referenced by Pastry::handleStateMessage().
00539 { 00540 std::map<TransportAddress, PLSRepairData>::iterator it; 00541 const TransportAddress* ask; 00542 bool left; 00543 00544 simtime_t now = simTime(); 00545 00546 // first eliminate outdated entries in awaitingRepair: 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 // don't expect any more repair messages: 00555 if (awaitingRepair.empty()) return TransportAddress::UNSPECIFIED_NODE; 00556 00557 // look for source node in our list: 00558 if ( (it = awaitingRepair.find(msg->getSender())) == awaitingRepair.end() ) 00559 return TransportAddress::UNSPECIFIED_NODE; 00560 00561 // which side of the LeafSet is affected: 00562 left = it->second.left; 00563 00564 // remove source node from list: 00565 awaitingRepair.erase(it); 00566 00567 // merge info from repair message: 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 // repair did not succeed, try again: 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 }
std::map<TransportAddress, PLSRepairData> PastryLeafSet::awaitingRepair [private] |
Definition at line 203 of file PastryLeafSet.h.
Referenced by failedNode(), initializeSet(), and repair().
std::vector<NodeHandle>::iterator PastryLeafSet::bigger [private] |
Definition at line 201 of file PastryLeafSet.h.
Referenced by balanceLeafSet(), failedNode(), getBiggestNode(), getSuccessor(), initializeSet(), insertLeaf(), isClosestNode(), isValid(), and mergeNode().
bool PastryLeafSet::isFull [private] |
Definition at line 207 of file PastryLeafSet.h.
Referenced by balanceLeafSet(), failedNode(), initializeSet(), insertLeaf(), mergeNode(), and repair().
std::vector<NodeHandle> PastryLeafSet::leaves [private] |
Definition at line 199 of file PastryLeafSet.h.
Referenced by balanceLeafSet(), createSiblingVector(), dumpToStateMessage(), dumpToVector(), earlyInit(), failedNode(), findCloserNodes(), getBiggestNode(), getDestinationNode(), getNewLeafsMessage(), getRandomNode(), getSmallestNode(), initializeSet(), insertLeaf(), and mergeNode().
bool PastryLeafSet::newLeafs [private] |
Definition at line 205 of file PastryLeafSet.h.
Referenced by failedNode(), getNewLeafsMessage(), initializeSet(), and insertLeaf().
uint32_t PastryLeafSet::numberOfLeaves [private] |
Definition at line 196 of file PastryLeafSet.h.
Referenced by dumpToStateMessage(), failedNode(), getNewLeafsMessage(), getRandomNode(), and insertLeaf().
BasePastry* PastryLeafSet::overlay [private] |
pointer to the main pastry module
Definition at line 198 of file PastryLeafSet.h.
Referenced by failedNode(), getBiggestNode(), getSmallestNode(), insertLeaf(), and mergeNode().
simtime_t PastryLeafSet::repairTimeout [private] |
Definition at line 197 of file PastryLeafSet.h.
Referenced by repair().
std::vector<NodeHandle>::iterator PastryLeafSet::smaller [private] |
Definition at line 200 of file PastryLeafSet.h.
Referenced by balanceLeafSet(), failedNode(), getPredecessor(), getSmallestNode(), initializeSet(), insertLeaf(), isClosestNode(), isValid(), and mergeNode().
bool PastryLeafSet::wasFull [private] |
Definition at line 208 of file PastryLeafSet.h.
Referenced by failedNode(), initializeSet(), and repair().