PastryLeafSet Class Reference

PastryLeafSet module. More...

#include <PastryLeafSet.h>

Inheritance diagram for PastryLeafSet:
PastryStateObject

List of all members.

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 NodeHandlegetDestinationNode (const OverlayKey &destination)
 gets the final node according to the Pastry routing scheme.
virtual const NodeHandlefindCloserNode (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 TransportAddressfailedNode (const TransportAddress &failed)
 tells the leafset that a node has failed
virtual const TransportAddressrepair (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 TransportAddressgetRandomNode ()
 returns a random node from the leafset
bool mergeNode (const NodeHandle &node, simtime_t prox)
 merge a node into LeafSet
const NodeHandlegetPredecessor (void) const
 return predecessor node for visualizing
const NodeHandlegetSuccessor (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.
NodeVectorcreateSiblingVector (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 NodeHandlegetBiggestNode (void) const
 return the node with the biggest key in the LeafSet or NodeHandle::UNSPECIFIED_NODE if LeafSet is empty
const OverlayKeygetBiggestKey (void) const
 return the biggest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty
const NodeHandlegetSmallestNode (void) const
 return the node with the smallest key in the LeafSet or NodeHandle::UNSPECIFIED_NODE if LeafSet is empty
const OverlayKeygetSmallestKey (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
BasePastryoverlay
 pointer to the main pastry module
std::vector< NodeHandleleaves
std::vector< NodeHandle >::iterator smaller
std::vector< NodeHandle >::iterator bigger
std::map< TransportAddress,
PLSRepairData
awaitingRepair
bool newLeafs
bool isFull
bool wasFull

Detailed Description

PastryLeafSet module.

This module contains the LeafSet of the Pastry implementation.

Author:
Felix Palmen
See also:
Pastry

Definition at line 60 of file PastryLeafSet.h.


Member Function Documentation

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

Parameters:
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

Parameters:
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.

Parameters:
affected the vector to fill with leaf set entries

Implements PastryStateObject.

Definition at line 412 of file PastryLeafSet.cc.

Referenced by Pastry::changeState().

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 }

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

Parameters:
failed the failed node
Returns:
a node to ask for REPAIR or TransportAddress::UNSPECIFIED_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.

Parameters:
destination the destination key
optimize if set, check all nodes and return the best/closest one
Returns:
a closer NodeHandle or NodeHandle::UNSPECIFIED_NODE if none was found

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().

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 }

const OverlayKey & PastryLeafSet::getBiggestKey ( void   )  const [private]

return the biggest key in the LeafSet or OverlayKey::UNSPECIFIED_KEY if LeafSet is empty

Returns:
biggest key in the set

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

Returns:
biggest node in the set

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.

Parameters:
destination the destination key
Returns:
the NodeHandle of the final node or NodeHandle::UNSPECIFIED_NODE if given destination key is outside the leaf set

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.

Returns:
pointer to newLeafs-message or NULL

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

Returns:
a random node or TransportAddress::UNSPECIFIED_NODE

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

Returns:
smallest key in the set

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

Returns:
smallest node in the set

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

Parameters:
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

Parameters:
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

Parameters:
destination the key to check
Returns:
true if we are closest to given key

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

Parameters:
key key to test
Returns:
true if key belongs to the left
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().

00102 {
00103     return (!(smaller->isUnspecified() || bigger->isUnspecified()));
00104 }

bool PastryLeafSet::mergeNode ( const NodeHandle node,
simtime_t  prox 
) [virtual]

merge a node into LeafSet

Parameters:
node the node to merge
prox the proximity value of the node
Returns:
true if node was merged

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

Parameters:
msg the state message of type REPAIR
prox record of proximity values matching the state message
Returns:
another node to ask for REPAIR or TransportAddress::UNSPECIFIED_NODE

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 }


Member Data Documentation

Definition at line 203 of file PastryLeafSet.h.

Referenced by failedNode(), initializeSet(), and repair().

std::vector<NodeHandle>::iterator PastryLeafSet::bigger [private]
bool PastryLeafSet::isFull [private]
std::vector<NodeHandle> PastryLeafSet::leaves [private]
bool PastryLeafSet::newLeafs [private]

Definition at line 205 of file PastryLeafSet.h.

Referenced by failedNode(), getNewLeafsMessage(), initializeSet(), and insertLeaf().

uint32_t PastryLeafSet::numberOfLeaves [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]
bool PastryLeafSet::wasFull [private]

Definition at line 208 of file PastryLeafSet.h.

Referenced by failedNode(), initializeSet(), and repair().


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:18 2010 for OverSim by  doxygen 1.6.3