BasePathLookup Class Reference

#include <BaseLookup.h>

List of all members.


Detailed Description

This class implements a path lookup.

Author:
Sebastian Mies


Protected Member Functions

bool accepts (int rpcId)
void handleResponse (FindNodeResponse *msg)
void handleTimeout (BaseCallMessage *msg, const TransportAddress &dest, int rpcId)
void handleFailedNodeResponse (const NodeHandle &src, cMessage *findNodeExt, bool retry)
 BasePathLookup (BaseLookup *lookup)
virtual ~BasePathLookup ()
virtual FindNodeCall * createRpcMessage (cMessage *findNodeExt=NULL)
 Creates a find node call message.
void add (const NodeHandle &handle, const NodeHandle &source=NodeHandle::UNSPECIFIED_NODE)
 Adds a NodeHandle to next hops.

Protected Attributes

BaseLookuplookup
int hops
int step
int pendingRpcs
bool finished
bool success
NodePairVector nextHops
std::map< TransportAddress,
NodeHandle
oldNextHops

Private Member Functions

void sendRpc (int num, cMessage *FindNodeExt=NULL)

Friends

class BaseLookup


Constructor & Destructor Documentation

BasePathLookup::BasePathLookup ( BaseLookup lookup  )  [protected]

00511 {
00512     this->lookup = lookup;
00513     this->hops = 0;
00514     this->step = 0;
00515     this->pendingRpcs = 0;
00516     this->finished = false;
00517     this->success = false;
00518     this->nextHops = NodePairVector( lookup->config.redundantNodes, lookup );
00519 }

BasePathLookup::~BasePathLookup (  )  [protected, virtual]

00522 {}


Member Function Documentation

bool BasePathLookup::accepts ( int  rpcId  )  [protected]

00525 {
00526     bool accept = ( rpcId == step ) && !finished;
00527     return accept;
00528 }

void BasePathLookup::handleResponse ( FindNodeResponse *  msg  )  [protected]

00531 {
00532     if (finished)
00533         return;
00534 
00535     const NodeHandle& source = msg->getSrcNode();
00536     std::map<TransportAddress, NodeHandle>::iterator oldPos;
00537     oldPos = oldNextHops.find(source);
00538     if (oldPos != oldNextHops.end()) oldNextHops.erase(oldPos);
00539 
00540     // increase hops: FIXME don't count local hops
00541     if (lookup->overlay->getThisNode() != source)
00542         hops++;
00543     step++;
00544 
00545     // decrease pending rpcs
00546     pendingRpcs--;
00547 
00548     // mode: merge or replace
00549     if (!lookup->config.merge) {
00550         nextHops.clear();
00551     }
00552 
00553     // add new next hops
00554     for ( uint i=0; i < msg->getClosestNodesArraySize(); i++ ) {
00555         const NodeHandle& handle = msg->getClosestNodes(i);
00556 
00557         // add NodeHandle to next hops and siblings
00558         add( handle, source ); 
00559 
00560         // check if node was found
00561         if ((lookup->numSiblings == 0) && (handle.key == lookup->key)
00562             && (!lookup->config.secure)) {
00563 
00564             lookup->addSibling( handle );
00565 
00566             // TODO: definition of hop count for iterative lookups is unclear
00567             // don't count local hops
00568             if (lookup->overlay->getThisNode() != msg->getSrcNode()) {
00569 //                        && (lookup->key != msg->getSrcNode().key)) {
00570                 hops++;
00571             }
00572             finished = true;
00573             success = true;
00574             return;
00575         } else
00576             if (lookup->numSiblings != 0 && !lookup->config.secure && msg->getSiblings() )
00577             lookup->addSibling( handle );
00578 
00579     }
00580 
00581     // check if sibling lookup is finished
00582     if ( msg->getSiblings() && msg->getClosestNodesArraySize() != 0 &&
00583          lookup->numSiblings != 0 && !lookup->config.secure ) {
00584 
00585         finished = true;
00586         success = true;
00587         return;
00588     }
00589 
00590     // extract find node extension object
00591     cMessage* findNodeExt = NULL;
00592     if (msg->hasObject("findNodeExt"))
00593         findNodeExt = (cMessage*)msg->removeObject("findNodeExt");
00594 
00595     // send next rpcs
00596     sendRpc( lookup->config.parallelRpcs, findNodeExt );
00597 
00598     // ...
00599     delete findNodeExt;
00600 }

