BaseLookup Class Reference

#include <BaseLookup.h>

Inheritance diagram for BaseLookup:

RpcListener AbstractLookup Comparator< OverlayKey > List of all members.

Detailed Description

This class implements a basic greedy lookup strategy.

It uses the standard metric for greedy behaviour. If another metric is needed, the distance function can be replaced by overriding the distance method.

Author:
Sebastian Mies


Public Member Functions

 BaseLookup (BaseOverlay *overlay, const BaseLookupConfiguration &config, const cObject *findNodeExt=NULL)
virtual ~BaseLookup ()
void lookup (const OverlayKey &key, uint numNeighbors=0, int hopCountMax=0, LookupListener *listener=NULL)
 Lookup a neighborhood or a key.
const NodeVectorgetResult () const
 Returns the result of the lookup.
bool isValid () const
 Returns true, if the lookup was successful.
uint getAccumulatedHops () const
 Returns the total number of hops for all lookup paths.

Protected Types

typedef hash_map< TransportAddress,
RpcInfoVector, TransportAddress::hashFcn
RpcInfoMap

Protected Member Functions

virtual BasePathLookupcreatePathLookup ()
 This method creates a new path lookup.
virtual FindNodeCallcreateInitialRpcCall ()
 This method creates the initial FindNode RPC call message used to query the local findNode() method.
int compare (const OverlayKey &lhs, const OverlayKey &rhs) const
bool addNeighbor (const NodeHandle &handle)
void setVisited (const TransportAddress &addr, bool visited=true)
bool getVisited (const TransportAddress &addr)
void handleRpcResponse (BaseResponseMessage *msg, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.
void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, int rpcId)
 This method is called if an RPC timeout has been reached.
void sendRpc (const NodeHandle &handle, FindNodeCall *call, BasePathLookup *listener, int rpcId)
void start ()
void stop ()
void checkStop ()

Protected Attributes

OverlayKey key
 key to lookup
BaseOverlayoverlay
 ptr to overlay
BaseLookupConfiguration config
 lookup configuration
cObject * firstCallExt
 additional info for first findNode()
LookupListenerlistener
 lookup listener
vector< BasePathLookup * > paths
 parallel paths
bool finished
 true, if lookup is finished
bool success
 true, if lookup was successful
bool running
 true, if lookup is running
uint finishedPaths
 number of finished paths
uint successfulPaths
 number of successful paths
uint accumulatedHops
 total number of hops (for all paths)
NodeVector neighbors
 closest nodes
TransportAddress::Set visited
 nodes already visited
int numNeighbors
 number of neighbors
int hopCountMax
 maximum hop count
RpcInfoMap rpcs

Friends

class BasePathLookup
class BaseOverlay

Classes

class  RpcInfo
class  RpcInfoVector


Member Typedef Documentation

typedef hash_map<TransportAddress, RpcInfoVector, TransportAddress::hashFcn> BaseLookup::RpcInfoMap [protected]


Constructor & Destructor Documentation

BaseLookup::BaseLookup ( BaseOverlay overlay,
const BaseLookupConfiguration config,
const cObject *  findNodeExt = NULL 
)

00046                                     :
00047     overlay(overlay),
00048     config(config),
00049     firstCallExt(NULL),
00050     finished(false),
00051     success(false),
00052     running(false)
00053 {
00054     if (findNodeExt) firstCallExt = static_cast<cObject*>(findNodeExt->dup());
00055     if (config.secure)
00056         cout << "WARNING: Secure BaseLookup is still under development!!"
00057              << endl;
00058 }

BaseLookup::~BaseLookup (  )  [virtual]

00061 {
00062     stop();
00063     delete firstCallExt;
00064     overlay->removeLookup(this);
00065 }


Member Function Documentation

bool BaseLookup::addNeighbor ( const NodeHandle handle  )  [protected]

00233 {
00234     bool result = false;
00235 
00236     if (numNeighbors == 0) {
00237         if (handle.key == key) {
00238             neighbors.clear();
00239             neighbors.push_back( handle );
00240             result = true;
00241         }
00242     } else {
00243         if (config.parallelPaths==1) {
00244             result = true;
00245             if (!neighbors.isFull())
00246                 neighbors.push_back(handle);
00247         } else {
00248             result = this->neighbors.add(handle);
00249         }
00250     }
00251 
00252     return result;
00253 }

void BaseLookup::checkStop (  )  [inline, protected]

00187 {
00188     // check if there are rpcs pending or lookup finished
00189     if ( (successfulPaths >=1 && numNeighbors == 0) ||
00190             (finishedPaths ==
00191              (uint)config.parallelPaths && numNeighbors > 0) ) {
00192 
00193         for (uint i=0; i<paths.size();i++)
00194             success |= paths[i]->success;
00195         delete this;
00196 
00197     } else if (rpcs.size() == 0)
00198         delete this;
00199 
00200 }

