#include <BaseLookup.h>
Inheritance diagram for BaseLookup:
It uses the standard metric for greedy behaviour. If another metric is needed, the distance function can be replaced by overriding the distance method.
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 NodeVector & | getResult () 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 BasePathLookup * | createPathLookup () |
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 |
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 | |
BaseOverlay * | overlay |
ptr to overlay | |
BaseLookupConfiguration | config |
lookup configuration | |
cObject * | firstCallExt |
additional info for first findNode() | |
LookupListener * | listener |
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 |
typedef hash_map<TransportAddress, RpcInfoVector, TransportAddress::hashFcn> BaseLookup::RpcInfoMap [protected] |
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] |
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] |
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
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.
00206 { 00207 return new BasePathLookup(this); 00208 }
uint BaseLookup::getAccumulatedHops | ( | ) | const [virtual] |
Returns the total number of hops for all lookup paths.
Implements AbstractLookup.
00464 { 00465 return accumulatedHops; 00466 }
const NodeVector & BaseLookup::getResult | ( | ) | const [virtual] |
Returns the result of the lookup.
Implements AbstractLookup.
00453 { 00454 // return neighbor vector 00455 return neighbors; 00456 }
bool BaseLookup::getVisited | ( | const TransportAddress & | addr | ) | [protected] |
void BaseLookup::handleRpcResponse | ( | BaseResponseMessage * | msg, | |
int | rpcId, | |||
simtime_t | rtt | |||
) | [protected, virtual] |
This method is called if an RPC response has been received.
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.
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.
Implements AbstractLookup.
void BaseLookup::lookup | ( | const OverlayKey & | key, | |
uint | numNeighbors = 0 , |
|||
int | hopCountMax = 0 , |
|||
LookupListener * | listener = NULL | |||
) | [virtual] |
Lookup a neighborhood or a key.
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 }
friend class BaseOverlay [friend] |
Reimplemented from RpcListener.
friend class BasePathLookup [friend] |
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