#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, int numSiblings=1, int hopCountMax=0, LookupListener *listener=NULL) |
Lookup siblings for 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 |
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 | |
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 | 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 |
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] |
00061 { 00062 stop(); 00063 delete firstCallExt; 00064 overlay->removeLookup(this); 00065 00066 // std::cout << "time: " << simulation.simTime() << "deleting " << this << endl; 00067 }
BasePathLookup * BaseLookup::createPathLookup | ( | ) | [protected, virtual] |
This method creates a new path lookup.
It may be overloaded to enhance BasePathLookup with some new information/features.
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
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
lhs | the first OverlayKey | |
rhs | the second OverlayKey |
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
handle | NodeHandle of the node to add |
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
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
addr | TransportAddress of the node |
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.
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.
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.
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.
Implements AbstractLookup.
00495 { 00496 // return sibling vector 00497 return siblings; 00498 }
bool BaseLookup::isValid | ( | ) | const [virtual] |
Returns true, if the lookup was successful.
Implements AbstractLookup.
uint BaseLookup::getAccumulatedHops | ( | ) | const [virtual] |
Returns the total number of hops for all lookup paths.
Implements AbstractLookup.
00506 { 00507 return accumulatedHops; 00508 }
friend class BasePathLookup [friend] |
friend class BaseOverlay [friend] |
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] |