int BaseLookup::compare ( const OverlayKey lhs,
const OverlayKey rhs 
) const [protected, virtual]

Reimplemented from Comparator< OverlayKey >.

00223 {
00224     return overlay->distance( key, lhs ).compareTo( overlay->distance(key,
00225                                                                       rhs));
00226 }

FindNodeCall * BaseLookup::createInitialRpcCall (  )  [protected, virtual]

This method creates the initial FindNode RPC call message used to query the local findNode() method.

It may be overridden to allow additional information being attached before the lookup procedure actually starts

Returns:
newly allocated FindNodeCall message
00211 {
00212     FindNodeCall* call = new FindNodeCall("FindNodeCall");
00213     if (firstCallExt)
00214         call->addObject(static_cast<cObject*>(firstCallExt->dup()));
00215     return call;
00216 }

BasePathLookup * BaseLookup::createPathLookup (  )  [protected, virtual]

This method creates a new path lookup.

It may be overloaded to enhance BasePathLookup with some new information/features.

Returns:
The new path lookup
00206 {
00207     return new BasePathLookup(this);
00208 }

uint BaseLookup::getAccumulatedHops (  )  const [virtual]

Returns the total number of hops for all lookup paths.

Returns:
The accumulated number of hops.

Implements AbstractLookup.

00464 {
00465     return accumulatedHops;
00466 }

const NodeVector & BaseLookup::getResult (  )  const [virtual]

Returns the result of the lookup.

Returns:
The result node vector.

Implements AbstractLookup.

00453 {
00454     // return neighbor vector
00455     return neighbors;
00456 }

bool BaseLookup::getVisited ( const TransportAddress addr  )  [protected]

00264 {
00265     return this->visited.count(addr) != 0;
00266 }

