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, int numSiblings=1, int hopCountMax=0, LookupListener *listener=NULL)
 Lookup siblings for 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 FindNodeCall * createInitialRpcCall ()
 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
 compares two OverlayKeys and indicates which one is closer to the key to look up
bool addSibling (const NodeHandle &handle)
 adds a node to the siblings NodeVector
void setVisited (const TransportAddress &addr, bool visited=true)
 adds/deletes visited nodes to/from the visited TransportAddress::Set
bool getVisited (const TransportAddress &addr)
 indicates if the specified node has been visited before
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 siblings
 closest nodes
TransportAddress::Set visited
 nodes already visited
int numSiblings
 number of siblings
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 
00066 //    std::cout << "time: " << simulation.simTime() << "deleting " << this << endl;
00067 }


Member Function Documentation

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
00238 {
00239     return new BasePathLookup(this);
00240 }

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
00243 {
00244     FindNodeCall* call = new FindNodeCall("FindNodeCall");
00245     if (firstCallExt)
00246         call->addObject(static_cast<cObject*>(firstCallExt->dup()));
00247     return call;
00248 }

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

compares two OverlayKeys and indicates which one is closer to the key to look up

Parameters:
lhs the first OverlayKey
rhs the second OverlayKey
Returns:
-1 if rhs is closer, 0 if lhs and rhs are equal and 1 if rhs is farther away to the key to lookup

Reimplemented from Comparator< OverlayKey >.

00255 { 
00256     return overlay->distance( key, lhs ).compareTo( overlay->distance(key,
00257                                                                       rhs));
00258 }

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

adds a node to the siblings NodeVector

Parameters:
handle NodeHandle of the node to add
Returns:
true if operation was succesfull, false otherwise
00265 {
00266     bool result = false;
00267 
00268     if (numSiblings == 0) {
00269         if (handle.key == key) {
00270             siblings.clear();
00271             siblings.push_back( handle );
00272             result = true;
00273         }
00274     } else {
00275         if (config.parallelPaths==1) {
00276             result = true;
00277             if (!siblings.isFull())
00278                 siblings.push_back(handle);
00279         } else {
00280             result = this->siblings.add(handle);
00281         }
00282     }
00283 
00284     return result;
00285 }

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

adds/deletes visited nodes to/from the visited TransportAddress::Set

Parameters:
addr TransportAddress of the node to add
visited if true node is addes, else node is erased
00288 {
00289     if (visited)
00290         this->visited.insert( addr );
00291     else
00292         this->visited.erase( addr );
00293 }

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

indicates if the specified node has been visited before

Parameters:
addr TransportAddress of the node
Returns:
false if addr is not in visited, true otherwise
00296 {
00297     return this->visited.count(addr) != 0;
00298 }

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.