void BasePathLookup::handleTimeout ( BaseCallMessage *  msg,
const TransportAddress dest,
int  rpcId 
) [protected]

00605 {
00606     if (finished)
00607         return;
00608 
00609     EV << "BasePathLookup: Timeout of RPC " << rpcId << endl;
00610 
00611     std::map<TransportAddress, NodeHandle>::iterator oldPos;
00612     oldPos = oldNextHops.find(dest);
00613 
00614     // decrease pending rpcs
00615     pendingRpcs--;
00616 
00617     cMessage* findNodeExt = NULL;
00618     if (msg && msg->hasObject("findNodeExt")) {
00619         findNodeExt = static_cast<cMessage*>(
00620                 msg->removeObject("findNodeExt"));
00621     }
00622 
00623     if (oldPos == oldNextHops.end() || (!lookup->config.failedNodeRpcs))
00624     {
00625         // last rpc? yes-> send next rpc
00626         if (pendingRpcs==0) sendRpc(1, findNodeExt);
00627         delete findNodeExt;
00628     }
00629     else
00630     {
00631         if (oldPos->second.isUnspecified())
00632         {
00633             FindNodeCall* findNodeCall = dynamic_cast<FindNodeCall*>(msg);
00634             // answer was from local findNode()
00635             if (findNodeCall && lookup->overlay->handleFailedNode(dest))
00636             {
00637                 NodeVector* retry = lookup->overlay->findNode(
00638                         findNodeCall->getLookupKey(), -1,
00639                         lookup->numSiblings, msg);
00640                 for (NodeVector::iterator i = retry->begin();
00641                         i != retry->end(); i++)
00642                     nextHops.add(std::pair<NodeHandle, NodeHandle>(
00643                                 *i, NodeHandle::UNSPECIFIED_NODE));
00644                 delete(retry);
00645             }
00646             if (pendingRpcs==0) sendRpc(1, findNodeExt);
00647             delete findNodeExt;
00648         }
00649         else
00650         {
00651             FailedNodeCall* call = new FailedNodeCall("FailedNodeCall");
00652             call->setFailedNode(dest);
00653             call->setLength( FAILEDNODECALL_L(call) );
00654             if (findNodeExt)
00655             {
00656                 call->addObject(findNodeExt);
00657                 call->addLength(findNodeExt->length());
00658             }
00659             lookup->overlay->countFailedNodeCall( call );
00660             lookup->overlay->sendRpcMessage(oldPos->second, call, lookup);
00661         }
00662     }
00663 }

void BasePathLookup::handleFailedNodeResponse ( const NodeHandle src,
cMessage *  findNodeExt,
bool  retry 
) [protected]

00667 {
00668     if (finished) return;
00669 
00670     std::map<TransportAddress, NodeHandle>::iterator oldPos;
00671     for (oldPos = oldNextHops.begin(); oldPos != oldNextHops.end(); oldPos++)
00672         if ((! oldPos->second.isUnspecified()) &&
00673             (oldPos->second == src)) break;
00674 
00675     if (oldPos == oldNextHops.end()) return;
00676 
00677     std::map<TransportAddress, NodeHandle>::iterator oldSrcPos =
00678         oldNextHops.find(src);
00679     const NodeHandle* oldSrc = &NodeHandle::UNSPECIFIED_NODE;
00680     if (oldSrcPos != oldNextHops.end()) oldSrc = &(oldSrcPos->second);
00681 
00682     if (retry)
00683     {
00684         nextHops.add(std::pair<NodeHandle, NodeHandle>(src, *oldSrc));
00685     }
00686 
00687     oldNextHops.erase(oldPos);
00688 
00689     // last rpc? yes-> send next rpc
00690     if ( pendingRpcs == 0 )
00691         sendRpc( 1, findNodeExt );
00692 }