void BaseLookup::handleRpcResponse ( BaseResponseMessage msg,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

This method is called if an RPC response has been received.

Parameters:
msg The response message.
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

00274 {
00275     // check flags
00276     if (finished || !running)
00277         return;
00278 
00279     // get source, cast messages and mark node as visited
00280     const TransportAddress& src = *(static_cast<const TransportAddress*>(
00281                 &(msg->getSrcNode())));
00282     FindNodeResponse* findNodeResponse = dynamic_cast<FindNodeResponse*>(msg);
00283     PingResponse* pingResponse = dynamic_cast<PingResponse*>(msg);
00284     FailedNodeResponse* failedNodeResponse =
00285         dynamic_cast<FailedNodeResponse*>(msg);
00286 
00287     setVisited( src );
00288 
00289     if ( findNodeResponse != NULL || pingResponse != NULL) {
00290         // add authentificated neighbor
00291         // addNeighbor( src );
00292     }
00293 
00294     // handle find node response
00295     if ( findNodeResponse != NULL ) {
00296 
00297         // check if rpc info is available, no -> exit
00298         if (rpcs.count(src)==0)
00299             return;
00300 
00301         // get info
00302         RpcInfoVector infos = rpcs[src];
00303         rpcs.erase(src);
00304 
00305         // add to neighborlist if not secure
00306   //      if (!config.secure)
00307   //          for (uint i=0; i<findNodeResponse->getClosestNodesArraySize(); i++)
00308   //              addNeighbor( findNodeResponse->getClosestNodes(i) );
00309 
00310         // iterate
00311         bool rpcHandled = false;
00312         for (uint i=0; i<infos.size(); i++) {
00313 
00314             // get info
00315             const RpcInfo& info = infos[i];
00316 
00317             // do not handle finished paths
00318             if (info.path->finished)
00319                 continue;
00320 
00321             // check if path accepts the message
00322             if ( !rpcHandled && info.path->accepts( info.vrpcId ) ) {
00323                 info.path->handleResponse( findNodeResponse );
00324                 rpcHandled = true;
00325             } else {
00326                 info.path->handleTimeout( NULL,
00327                         TransportAddress::UNSPECIFIED_NODE, info.vrpcId );
00328             }
00329 
00330             // count finished and successful paths
00331             if (info.path->finished) {
00332                 finishedPaths++;
00333 
00334                 // count total number of hops
00335                 accumulatedHops += info.path->hops;
00336 
00337                 if (info.path->success)
00338                     successfulPaths++;
00339             }
00340 
00341         }
00342     }
00343 
00344     // handle failed node response
00345     if ( failedNodeResponse != NULL ) {
00346         cMessage* findNodeExt = NULL;
00347         if (failedNodeResponse->hasObject("findNodeExt")) {
00348             findNodeExt =
00349                 (cMessage*)failedNodeResponse->removeObject("findNodeExt");
00350         }
00351         for (std::vector<BasePathLookup*>::iterator i = paths.begin();
00352                 i != paths.end(); i++)
00353             (*i)->handleFailedNodeResponse( failedNodeResponse->getSrcNode(),
00354                     findNodeExt, failedNodeResponse->getTryAgain() );
00355     }
00356 
00357     checkStop();
00358 }

void BaseLookup::handleRpcTimeout ( BaseCallMessage msg,
const TransportAddress dest,
int  rpcId 
) [protected, virtual]

This method is called if an RPC timeout has been reached.

Parameters:
msg The original RPC message.
dest The destination node
rpcId The RPC id.

Reimplemented from RpcListener.

00363 {
00364     // check flags
00365     if (finished || !running)
00366         return;
00367 
00368     // check if rpc info is available
00369     const TransportAddress& src = dest;
00370     if (rpcs.count(src)==0)
00371         return;
00372     RpcInfoVector& infos = rpcs[src];
00373 
00374     // iterate
00375     for (uint i=0; i < infos.size(); i++) {
00376 
00377         const RpcInfo& info = infos[i];
00378 
00379         // do not handle finished paths
00380         if (info.path->finished)
00381             continue;
00382 
00383         // delegate timeout
00384         info.path->handleTimeout( msg, dest, info.vrpcId );
00385 
00386         // count total number of hops
00387         accumulatedHops += info.path->hops;
00388 
00389         // count finished and successful paths
00390         if (info.path->finished) {
00391             finishedPaths++;
00392             if (info.path->success)
00393                 successfulPaths++;
00394         }
00395     }
00396 
00397     checkStop();
00398 }

bool BaseLookup::isValid (  )  const [virtual]

Returns true, if the lookup was successful.

Returns:
true, if the lookup was successful.

Implements AbstractLookup.

00459 {
00460     return success && finished;
00461 }

void BaseLookup::lookup ( const OverlayKey key,
uint  numNeighbors = 0,
int  hopCountMax = 0,
LookupListener listener = NULL 
) [virtual]

Lookup a neighborhood or a key.

Parameters:
key The key to lookup
numNeighbors Number of Neighbors to lookup
hopCountMax Maximum hop count
listener Listener to inform, when the lookup is done

Implements AbstractLookup.

00437 {
00438     // check flags
00439     if (finished || running)
00440         return;
00441 
00442     // set params
00443     this->key = key;
00444     this->numNeighbors = numNeighbors;
00445     this->hopCountMax = hopCountMax;
00446     this->listener = listener;
00447 
00448     // start lookup
00449     start();
00450 }

void BaseLookup::sendRpc ( const NodeHandle handle,
FindNodeCall call,
BasePathLookup listener,
int  rpcId 
) [protected]

00402 {
00403     // check flags
00404     if (finished || !running)
00405         return;
00406 
00407     // create rpc info
00408     RpcInfo info;
00409     info.path = listener;
00410     info.vrpcId = rpcId;
00411 
00412     // send new message
00413     if ( rpcs.count(handle)==0 ) {
00414         RpcInfoVector newVector = RpcInfoVector();
00415         rpcs[handle] = newVector;
00416 
00417         if (overlay->measureNetwInitPhase ||
00418             !overlay->underlayConfigurator->isInit()) {
00419 
00420             overlay->numFindNodeSent++;
00421             overlay->bytesFindNodeSent += call->byteLength();
00422         }
00423 
00424         newVector.nonce = overlay->sendRpcMessage( handle, call, this );
00425     }
00426 
00427     // register info
00428     rpcs[handle].push_back(info);
00429 }

void BaseLookup::setVisited ( const TransportAddress addr,
bool  visited = true 
) [protected]

00256 {
00257     if (visited)
00258         this->visited.insert( addr );
00259     else
00260         this->visited.erase( addr );
00261 }

void BaseLookup::start (  )  [protected]

00068 {
00069     // init params
00070     this->successfulPaths = 0;
00071     this->finishedPaths   = 0;
00072     this->accumulatedHops = 0;
00073 
00074     // init flags
00075     this->finished = false;
00076     this->success  = false;
00077     this->running  = true;
00078 
00079     // init neighborhood vector
00080     neighbors = NodeVector( numNeighbors == 0 ? 1 : numNeighbors, this );
00081 
00082     // get local closest nodes
00083     FindNodeCall* call = createInitialRpcCall();
00084     NodeVector* nextHops = overlay->findNode(key, call);
00085 
00086     // if this node is new and no nodes are known -> stop lookup
00087     if (nextHops->size() == 0) {
00088         stop();
00089         delete nextHops;
00090         delete call;
00091         return;
00092     }
00093 
00094     // Finish lookup if the key is local
00095     if ((numNeighbors != 0) && overlay->isResponsible(key)) {
00096         for (int i=0; i<nextHops->size(); i++) {
00097             addNeighbor((*nextHops)[i]);
00098         }
00099 
00100         success = true;
00101         finished = true;
00102     } else if ((nextHops->find(key).isUnspecified() == false)
00103         && !config.secure ) {
00104         // node is one of our neighbors
00105         
00106         addNeighbor(nextHops->find(key));
00107         
00108         // TODO: definition of hop count for iterative lookups is unclear
00109         // add one hop if destination node is our neighbor
00110         if (key != overlay->getThisNode().key)
00111             accumulatedHops++;
00112         
00113         success = true;
00114         finished = true;
00115     }
00116 
00117     // if the key was local or belongs to one of our neighbors we are finished
00118     if (finished) {
00119         // UGLY - calls stop and finishs the lookup
00120         delete nextHops;
00121         delete call;
00122         delete this;
00123         return;
00124     }   
00125 
00126 
00127     // remove find node extensions
00128     cMessage* findNodeExt = NULL;
00129     if (call->hasObject("findNodeExt"))
00130         findNodeExt = (cMessage*)call->removeObject("findNodeExt");
00131     delete call;
00132 
00133     // distribution of nodes to paths
00134     uint n = nextHops->size() / config.parallelPaths;
00135 
00136     // not enough nodes for all paths? -> reduce number of parallel paths
00137     if ( n == 0 ) {
00138         config.parallelPaths = nextHops->size();
00139         n = 1;
00140     }
00141 
00142     // create parallel paths
00143     int j=0;
00144     for (int i=0; i<config.parallelPaths; i++) {
00145 
00146         // create state
00147         BasePathLookup* pathLookup = new BasePathLookup( this );
00148         paths.push_back( pathLookup );
00149 
00150         // populate next hops
00151         for ( uint k=0; k<n; k++, j++ )
00152             pathLookup->add( (*nextHops)[j] );
00153 
00154         // send initial rpcs
00155         pathLookup->sendRpc( config.parallelRpcs, findNodeExt );
00156     }
00157     delete nextHops;
00158     delete findNodeExt;
00159 }

void BaseLookup::stop (  )  [protected]

00162 {
00163     // only stop if running
00164     if (!running)
00165         return;
00166 
00167     // cancel pending rpcs
00168     for (RpcInfoMap::iterator i = rpcs.begin(); i != rpcs.end(); i++)
00169         overlay->cancelRpcMessage( i->second.nonce );
00170     rpcs.clear();
00171 
00172     // delete path lookups
00173     for (uint i=0; i<paths.size(); i++)
00174         delete paths[i];
00175     paths.clear();
00176 
00177     // reset running flag
00178     running  = false;
00179     finished = true;
00180 
00181     // inform listener
00182     if ( listener != NULL )
00183         listener->lookupFinished(this);
00184 }


Friends And Related Function Documentation

friend class BaseOverlay [friend]

Reimplemented from RpcListener.

friend class BasePathLookup [friend]


Member Data Documentation

uint BaseLookup::accumulatedHops [protected]

total number of hops (for all paths)

BaseLookupConfiguration BaseLookup::config [protected]

lookup configuration

bool BaseLookup::finished [protected]

true, if lookup is finished

uint BaseLookup::finishedPaths [protected]

number of finished paths

cObject* BaseLookup::firstCallExt [protected]

additional info for first findNode()

int BaseLookup::hopCountMax [protected]

maximum hop count

OverlayKey BaseLookup::key [protected]

key to lookup

LookupListener* BaseLookup::listener [protected]

lookup listener

NodeVector BaseLookup::neighbors [protected]

closest nodes

int BaseLookup::numNeighbors [protected]

number of neighbors

BaseOverlay* BaseLookup::overlay [protected]

ptr to overlay

vector<BasePathLookup*> BaseLookup::paths [protected]

parallel paths

RpcInfoMap BaseLookup::rpcs [protected]

bool BaseLookup::running [protected]

true, if lookup is running

bool BaseLookup::success [protected]

true, if lookup was successful

uint BaseLookup::successfulPaths [protected]

number of successful paths

TransportAddress::Set BaseLookup::visited [protected]

nodes already visited


The documentation for this class was generated from the following files:
Generated on Fri May 11 14:52:39 2007 for ITM OverSim by  doxygen 1.4.7