00306 {
00307     // check flags
00308     if (finished || !running)
00309         return;
00310 
00311     // get source, cast messages and mark node as visited
00312     const TransportAddress& src = *(static_cast<const TransportAddress*>(
00313                                                                         &(msg->getSrcNode())));
00314     FindNodeResponse* findNodeResponse = dynamic_cast<FindNodeResponse*>(msg);
00315     PingResponse* pingResponse = dynamic_cast<PingResponse*>(msg);
00316     FailedNodeResponse* failedNodeResponse =
00317     dynamic_cast<FailedNodeResponse*>(msg);
00318 
00319     setVisited( src );
00320 
00321     if ( findNodeResponse != NULL || pingResponse != NULL) {
00322         // add authentificated sibling
00323         // addSibling( src );
00324     }
00325 
00326     // handle find node response
00327     if ( findNodeResponse != NULL ) {
00328 //      std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " this: " << this << " received rpc with nonce: " << findNodeResponse->getNonce() << " from: " << findNodeResponse->getSrcNode() << endl;
00329 
00330         // check if rpc info is available, no -> exit
00331         if (rpcs.count(src)==0)
00332             return;
00333 
00334         // get info
00335         RpcInfoVector infos = rpcs[src];
00336         rpcs.erase(src);
00337 
00338         // add to siblinglist if not secure
00339         //      if (!config.secure)
00340         //          for (uint i=0; i<findNodeResponse->getClosestNodesArraySize(); i++)
00341         //              addSibling( findNodeResponse->getClosestNodes(i) );
00342 
00343         // iterate
00344         bool rpcHandled = false;
00345         for (uint i=0; i<infos.size(); i++) {
00346 
00347             // get info
00348             const RpcInfo& info = infos[i];
00349 
00350             // do not handle finished paths
00351             if (info.path->finished)
00352                 continue;
00353 
00354             // check if path accepts the message
00355             if ( !rpcHandled && info.path->accepts( info.vrpcId ) ) {
00356                 info.path->handleResponse( findNodeResponse );
00357                 rpcHandled = true;
00358             } else {
00359                 info.path->handleTimeout( NULL,
00360                                           findNodeResponse->getSrcNode(), info.vrpcId );
00361             }
00362 
00363             // count finished and successful paths
00364             if (info.path->finished) {
00365                 finishedPaths++;
00366 
00367                 // count total number of hops
00368                 accumulatedHops += info.path->hops;
00369 
00370                 if (info.path->success)
00371                     successfulPaths++;
00372             }
00373 
00374         }
00375     }
00376 
00377 
00378     // handle failed node response
00379     if ( failedNodeResponse != NULL ) {
00380         cMessage* findNodeExt = NULL;
00381         if (failedNodeResponse->hasObject("findNodeExt")) {
00382             findNodeExt =
00383             (cMessage*)failedNodeResponse->removeObject("findNodeExt");
00384         }
00385         for (std::vector<BasePathLookup*>::iterator i = paths.begin();
00386             i != paths.end(); i++)
00387             (*i)->handleFailedNodeResponse( 
00388                 failedNodeResponse->getSrcNode(),
00389                 findNodeExt, failedNodeResponse->getTryAgain() 
00390             );
00391     }
00392 
00393     checkStop();
00394 }

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.

00399 {
00400     // check flags
00401     if (finished || !running)
00402         return;
00403 
00404     // check if rpc info is available
00405     const TransportAddress& src = dest;
00406     if (rpcs.count(src)==0)
00407         return;
00408     RpcInfoVector& infos = rpcs[src];
00409 
00410     // iterate
00411     for (uint i=0; i < infos.size(); i++) {
00412 
00413         const RpcInfo& info = infos[i];
00414 
00415         // do not handle finished paths
00416         if (info.path->finished)
00417             continue;
00418 
00419         // delegate timeout
00420         info.path->handleTimeout( msg, dest, info.vrpcId );
00421 
00422         // count total number of hops
00423         accumulatedHops += info.path->hops;
00424 
00425         // count finished and successful paths
00426         if (info.path->finished) {
00427             finishedPaths++;
00428             if (info.path->success)
00429                 successfulPaths++;
00430         }
00431     }
00432 
00433     checkStop();
00434 }

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

00438 {
00439     // check flags
00440     if (finished || !running) {
00441         delete call;
00442         return;
00443     }
00444 
00445     // create rpc info
00446     RpcInfo info;
00447     info.path = listener;
00448     info.vrpcId = rpcId;
00449 
00450     // send new message
00451     if ( rpcs.count(handle) == 0 ) {
00452         RpcInfoVector newVector;
00453 
00454         if (overlay->measureNetwInitPhase ||
00455             !overlay->underlayConfigurator->isInit()) {
00456 
00457             overlay->numFindNodeSent++;
00458             overlay->bytesFindNodeSent += call->byteLength();
00459         }
00460 
00461         newVector.nonce = overlay->sendRpcMessage( handle, call, this );
00462 
00463 //      std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " new rpc with nonce: " << newVector.nonce << " to: " << handle << endl;
00464         rpcs[handle] = newVector;
00465     } else {
00466         delete call;
00467     }
00468 
00469     // register info
00470     rpcs[handle].push_back(info);
00471 }