void BasePathLookup::sendRpc ( int  num,
cMessage *  FindNodeExt = NULL 
) [private]

00695 {
00696     // path finished? yes -> quit
00697     if (finished)
00698         return;
00699 
00700     // check for maximum hop count
00701     if (lookup->hopCountMax && (hops >= lookup->hopCountMax)) {
00702         EV << "BasePathLookup::sendRpc(): Max hop count exceeded - "
00703         << "lookup failed!" << endl;
00704         finished = true;
00705         success = false;
00706         return;
00707     }
00708 
00709     // send rpc messages
00710 
00711     while ( num > 0 && nextHops.size() != 0 ) {
00712 
00713         // get top node pair
00714         const std::pair<NodeHandle, NodeHandle>& pair = nextHops.front();
00715 
00716         // check if node has already been visited? no ->
00717         // TODO: doesn't work with Broose
00718         if ( !lookup->getVisited( pair.first ) ) {
00719 
00720             // send rpc to node increase pending rpcs
00721             pendingRpcs++;
00722             num--;
00723             FindNodeCall* call = createRpcMessage( findNodeExt );
00724             lookup->overlay->countFindNodeCall( call );
00725             lookup->sendRpc( pair.first, call, this, step );
00726             oldNextHops[pair.first] = pair.second;
00727         }
00728 
00729         // delete first element and continue
00730         nextHops.erase( nextHops.begin() );
00731     }
00732 
00733     // no rpc sent and no pending rpcs? -> failed
00734     if ( pendingRpcs == 0 ) {
00735         finished = true;
00736         success = false;
00737     }
00738 }

FindNodeCall * BasePathLookup::createRpcMessage ( cMessage *  findNodeExt = NULL  )  [protected, virtual]

Creates a find node call message.

This method can be overridden to add some additional state information to the FindNodeCall message.

Parameters:
findNodeExt Pointer to a optional cMessage, that may contain overlay specific data to be attached to FindNode RPCs and BaseRouteMessages
Returns:
Pointer to a new FindNodeCall message.
00741 {
00742     // create default find node call message
00743     FindNodeCall* call = new FindNodeCall( "FindNodeCall" );
00744     call->setLookupKey( lookup->key );
00745     call->setNumRedundantNodes(lookup->config.redundantNodes);
00746     call->setNumSiblings(lookup->numSiblings);
00747     call->setLength( FINDNODECALL_L(call) );
00748 
00749     // duplicate extension object
00750     if ( findNodeExt != NULL ) {
00751         call->addObject( (cObject*)findNodeExt->dup() );
00752         call->addLength( findNodeExt->length() );
00753     }
00754 
00755     return call;
00756 }

void BasePathLookup::add ( const NodeHandle handle,
const NodeHandle source = NodeHandle::UNSPECIFIED_NODE 
) [protected]

Adds a NodeHandle to next hops.

00759 {
00760     if ( lookup->config.merge )
00761         nextHops.add( std::pair<NodeHandle, NodeHandle>(handle, source) );
00762     else
00763         nextHops.push_back( std::pair<NodeHandle, NodeHandle>(handle, source) );
00764 }


Friends And Related Function Documentation

friend class BaseLookup [friend]


Member Data Documentation

BaseLookup* BasePathLookup::lookup [protected]

int BasePathLookup::hops [protected]

int BasePathLookup::step [protected]

int BasePathLookup::pendingRpcs [protected]

bool BasePathLookup::finished [protected]

bool BasePathLookup::success [protected]

NodePairVector BasePathLookup::nextHops [protected]

std::map<TransportAddress, NodeHandle> BasePathLookup::oldNextHops [protected]


The documentation for this class was generated from the following files:
Generated on Tue Jul 24 16:51:18 2007 for ITM OverSim by  doxygen 1.5.1