#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, int retries=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. | |
void | abortLookup () |
Aborts a running lookup. | |
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, const OverlayKey &destKey) |
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 | |
int | retries |
number of retries, if lookup fails | |
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.
00265 { 00266 return new BasePathLookup(this); 00267 }
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
00270 { 00271 FindNodeCall* call = new FindNodeCall("FindNodeCall"); 00272 if (firstCallExt) 00273 call->addObject(static_cast<cObject*>(firstCallExt->dup())); 00274 return call; 00275 }
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 >.
00282 { 00283 return overlay->distance( key, lhs ).compareTo( overlay->distance(key, 00284 rhs)); 00285 }
bool BaseLookup::addSibling | ( | const NodeHandle & | handle | ) | [protected] |
adds a node to the siblings NodeVector
handle | NodeHandle of the node to add |
00292 { 00293 bool result = false; 00294 00295 if (numSiblings == 0) { 00296 if (handle.key == key) { 00297 siblings.clear(); 00298 siblings.push_back( handle ); 00299 result = true; 00300 } 00301 } else { 00302 if (config.parallelPaths==1) { 00303 result = true; 00304 if (!siblings.isFull()) 00305 siblings.push_back(handle); 00306 } else { 00307 result = this->siblings.add(handle); 00308 } 00309 } 00310 00311 return result; 00312 }
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 |
00315 { 00316 if (visited) 00317 this->visited.insert( addr ); 00318 else 00319 this->visited.erase( addr ); 00320 }
bool BaseLookup::getVisited | ( | const TransportAddress & | addr | ) | [protected] |
indicates if the specified node has been visited before
addr | TransportAddress of the node |
00323 { 00324 return this->visited.count(addr) != 0; 00325 }
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.
00333 { 00334 // check flags 00335 if (finished || !running) 00336 return; 00337 00338 // get source, cast messages and mark node as visited 00339 const TransportAddress& src = *(static_cast<const TransportAddress*>( 00340 &(msg->getSrcNode()))); 00341 FindNodeResponse* findNodeResponse = dynamic_cast<FindNodeResponse*>(msg); 00342 PingResponse* pingResponse = dynamic_cast<PingResponse*>(msg); 00343 FailedNodeResponse* failedNodeResponse = 00344 dynamic_cast<FailedNodeResponse*>(msg); 00345 00346 setVisited( src ); 00347 00348 if ( findNodeResponse != NULL || pingResponse != NULL) { 00349 // add authentificated sibling 00350 // addSibling( src ); 00351 } 00352 00353 // handle find node response 00354 if ( findNodeResponse != NULL ) { 00355 // std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " this: " << this << " received rpc with nonce: " << findNodeResponse->getNonce() << " from: " << findNodeResponse->getSrcNode() << endl; 00356 00357 // check if rpc info is available, no -> exit 00358 if (rpcs.count(src)==0) 00359 return; 00360 00361 // get info 00362 RpcInfoVector infos = rpcs[src]; 00363 rpcs.erase(src); 00364 00365 // add to siblinglist if not secure 00366 // if (!config.secure) 00367 // for (uint i=0; i<findNodeResponse->getClosestNodesArraySize(); i++) 00368 // addSibling( findNodeResponse->getClosestNodes(i) ); 00369 00370 // iterate 00371 bool rpcHandled = false; 00372 for (uint i=0; i<infos.size(); i++) { 00373 00374 // get info 00375 const RpcInfo& info = infos[i]; 00376 00377 // do not handle finished paths 00378 if (info.path->finished) 00379 continue; 00380 00381 // check if path accepts the message 00382 if ( !rpcHandled && info.path->accepts( info.vrpcId ) ) { 00383 info.path->handleResponse( findNodeResponse ); 00384 rpcHandled = true; 00385 } else { 00386 info.path->handleTimeout( NULL, 00387 findNodeResponse->getSrcNode(), info.vrpcId ); 00388 } 00389 00390 // count finished and successful paths 00391 if (info.path->finished) { 00392 finishedPaths++; 00393 00394 // count total number of hops 00395 accumulatedHops += info.path->hops; 00396 00397 if (info.path->success) 00398 successfulPaths++; 00399 } 00400 00401 } 00402 } 00403 00404 00405 // handle failed node response 00406 if ( failedNodeResponse != NULL ) { 00407 cMessage* findNodeExt = NULL; 00408 if (failedNodeResponse->hasObject("findNodeExt")) { 00409 findNodeExt = 00410 (cMessage*)failedNodeResponse->removeObject("findNodeExt"); 00411 } 00412 for (std::vector<BasePathLookup*>::iterator i = paths.begin(); 00413 i != paths.end(); i++) 00414 (*i)->handleFailedNodeResponse( 00415 failedNodeResponse->getSrcNode(), 00416 findNodeExt, failedNodeResponse->getTryAgain() 00417 ); 00418 } 00419 00420 checkStop(); 00421 }
void BaseLookup::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId, | |||
const OverlayKey & | destKey | |||
) | [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. | |
destKey | the destination OverlayKey |
Reimplemented from RpcListener.
00427 { 00428 // check flags 00429 if (finished || !running) 00430 return; 00431 00432 // check if rpc info is available 00433 const TransportAddress& src = dest; 00434 if (rpcs.count(src)==0) { 00435 cout << "BaseLookup::handleRpcTimeout(): RPC Timeout, but node" 00436 << " is not in rpcs structure!" << endl; 00437 return; 00438 } 00439 00440 RpcInfoVector infos = rpcs[src]; 00441 rpcs.erase(src); // ib 00442 00443 // iterate 00444 for (uint i=0; i < infos.size(); i++) { 00445 00446 const RpcInfo& info = infos[i]; 00447 00448 // do not handle finished paths 00449 if (info.path->finished) 00450 continue; 00451 00452 // delegate timeout 00453 info.path->handleTimeout( msg, dest, info.vrpcId ); 00454 00455 // count total number of hops 00456 accumulatedHops += info.path->hops; 00457 00458 // count finished and successful paths 00459 if (info.path->finished) { 00460 finishedPaths++; 00461 if (info.path->success) 00462 successfulPaths++; 00463 } 00464 } 00465 00466 checkStop(); 00467 }
void BaseLookup::sendRpc | ( | const NodeHandle & | handle, | |
FindNodeCall * | call, | |||
BasePathLookup * | listener, | |||
int | rpcId | |||
) | [protected] |
00471 { 00472 // check flags 00473 if (finished || !running) { 00474 delete call; 00475 return; 00476 } 00477 00478 // create rpc info 00479 RpcInfo info; 00480 info.path = listener; 00481 info.vrpcId = rpcId; 00482 00483 // send new message 00484 if ( rpcs.count(handle) == 0 ) { 00485 RpcInfoVector newVector; 00486 00487 if (overlay->measureNetwInitPhase || 00488 !overlay->underlayConfigurator->isInit()) { 00489 00490 overlay->numFindNodeSent++; 00491 overlay->bytesFindNodeSent += call->byteLength(); 00492 } 00493 00494 newVector.nonce = overlay->sendRpcMessage( handle, call, this ); 00495 00496 // std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " new rpc with nonce: " << newVector.nonce << " to: " << handle << endl; 00497 rpcs[handle] = newVector; 00498 // setVisited(handle); // TODO ib 00499 } else { 00500 opp_error("BaseLookup::sendRpc(): RPC already sent..."); 00501 delete call; 00502 } 00503 00504 // register info 00505 rpcs[handle].push_back(info); 00506 }
void BaseLookup::start | ( | ) | [protected] |
00079 { 00080 // std::cout << "time: " << simulation.simTime() << " start(): node: " << overlay->thisNode << " this: " << this << " key: " << key << endl; 00081 00082 // init params 00083 this->successfulPaths = 0; 00084 this->finishedPaths = 0; 00085 this->accumulatedHops = 0; 00086 00087 // init flags 00088 this->finished = false; 00089 this->success = false; 00090 this->running = true; 00091 00092 // init siblings vector 00093 siblings = NodeVector( numSiblings == 0 ? 1 : numSiblings, this ); 00094 visited.clear(); 00095 00096 // get local closest nodes 00097 FindNodeCall* call = createInitialRpcCall(); 00098 NodeVector* nextHops = overlay->findNode(key, config.redundantNodes, 00099 numSiblings, call); 00100 bool err; 00101 00102 setVisited(overlay->getThisNode()); 00103 00104 // if this node is new and no nodes are known -> stop lookup 00105 if (nextHops->size() == 0) { 00106 // std::cout << "BaseLookup: No next hops known" << endl; 00107 finished = true; 00108 success = false; 00109 } else if ((numSiblings == 0) && 00110 overlay->isSiblingFor(overlay->thisNode, key, numSiblings, &err)) { 00111 00112 if (overlay->getThisNode().key == key) { 00113 addSibling( overlay->getThisNode() ); 00114 success = true; 00115 } else { 00116 std::cout << "BaseLookup: numSiblings==0 and no node with this id" 00117 << endl; 00118 success = false; 00119 } 00120 finished = true; 00121 } 00122 // finish lookup if the key is local and siblings are needed 00123 else if ( numSiblings != 0 && 00124 overlay->isSiblingFor(overlay->thisNode, key, numSiblings, &err) 00125 && !config.secure) { 00126 00127 for (uint i=0; i<nextHops->size(); i++) { 00128 addSibling( nextHops->at(i) ); 00129 } 00130 00131 // TODO: definition of hop count for iterative lookups is unclear 00132 // add one hop if destination node is our sibling 00133 if ( key != overlay->getThisNode().key ) { 00134 accumulatedHops++; 00135 } 00136 00137 success = finished = true; 00138 00139 } 00140 /* 00141 // check if the node is found locally 00142 else if ( nextHops->contains(key) && !config.secure ) { 00143 00144 // node is one of our siblings 00145 addSibling( nextHops->find( key ) ); 00146 00147 // TODO: definition of hop count for iterative lookups is unclear 00148 // add one hop if destination node is our sibling 00149 if ( key != overlay->getThisNode().key ) 00150 accumulatedHops++; 00151 00152 success = true; 00153 finished = true; 00154 } 00155 */ 00156 00157 // if the key was local or belongs to one of our siblings we are finished 00158 if (finished) { 00159 // UGLY - calls stop and finishs the lookup 00160 delete nextHops; 00161 delete call; 00162 delete this; 00163 return; 00164 } 00165 00166 00167 // remove find node extensions 00168 cMessage* findNodeExt = NULL; 00169 if (call->hasObject("findNodeExt")) 00170 findNodeExt = (cMessage*)call->removeObject("findNodeExt"); 00171 delete call; 00172 00173 // distribution of nodes to paths 00174 uint n = nextHops->size() / config.parallelPaths; 00175 00176 // not enough nodes for all paths? -> reduce number of parallel paths 00177 if ( n == 0 ) { 00178 config.parallelPaths = nextHops->size(); 00179 n = 1; 00180 } 00181 00182 // create parallel paths 00183 int j=0; 00184 for (int i=0; i<config.parallelPaths; i++) { 00185 00186 // create state 00187 BasePathLookup* pathLookup = new BasePathLookup( this ); 00188 paths.push_back( pathLookup ); 00189 00190 // populate next hops 00191 for ( uint k=0; k<n; k++, j++ ) 00192 pathLookup->add( nextHops->at(j) ); 00193 00194 // send initial rpcs 00195 pathLookup->sendRpc( config.parallelRpcs, findNodeExt ); 00196 } 00197 delete nextHops; 00198 delete findNodeExt; 00199 }
void BaseLookup::stop | ( | ) | [protected] |
00202 { 00203 // only stop if running 00204 if (!running) 00205 return; 00206 00207 // cancel pending rpcs 00208 for (RpcInfoMap::iterator i = rpcs.begin(); i != rpcs.end(); i++) { 00209 // std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " this: " << this << " first: " << i->first << " nonce: " << i->second.nonce << endl; 00210 overlay->cancelRpcMessage( i->second.nonce ); 00211 } 00212 rpcs.clear(); 00213 00214 // delete path lookups 00215 for (uint i=0; i<paths.size(); i++) 00216 delete paths[i]; 00217 paths.clear(); 00218 00219 // reset running flag 00220 running = false; 00221 finished = true; 00222 00223 // inform listener 00224 if ( listener != NULL ) { 00225 listener->lookupFinished(this); 00226 listener = NULL; 00227 } 00228 }
void BaseLookup::checkStop | ( | ) | [inline, protected] |
00231 { 00232 bool finishLookup = false; 00233 00234 // check if there are rpcs pending or lookup finished 00235 if ( (successfulPaths >=1 && numSiblings == 0) || 00236 (finishedPaths == 00237 (uint)config.parallelPaths && numSiblings > 0) ) { 00238 00239 for (uint i=0; i<paths.size(); i++) 00240 success |= paths[i]->success; 00241 finishLookup = true; 00242 } else if (rpcs.size() == 0) { 00243 finishLookup = true; 00244 } 00245 00246 if (finishLookup == true) { 00247 if (success == false && retries > 0) { 00248 // std::cout << "BaseLookup::checkStop(): Retry..." << endl; 00249 retries--; 00250 LookupListener* oldListener = listener; 00251 listener = NULL; 00252 stop(); 00253 listener = oldListener; 00254 start(); 00255 } else { 00256 delete this; 00257 } 00258 } 00259 }
void BaseLookup::lookup | ( | const OverlayKey & | key, | |
int | numSiblings = 1 , |
|||
int | hopCountMax = 0 , |
|||
int | retries = 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 | |
retries | Number of retries if lookup fails | |
listener | Listener to inform, when the lookup is done |
Implements AbstractLookup.
00514 { 00515 // check flags 00516 if (finished || running) 00517 return; 00518 00519 // set params 00520 this->key = key; 00521 this->numSiblings = numSiblings; 00522 this->hopCountMax = hopCountMax; 00523 this->listener = listener; 00524 this->retries = retries; 00525 00526 // start lookup 00527 start(); 00528 }
const NodeVector & BaseLookup::getResult | ( | ) | const [virtual] |
Returns the result of the lookup.
Implements AbstractLookup.
00531 { 00532 // return sibling vector 00533 return siblings; 00534 }
bool BaseLookup::isValid | ( | ) | const [virtual] |
Returns true, if the lookup was successful.
Implements AbstractLookup.
void BaseLookup::abortLookup | ( | ) | [virtual] |
Aborts a running lookup.
This method aborts a running lookup without calling the listener and delete the lookup object.
Implements AbstractLookup.
00070 { 00071 if (listener != NULL) { 00072 delete listener; 00073 listener = NULL; 00074 } 00075 delete this; 00076 }
uint BaseLookup::getAccumulatedHops | ( | ) | const [virtual] |
Returns the total number of hops for all lookup paths.
Implements AbstractLookup.
00542 { 00543 return accumulatedHops; 00544 }
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
int BaseLookup::retries [protected] |
number of retries, if lookup fails
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] |