void BaseLookup::start (  )  [protected]

00070 {
00071 //    std::cout << "time: " << simulation.simTime() << " start(): node: " << overlay->thisNode << " this: " << this  << " key: " << key << endl;
00072 
00073     // init params
00074     this->successfulPaths = 0;
00075     this->finishedPaths   = 0;
00076     this->accumulatedHops = 0;
00077 
00078     // init flags
00079     this->finished = false;
00080     this->success  = false;
00081     this->running  = true;
00082 
00083     // init siblings vector
00084     siblings = NodeVector( numSiblings == 0 ? 1 : numSiblings, this );
00085 
00086     // get local closest nodes
00087     FindNodeCall* call = createInitialRpcCall();
00088     NodeVector* nextHops = overlay->findNode(key, config.redundantNodes,
00089                                              numSiblings, call);
00090 
00091     // if this node is new and no nodes are known -> stop lookup
00092     if (nextHops->size() == 0) {
00093         stop();
00094         delete nextHops;
00095         delete call;
00096         return;
00097     }
00098 
00099     setVisited(overlay->getThisNode());
00100 
00101     bool err;
00102 
00103     if ((numSiblings == 0) &&
00104         overlay->isSiblingFor(overlay->thisNode, key, numSiblings, &err)) {
00105         
00106         if (overlay->getThisNode().key == key) {
00107             addSibling( overlay->getThisNode() );
00108             success = true;
00109         } else {
00110             success = false;
00111         }
00112         finished = true;
00113     }
00114     // finish lookup if the key is local and siblings are needed
00115     else if ( numSiblings != 0 && 
00116               overlay->isSiblingFor(overlay->thisNode, key, numSiblings, &err)
00117               && !config.secure) {
00118         
00119         for (uint i=0; i<nextHops->size(); i++)
00120             addSibling( nextHops->at(i) );
00121 
00122         // TODO: definition of hop count for iterative lookups is unclear
00123         // add one hop if destination node is our sibling
00124         if ( key != overlay->getThisNode().key )
00125             accumulatedHops++;
00126 
00127         success = finished = true;
00128 
00129     } else
00130 /* 
00131         // check if the node is found locally
00132         if ( nextHops->contains(key) && !config.secure ) {
00133 
00134         // node is one of our siblings
00135         addSibling( nextHops->find( key ) );
00136 
00137         // TODO: definition of hop count for iterative lookups is unclear
00138         // add one hop if destination node is our sibling
00139         if ( key != overlay->getThisNode().key )
00140             accumulatedHops++;
00141 
00142         success = true;
00143         finished = true;
00144     }
00145 */
00146 
00147     // if the key was local or belongs to one of our siblings we are finished
00148     if (finished) {
00149         // UGLY - calls stop and finishs the lookup
00150         delete nextHops;
00151         delete call;
00152         delete this;
00153         return;
00154     }
00155 
00156 
00157     // remove find node extensions
00158     cMessage* findNodeExt = NULL;
00159     if (call->hasObject("findNodeExt"))
00160         findNodeExt = (cMessage*)call->removeObject("findNodeExt");
00161     delete call;
00162 
00163     // distribution of nodes to paths
00164     uint n = nextHops->size() / config.parallelPaths;
00165 
00166     // not enough nodes for all paths? -> reduce number of parallel paths
00167     if ( n == 0 ) {
00168         config.parallelPaths = nextHops->size();
00169         n = 1;
00170     }
00171 
00172     // create parallel paths
00173     int j=0;
00174     for (int i=0; i<config.parallelPaths; i++) {
00175 
00176         // create state
00177         BasePathLookup* pathLookup = new BasePathLookup( this );
00178         paths.push_back( pathLookup );
00179 
00180         // populate next hops
00181         for ( uint k=0; k<n; k++, j++ )
00182             pathLookup->add( nextHops->at(j) );
00183 
00184         // send initial rpcs
00185         pathLookup->sendRpc( config.parallelRpcs, findNodeExt );
00186     }
00187     delete nextHops;
00188     delete findNodeExt;
00189 }

