#include <BaseLookup.h>
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=OverlayKey::UNSPECIFIED_KEY) |
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.
00263 { 00264 return new BasePathLookup(this); 00265 }
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
00268 { 00269 FindNodeCall* call = new FindNodeCall("FindNodeCall"); 00270 if (firstCallExt) 00271 call->addObject(static_cast<cObject*>(firstCallExt->dup())); 00272 return call; 00273 }
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 >.
00280 { 00281 return overlay->distance( key, lhs ).compareTo( overlay->distance(key, 00282 rhs)); 00283 }
bool BaseLookup::addSibling | ( | const NodeHandle & | handle | ) | [protected] |
adds a node to the siblings NodeVector
handle | NodeHandle of the node to add |
00290 { 00291 bool result = false; 00292 00293 if (numSiblings == 0) { 00294 if (handle.key == key) { 00295 siblings.clear(); 00296 siblings.push_back( handle ); 00297 result = true; 00298 } 00299 } else { 00300 if (config.parallelPaths==1) { 00301 result = true; 00302 if (!siblings.isFull()) { 00303 siblings.push_back(handle); 00304 } 00305 } else { 00306 result = this->siblings.add(handle); 00307 } 00308 } 00309 00310 return result; 00311 }
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 |
00314 { 00315 if (visited) 00316 this->visited.insert( addr ); 00317 else 00318 this->visited.erase( addr ); 00319 }
bool BaseLookup::getVisited | ( | const TransportAddress & | addr | ) | [protected] |
indicates if the specified node has been visited before
addr | TransportAddress of the node |
00322 { 00323 return this->visited.count(addr) != 0; 00324 }
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.
00332 { 00333 // check flags 00334 if (finished || !running) 00335 return; 00336 00337 // get source, cast messages and mark node as visited 00338 const TransportAddress& src = *(static_cast<const TransportAddress*>( 00339 &(msg->getSrcNode()))); 00340 FindNodeResponse* findNodeResponse = dynamic_cast<FindNodeResponse*>(msg); 00341 PingResponse* pingResponse = dynamic_cast<PingResponse*>(msg); 00342 FailedNodeResponse* failedNodeResponse = 00343 dynamic_cast<FailedNodeResponse*>(msg); 00344 00345 setVisited( src ); 00346 00347 if ( findNodeResponse != NULL || pingResponse != NULL) { 00348 // add authentificated sibling 00349 // addSibling( src ); 00350 } 00351 00352 // handle find node response 00353 if ( findNodeResponse != NULL ) { 00354 // std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " this: " << this << " received rpc with nonce: " << findNodeResponse->getNonce() << " from: " << findNodeResponse->getSrcNode() << endl; 00355 00356 // check if rpc info is available, no -> exit 00357 if (rpcs.count(src)==0) 00358 return; 00359 00360 // get info 00361 RpcInfoVector infos = rpcs[src]; 00362 rpcs.erase(src); 00363 00364 // add to siblinglist if not secure 00365 // if (!config.secure) 00366 // for (uint i=0; i<findNodeResponse->getClosestNodesArraySize(); i++) 00367 // addSibling( findNodeResponse->getClosestNodes(i) ); 00368 00369 // iterate 00370 bool rpcHandled = false; 00371 for (uint i=0; i<infos.size(); i++) { 00372 00373 // get info 00374 const RpcInfo& info = infos[i]; 00375 00376 // do not handle finished paths 00377 if (info.path->finished) 00378 continue; 00379 00380 // check if path accepts the message 00381 if ( !rpcHandled && info.path->accepts( info.vrpcId ) ) { 00382 info.path->handleResponse( findNodeResponse ); 00383 rpcHandled = true; 00384 } else { 00385 info.path->handleTimeout( NULL, 00386 findNodeResponse->getSrcNode(), info.vrpcId ); 00387 } 00388 00389 // count finished and successful paths 00390 if (info.path->finished) { 00391 finishedPaths++; 00392 00393 // count total number of hops 00394 accumulatedHops += info.path->hops; 00395 00396 if (info.path->success) 00397 successfulPaths++; 00398 } 00399 00400 } 00401 } 00402 00403 00404 // handle failed node response 00405 if ( failedNodeResponse != NULL ) { 00406 cMessage* findNodeExt = NULL; 00407 if (failedNodeResponse->hasObject("findNodeExt")) { 00408 findNodeExt = 00409 (cMessage*)failedNodeResponse->removeObject("findNodeExt"); 00410 } 00411 for (std::vector<BasePathLookup*>::iterator i = paths.begin(); 00412 i != paths.end(); i++) 00413 (*i)->handleFailedNodeResponse( 00414 failedNodeResponse->getSrcNode(), 00415 findNodeExt, failedNodeResponse->getTryAgain() 00416 ); 00417 } 00418 00419 checkStop(); 00420 }
void BaseLookup::handleRpcTimeout | ( | BaseCallMessage * | msg, | |
const TransportAddress & | dest, | |||
int | rpcId, | |||
const OverlayKey & | destKey = OverlayKey::UNSPECIFIED_KEY | |||
) | [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.
00426 { 00427 // check flags 00428 if (finished || !running) 00429 return; 00430 00431 // check if rpc info is available 00432 const TransportAddress& src = dest; 00433 if (rpcs.count(src)==0) { 00434 cout << "BaseLookup::handleRpcTimeout(): RPC Timeout, but node" 00435 << " is not in rpcs structure!" << endl; 00436 return; 00437 } 00438 00439 RpcInfoVector infos = rpcs[src]; 00440 rpcs.erase(src); // ib 00441 00442 // iterate 00443 for (uint i=0; i < infos.size(); i++) { 00444 00445 const RpcInfo& info = infos[i]; 00446 00447 // do not handle finished paths 00448 if (info.path->finished) 00449 continue; 00450 00451 // delegate timeout 00452 info.path->handleTimeout( msg, dest, info.vrpcId ); 00453 00454 // count total number of hops 00455 accumulatedHops += info.path->hops; 00456 00457 // count finished and successful paths 00458 if (info.path->finished) { 00459 finishedPaths++; 00460 if (info.path->success) 00461 successfulPaths++; 00462 } 00463 } 00464 checkStop(); 00465 }
void BaseLookup::sendRpc | ( | const NodeHandle & | handle, | |
FindNodeCall * | call, | |||
BasePathLookup * | listener, | |||
int | rpcId | |||
) | [protected] |
00469 { 00470 // check flags 00471 if (finished || !running) { 00472 delete call; 00473 return; 00474 } 00475 00476 // create rpc info 00477 RpcInfo info; 00478 info.path = listener; 00479 info.vrpcId = rpcId; 00480 00481 // send new message 00482 if ( rpcs.count(handle) == 0 ) { 00483 RpcInfoVector newVector; 00484 00485 if (overlay->measureNetwInitPhase || 00486 !overlay->underlayConfigurator->isInit()) { 00487 00488 overlay->numFindNodeSent++; 00489 overlay->bytesFindNodeSent += call->byteLength(); 00490 } 00491 00492 newVector.nonce = overlay->sendUdpRpcCall(handle, call, -1, 0, -1, 00493 this); 00494 00495 // std::cout << "time: " << simulation.simTime() << " node: " << overlay->thisNode << " new rpc with nonce: " << newVector.nonce << " to: " << handle << endl; 00496 rpcs[handle] = newVector; 00497 // setVisited(handle); // TODO ib 00498 } else { 00499 opp_error("BaseLookup::sendRpc(): RPC already sent..."); 00500 delete call; 00501 } 00502 00503 // register info 00504 rpcs[handle].push_back(info); 00505 }
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) && overlay->isSiblingFor(overlay->thisNode, 00110 key, numSiblings, 00111 &err)) { 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 == (uint)config.parallelPaths && numSiblings > 0)) { 00237 for (uint i=0; i<paths.size(); i++) 00238 success |= paths[i]->success; 00239 finishLookup = true; 00240 } else if (rpcs.size() == 0) { 00241 finishLookup = true; 00242 } 00243 00244 if (finishLookup == true) { 00245 if (success == false && retries > 0) { 00246 // std::cout << "BaseLookup::checkStop(): Retry..." << endl; 00247 retries--; 00248 LookupListener* oldListener = listener; 00249 listener = NULL; 00250 stop(); 00251 listener = oldListener; 00252 start(); 00253 } else { 00254 delete this; 00255 } 00256 } 00257 }
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.
00513 { 00514 EV << "[BaseLookup::lookup() @ " << overlay->thisNode.ip 00515 << " (" << overlay->thisNode.key.toString(16) << ")]\n" 00516 << " Lookup of key " << key 00517 << endl; 00518 00519 // check flags 00520 if (finished || running) 00521 return; 00522 00523 // set params 00524 this->key = key; 00525 this->numSiblings = numSiblings; 00526 this->hopCountMax = hopCountMax; 00527 this->listener = listener; 00528 this->retries = retries; 00529 00530 // start lookup 00531 start(); 00532 }
const NodeVector & BaseLookup::getResult | ( | ) | const [virtual] |
Returns the result of the lookup.
Implements AbstractLookup.
00535 { 00536 // return sibling vector 00537 return siblings; 00538 }
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.
00546 { 00547 return accumulatedHops; 00548 }
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] |