PastryLeafSet Class Reference

#include <PastryLeafSet.h>

Inheritance diagram for PastryLeafSet:

PastryStateObject

List of all members.


Detailed Description

PastryLeafSet module.

This module contains the LeafSet of the Pastry implementation.

Author:
Felix Palmen
See also:
Pastry

Public Member Functions

void initializeSet (uint numberOfLeaves, uint bitsPerDigit, double 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

uint numberOfLeaves
double 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

Member Function Documentation

void PastryLeafSet::initializeSet ( uint  numberOfLeaves,
uint  bitsPerDigit,
double  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

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.

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.

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.

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.

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

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

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

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

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

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

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

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

Returns:
a random node or TransportAddress::UNSPECIFIED_NODE

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

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

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

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

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.

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.

Returns:
pointer to newLeafs-message or NULL

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]

initialize watches etc.

Implements PastryStateObject.

00054 {
00055     WATCH_VECTOR(leaves);
00056 }

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

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

Returns:
biggest key in the set

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

Returns:
smallest node in the set

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

Returns:
smallest key in the set

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

Parameters:
key key to test
Returns:
true if key belongs to the left

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

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 }


Member Data Documentation

double PastryLeafSet::repairTimeout [private]

Referenced by repair().

pointer to the main pastry module

Referenced by failedNode(), and insertLeaf().

std::vector<NodeHandle> PastryLeafSet::leaves [private]

std::vector<NodeHandle>::iterator PastryLeafSet::smaller [private]

std::vector<NodeHandle>::iterator PastryLeafSet::bigger [private]

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

bool PastryLeafSet::newLeafs [private]

bool PastryLeafSet::isFull [private]

bool PastryLeafSet::wasFull [private]

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


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:07 2008 for ITM OverSim by  doxygen 1.5.5