void BaseLookup::stop (  )  [protected]

00192 {
00193     // only stop if running
00194     if (!running)
00195         return;
00196 
00197     // cancel pending rpcs
00198     for (RpcInfoMap::iterator i = rpcs.begin(); i != rpcs.end(); i++) {
00199 //      std::cout << "time: " << simulation.simTime()     << " node: " << overlay->thisNode       << " this: " << this << " first: " << i->first  << " nonce: " << i->second.nonce << endl;
00200         overlay->cancelRpcMessage( i->second.nonce );
00201     }
00202     rpcs.clear();
00203 
00204     // delete path lookups
00205     for (uint i=0; i<paths.size(); i++)
00206         delete paths[i];
00207     paths.clear();
00208 
00209     // reset running flag
00210     running  = false;
00211     finished = true;
00212 
00213     // inform listener
00214     if ( listener != NULL )
00215         listener->lookupFinished(this);
00216 }

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

00219 {
00220     // check if there are rpcs pending or lookup finished
00221     if ( (successfulPaths >=1 && numSiblings == 0) ||
00222          (finishedPaths ==
00223           (uint)config.parallelPaths && numSiblings > 0) ) {
00224 
00225         for (uint i=0; i<paths.size();i++)
00226             success |= paths[i]->success;
00227         delete this;
00228 
00229     } else if (rpcs.size() == 0)
00230         delete this;
00231 
00232 }

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

Lookup siblings for a key.

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

Implements AbstractLookup.

00479 {
00480     // check flags
00481     if (finished || running)
00482         return;
00483 
00484     // set params
00485     this->key = key;
00486     this->numSiblings = numSiblings;
00487     this->hopCountMax = hopCountMax;
00488     this->listener = listener;
00489 
00490     // start lookup
00491     start();
00492 }

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

Returns the result of the lookup.

Returns:
The result node vector.

Implements AbstractLookup.

00495 {
00496     // return sibling vector
00497     return siblings;
00498 }

bool BaseLookup::isValid (  )  const [virtual]

Returns true, if the lookup was successful.

Returns:
true, if the lookup was successful.

Implements AbstractLookup.

00501 {
00502     return success && finished;
00503 }

uint BaseLookup::getAccumulatedHops (  )  const [virtual]

Returns the total number of hops for all lookup paths.

Returns:
The accumulated number of hops.

Implements AbstractLookup.

00506 {
00507     return accumulatedHops;
00508 }


Friends And Related Function Documentation

friend class BasePathLookup [friend]

friend class BaseOverlay [friend]


Member Data Documentation

OverlayKey BaseLookup::key [protected]

key to lookup

BaseOverlay* BaseLookup::overlay [protected]

ptr to overlay

BaseLookupConfiguration BaseLookup::config [protected]

lookup configuration

cObject* BaseLookup::firstCallExt [protected]

additional info for first findNode()

LookupListener* BaseLookup::listener [protected]

lookup listener

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

parallel paths

bool BaseLookup::finished [protected]

true, if lookup is finished

bool BaseLookup::success [protected]

true, if lookup was successful

bool BaseLookup::running [protected]

true, if lookup is running

uint BaseLookup::finishedPaths [protected]

number of finished paths

uint BaseLookup::successfulPaths [protected]

number of successful paths

uint BaseLookup::accumulatedHops [protected]

total number of hops (for all paths)

NodeVector BaseLookup::siblings [protected]

closest nodes

TransportAddress::Set BaseLookup::visited [protected]

nodes already visited

int BaseLookup::numSiblings [protected]

number of siblings

int BaseLookup::hopCountMax [protected]

maximum hop count

RpcInfoMap BaseLookup::rpcs [protected]


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