#include <DHT.h>
Inheritance diagram for DHT:
A Distributed Hash Table (DHT) for KBR protocols
Public Member Functions | |
virtual | ~DHT () |
Protected Member Functions | |
void | initializeApp (int stage) |
initializes derived class-attributes | |
void | finishApp () |
collects statistical data of derived app | |
void | handleTimerEvent (cMessage *msg) |
processes self-messages | |
bool | handleRpc (BaseCallMessage *msg) |
Processes Remote-Procedure-Call invokation messages. | |
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 | handleUpperMessage (cMessage *msg) |
handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function) | |
void | handlePutRequest (DHTPutCall *dhtMsg) |
void | handleGetRequest (DHTGetCall *dhtMsg) |
void | handlePutResponse (DHTPutResponse *dhtMsg) |
void | handleGetResponse (DHTGetResponse *dhtMsg) |
void | handlePutCAPIRequest (DHTputCAPICall *capiPutMsg) |
void | handleGetCAPIRequest (DHTgetCAPICall *capiPutMsg) |
void | handleLookupCAPIRequest (DHTlookupCAPICall *capiLookupMsg) |
void | update (const NodeHandle &node, bool joined) |
Common API function: informs application about neighbors and own nodeID. | |
void | replicate (LookupResponse *lookupMsg) |
Protected Attributes | |
int | numReplica |
int | numGetRequests |
double | ratioIdentical |
double | numStored |
number of stored messages | |
double | maintenanceMessages |
double | normalMessages |
double | numBytesMaintenance |
double | numBytesNormal |
double | lastGetCall |
std::map< unsigned int, BaseCallMessage * > | rpcIdMap |
List of the Rpc Ids of the messages sent following the reception of an rpc request (the second member). | |
std::map< OverlayKey, GetMapEntry > | getMap |
DHTDataStorage * | dataStorage |
pointer to the dht data storage |
DHT::~DHT | ( | ) | [virtual] |
void DHT::initializeApp | ( | int | stage | ) | [protected, virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented from BaseApp.
00046 { 00047 if(stage != MIN_STAGE_APP) 00048 return; 00049 00050 dataStorage = check_and_cast<DHTDataStorage*> 00051 (parentModule()->submodule("dhtDataStorage")); 00052 00053 numReplica = par("numReplica"); 00054 numGetRequests = par("numGetRequests"); 00055 ratioIdentical = par("ratioIdentical"); 00056 00057 if (numReplica > overlay->getMaxNumSiblings()) { 00058 opp_error("DHT::initialize(): numReplica bigger than what this overlay can handle (%d)", overlay->getMaxNumSiblings()); 00059 } 00060 numStored = 0; 00061 maintenanceMessages = 0; 00062 normalMessages = 0; 00063 numBytesMaintenance = 0; 00064 numBytesNormal = 0; 00065 WATCH(numStored); 00066 WATCH(maintenanceMessages); 00067 WATCH(normalMessages); 00068 WATCH(numBytesNormal); 00069 WATCH(numBytesMaintenance); 00070 WATCH_MAP(rpcIdMap); 00071 }
void DHT::finishApp | ( | ) | [protected, virtual] |
collects statistical data of derived app
Reimplemented from BaseApp.
00688 { 00689 double time = simTime() - creationTime; 00690 globalStatistics->addStdDev("DHT: Stored Messages", numStored); 00691 globalStatistics->addStdDev("DHT: Maintenance Messages", 00692 maintenanceMessages); 00693 globalStatistics->addStdDev("DHT: Normal Messages", normalMessages); 00694 globalStatistics->addStdDev("DHT: Bytes/s Maintenance Sent", 00695 numBytesMaintenance / time); 00696 globalStatistics->addStdDev("DHT: Bytes/s Normal Sent", 00697 numBytesNormal / time); 00698 }
void DHT::handleTimerEvent | ( | cMessage * | msg | ) | [protected, virtual] |
processes self-messages
method to handle self-messages should be overwritten in derived application if needed
msg | self-message |
Reimplemented from BaseApp.
00074 { 00075 DHTTtlTimer* msg_timer; 00076 if (msg->isName("ttl_timer")) { 00077 msg_timer = check_and_cast<DHTTtlTimer*>(msg); 00078 00079 EV << "(DHT) received timer ttl, key: " 00080 << msg_timer->getKey().toString(16) 00081 << "\n (thisNode.key = " 00082 << thisNode.key.toString(16) << ")" 00083 << endl; 00084 00085 dataStorage->removeData(msg_timer->getKey()); 00086 delete msg_timer; 00087 } 00088 }
bool DHT::handleRpc | ( | BaseCallMessage * | msg | ) | [protected, virtual] |
Processes Remote-Procedure-Call invokation messages.
This method should be overloaded when the overlay provides RPC functionality.
Reimplemented from BaseRpc.
00091 { 00092 // delegate messages 00093 RPC_SWITCH_START( msg ) 00094 // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> ) 00095 RPC_DELEGATE( DHTPut, handlePutRequest ); 00096 RPC_DELEGATE( DHTGet, handleGetRequest ); 00097 RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests coming from an upper tier 00098 RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest ); 00099 RPC_DELEGATE( DHTlookupCAPI, handleLookupCAPIRequest ); 00100 RPC_SWITCH_END( ) 00101 00102 return RPC_HANDLED; 00103 }
void DHT::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.
00107 { 00108 RPC_SWITCH_START(msg) 00109 RPC_ON_RESPONSE( DHTPut ) { 00110 handlePutResponse(_DHTPutResponse); 00111 EV << "DHT Put RPC Response received: id=" << rpcId 00112 << " msg=" << *_DHTPutResponse << " rtt=" << rtt << endl; 00113 break; 00114 } 00115 RPC_ON_RESPONSE( DHTGet ) { 00116 handleGetResponse(_DHTGetResponse); 00117 EV << "DHT Get RPC Response received: id=" << rpcId 00118 << " msg=" << *_DHTGetResponse << " rtt=" << rtt << endl; 00119 break; 00120 } 00121 RPC_ON_RESPONSE( Lookup ) { 00122 replicate(_LookupResponse); 00123 EV << "Replica Set RPC Response received: id=" << rpcId 00124 << " msg=" << *_LookupResponse << " rtt=" << rtt << endl; 00125 break; 00126 } 00127 RPC_SWITCH_END( ) 00128 }
void DHT::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.
00131 { 00132 00133 RPC_SWITCH_START( msg ) 00134 RPC_ON_CALL( DHTPut ) { 00135 EV << "DHTPut Timeout" << endl; 00136 std::map<unsigned int, BaseCallMessage*>::iterator it = 00137 rpcIdMap.find(msg->getNonce()); 00138 if (it == rpcIdMap.end() || it->second == NULL) 00139 return; 00140 00141 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse(); 00142 capiPutRespMsg->setKey(_DHTPutCall->getKey()); 00143 capiPutRespMsg->setIsSuccess(false); 00144 sendRpcResponse(RPC_TO_UPPERTIER, it->second, capiPutRespMsg); 00145 rpcIdMap.erase(msg->getNonce()); 00146 break; 00147 } 00148 RPC_ON_CALL( DHTGet ) { 00149 EV << "DHTGet Timeout" << endl; 00150 std::map<unsigned int, BaseCallMessage*>::iterator it = 00151 rpcIdMap.find(_DHTGetCall->getNonce()); 00152 std::map<OverlayKey, GetMapEntry>::iterator it2 = 00153 getMap.find(_DHTGetCall->getKey()); 00154 00155 if (it2 == getMap.end()) { //unknown request 00156 return; 00157 } 00158 00159 if (!(it == rpcIdMap.end() || it->second == NULL)) { 00160 //we have sent a 'real' get request 00161 rpcIdMap.erase(_DHTGetCall->getNonce()); 00162 //ask anyone else, if possible 00163 if ((it2->second.hashVector != NULL) 00164 && (it2->second.hashVector->size() > 0)) { 00165 00166 DHTGetCall* getCall = new DHTGetCall(); 00167 getCall->setKey(_DHTGetCall->getKey()); 00168 getCall->setIsHash(false); 00169 getCall->setLength(GETCALL_L(getCall)); 00170 RECORD_STATS(normalMessages++; 00171 numBytesNormal += getCall->byteLength()); 00172 int nonce = sendRpcMessage(RPC_TO_UDP, 00173 it2->second.hashVector->back(), getCall); 00174 rpcIdMap.insert(make_pair(nonce, it2->second.callMsg)); 00175 it2->second.hashVector->pop_back(); 00176 } else { 00177 //no one else 00178 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse(); 00179 capiGetRespMsg->setKey(_DHTGetCall->getKey()); 00180 capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE); 00181 capiGetRespMsg->setIsSuccess(false); 00182 sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, 00183 capiGetRespMsg); 00184 getMap.erase(_DHTGetCall->getKey()); 00185 return; 00186 } 00187 } else { 00188 //try to ask another one of the replica list for the hash 00189 if (it2->second.replica.size() > 0) { 00190 DHTGetCall* getCall = new DHTGetCall(); 00191 getCall->setKey(_DHTGetCall->getKey()); 00192 getCall->setIsHash(true); 00193 getCall->setLength(GETCALL_L(getCall)); 00194 RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength()); 00195 sendRpcMessage(RPC_TO_UDP, it2->second.replica.back(), getCall); 00196 it2->second.replica.pop_back(); 00197 00198 } 00199 else { 00200 //no one else to ask, see what we can do with what we have 00201 if (it2->second.numResponses > 0){ 00202 unsigned int maxCount = 0; 00203 ReplicaVector* hashVector = NULL; 00204 std::map<BinaryValue, ReplicaVector>::iterator itHashes; 00205 for (itHashes = it2->second.hashes.begin(); itHashes != it2->second.hashes.end(); itHashes++) { 00206 if (itHashes->second.size() > maxCount) { 00207 maxCount = itHashes->second.size(); 00208 hashVector = &(itHashes->second); 00209 } 00210 } 00211 if ((double)maxCount/(double)it2->second.numResponses >= ratioIdentical) { 00212 it2->second.hashVector = hashVector; 00213 } 00214 } 00215 00216 if ((it2->second.hashVector != NULL) && (it2->second.hashVector->size() > 0)) 00217 { 00218 DHTGetCall* getCall = new DHTGetCall(); 00219 getCall->setKey(_DHTGetCall->getKey()); 00220 getCall->setIsHash(false); 00221 getCall->setLength(GETCALL_L(getCall)); 00222 RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength()); 00223 int nonce = sendRpcMessage(RPC_TO_UDP, it2->second.hashVector->back(), getCall); 00224 rpcIdMap.insert(make_pair(nonce, it2->second.callMsg)); 00225 it2->second.hashVector->pop_back(); 00226 } 00227 else { 00228 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse(); 00229 capiGetRespMsg->setKey(_DHTGetCall->getKey()); 00230 capiGetRespMsg->setIsSuccess(false); 00231 sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg); 00232 getMap.erase(_DHTGetCall->getKey()); 00233 } 00234 } 00235 } 00236 00237 00238 break; 00239 } 00240 RPC_SWITCH_END( ) 00241 00242 }
void DHT::handleUpperMessage | ( | cMessage * | msg | ) | [protected, virtual] |
handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function)
msg | the message to handle |
Reimplemented from BaseApp.
00246 { 00247 error("DHT::handleUpperMessage(): Received message with unknown type!"); 00248 00249 delete msg; 00250 }
void DHT::handlePutRequest | ( | DHTPutCall * | dhtMsg | ) | [protected] |
00253 { 00254 std::string tempString = "PUT_REQUEST received: " + 00255 std::string(dhtMsg->getKey().toString(16)); 00256 parentModule()->parentModule()->bubble(tempString.c_str()); 00257 00258 if (!(dataStorage->isModifiable(dhtMsg->getKey()))) { 00259 //check if the put request came from the right node 00260 NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey()); 00261 if (((!sourceNode.isUnspecified()) && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode != dhtMsg->getSrcNode())) 00262 || ((dhtMsg->getMaintenance()) && (dhtMsg->getOwnerNode() == sourceNode))) { 00263 DHTPutResponse* responseMsg = new DHTPutResponse(); 00264 responseMsg->setKey(dhtMsg->getKey()); 00265 tempString = "Error, not allowed to modify this key"; 00266 responseMsg->setValue(BinaryValue(tempString)); 00267 responseMsg->setLength(PUTRESPONSE_L(responseMsg)); 00268 RECORD_STATS(normalMessages++; 00269 numBytesNormal += responseMsg->byteLength()); 00270 sendRpcResponse(RPC_TO_UDP, dhtMsg, responseMsg); 00271 return; 00272 } 00273 00274 } 00275 00276 // remove data item from local data storage 00277 cancelAndDelete(dataStorage->getTtlMessage(dhtMsg->getKey())); 00278 dataStorage->removeData(dhtMsg->getKey()); 00279 if (dhtMsg->getValue().size() > 0) { 00280 //add ttl timer 00281 DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer"); 00282 timerMsg->setKey(dhtMsg->getKey()); 00283 scheduleAt(simTime()+dhtMsg->getTtl(), timerMsg); 00284 // storage data item in local data storage 00285 bool err; 00286 dataStorage->addData(dhtMsg->getKey(), dhtMsg->getValue(), timerMsg, 00287 dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(), 00288 overlay->isSiblingFor(thisNode, dhtMsg->getKey(), 00289 1, &err)); 00290 } 00291 00292 // send back 00293 DHTPutResponse* responseMsg = new DHTPutResponse(); 00294 responseMsg->setKey(dhtMsg->getKey()); 00295 00296 responseMsg->setValue(dhtMsg->getValue()); 00297 responseMsg->setLength(PUTRESPONSE_L(responseMsg)); 00298 RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength()); 00299 00300 sendRpcResponse(RPC_TO_UDP, dhtMsg, responseMsg); 00301 }
void DHT::handleGetRequest | ( | DHTGetCall * | dhtMsg | ) | [protected] |
00304 { 00305 std::string tempString = "GET_REQUEST received: " + 00306 std::string(dhtMsg->getKey().toString(16)); 00307 parentModule()->parentModule()->bubble(tempString.c_str()); 00308 00309 BinaryValue storedValue = dataStorage->getData(dhtMsg->getKey()); 00310 00311 00312 // send back 00313 DHTGetResponse* responseMsg = new DHTGetResponse(); 00314 responseMsg->setKey(dhtMsg->getKey()); 00315 responseMsg->setIsHash(dhtMsg->getIsHash()); 00316 if (storedValue == BinaryValue::UNSPECIFIED_VALUE) { 00317 responseMsg->setValue(BinaryValue::UNSPECIFIED_VALUE); 00318 } 00319 else { 00320 if (dhtMsg->getIsHash()) { 00321 CSHA1 sha1; 00322 char temp[41]; 00323 temp[0] = '\0'; 00324 sha1.Reset(); 00325 sha1.Update((uint8_t*)(&(*storedValue.begin())), 00326 storedValue.size()); 00327 sha1.Final(); 00328 sha1.ReportHash(temp, CSHA1::REPORT_HEX); 00329 00330 responseMsg->setValue(BinaryValue((char*)temp)); 00331 } 00332 else { 00333 responseMsg->setValue(storedValue); 00334 } 00335 } 00336 responseMsg->setLength(GETRESPONSE_L(responseMsg)); 00337 RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength()); 00338 sendRpcResponse(RPC_TO_UDP, dhtMsg, responseMsg); 00339 }
void DHT::handlePutResponse | ( | DHTPutResponse * | dhtMsg | ) | [protected] |
00374 { 00375 std::map<unsigned int, BaseCallMessage*>::iterator it = 00376 rpcIdMap.find(dhtMsg->getNonce()); 00377 if (it == rpcIdMap.end() || it->second == NULL) 00378 return; 00379 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse(); 00380 capiPutRespMsg->setKey(dhtMsg->getKey()); 00381 capiPutRespMsg->setValue(dhtMsg->getValue()); 00382 capiPutRespMsg->setIsSuccess(true); 00383 sendRpcResponse(RPC_TO_UPPERTIER, it->second, capiPutRespMsg); 00384 rpcIdMap.erase(dhtMsg->getNonce()); 00385 }
void DHT::handleGetResponse | ( | DHTGetResponse * | dhtMsg | ) | [protected] |
00388 { 00389 std::map<unsigned int, BaseCallMessage*>::iterator it = 00390 rpcIdMap.find(dhtMsg->getNonce()); 00391 std::map<OverlayKey, GetMapEntry>::iterator it2 = 00392 getMap.find(dhtMsg->getKey()); 00393 if (it2 == getMap.end()) //unknown request 00394 return; 00395 00396 if ((it != rpcIdMap.end()) && (it->second != NULL)) { 00397 //we have sent a 'real' get request 00398 rpcIdMap.erase(dhtMsg->getNonce()); 00399 if (!dhtMsg->getIsHash()) { 00400 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse(); 00401 capiGetRespMsg->setKey(dhtMsg->getKey()); 00402 capiGetRespMsg->setValue(dhtMsg->getValue()); 00403 capiGetRespMsg->setIsSuccess(true); 00404 sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, 00405 capiGetRespMsg); 00406 getMap.erase(dhtMsg->getKey()); 00407 return; 00408 } 00409 } 00410 else { 00411 if (dhtMsg->getIsHash()) { 00412 std::map<BinaryValue, ReplicaVector>::iterator itHashes = it2->second.hashes.find(dhtMsg->getValue()); 00413 if (itHashes == it2->second.hashes.end()) //new hash 00414 { 00415 ReplicaVector vect = ReplicaVector(); 00416 vect.push_back(dhtMsg->getSrcNode()); 00417 it2->second.hashes.insert(make_pair(dhtMsg->getValue(), vect)); 00418 } 00419 else { 00420 itHashes->second.push_back(dhtMsg->getSrcNode()); 00421 } 00422 it2->second.numResponses++; 00423 if (it2->second.numResponses >= numGetRequests) { 00424 //we've got all the answers we wanted 00425 unsigned int maxCount = 0; 00426 ReplicaVector* hashVector = NULL; 00427 for (itHashes = it2->second.hashes.begin(); itHashes != it2->second.hashes.end(); itHashes++) { 00428 if (itHashes->second.size() > maxCount) { 00429 maxCount = itHashes->second.size(); 00430 hashVector = &(itHashes->second); 00431 } 00432 } 00433 if ((double)maxCount/(double)it2->second.numResponses >= ratioIdentical) { 00434 it2->second.hashVector = hashVector; 00435 } 00436 else { 00437 //we'll try to ask some other nodes 00438 if (it2->second.replica.size() > 0) { 00439 DHTGetCall* getCall = new DHTGetCall(); 00440 getCall->setKey(dhtMsg->getKey()); 00441 getCall->setIsHash(true); 00442 getCall->setLength(GETCALL_L(getCall)); 00443 RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength()); 00444 sendRpcMessage(RPC_TO_UDP, it2->second.replica.back(), getCall); 00445 it2->second.replica.pop_back(); 00446 } 00447 else { //we don't have anyone else to ask 00448 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse(); 00449 capiGetRespMsg->setKey(dhtMsg->getKey()); 00450 capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE); 00451 capiGetRespMsg->setIsSuccess(false); 00452 sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg); 00453 getMap.erase(dhtMsg->getKey()); 00454 } 00455 00456 00457 } 00458 } 00459 } 00460 } 00461 00462 if (it2->second.hashVector != NULL) { 00463 //we have already received all the response and chosen a hash 00464 if (it2->second.hashVector->size() > 0) { 00465 DHTGetCall* getCall = new DHTGetCall(); 00466 getCall->setKey(dhtMsg->getKey()); 00467 getCall->setIsHash(false); 00468 getCall->setLength(GETCALL_L(getCall)); 00469 RECORD_STATS(normalMessages++; 00470 numBytesNormal += getCall->byteLength()); 00471 int nonce = sendRpcMessage(RPC_TO_UDP, 00472 it2->second.hashVector->back(), getCall); 00473 rpcIdMap.insert(make_pair(nonce, it2->second.callMsg)); 00474 it2->second.hashVector->pop_back(); 00475 } 00476 else { //we don't have anyone else to ask 00477 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse(); 00478 capiGetRespMsg->setKey(dhtMsg->getKey()); 00479 capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE); 00480 capiGetRespMsg->setIsSuccess(false); 00481 sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, 00482 capiGetRespMsg); 00483 rpcIdMap.erase(dhtMsg->getNonce()); 00484 getMap.erase(dhtMsg->getKey()); 00485 } 00486 } 00487 }
void DHT::handlePutCAPIRequest | ( | DHTputCAPICall * | capiPutMsg | ) | [protected] |
00342 { 00343 //asks the replica list 00344 LookupCall* replicaMsg = new LookupCall(); 00345 replicaMsg->setKey(capiPutMsg->getKey()); 00346 replicaMsg->setNumSiblings(numReplica); 00347 int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE, 00348 replicaMsg, NULL, OverlayKey::UNSPECIFIED_KEY, -1, 0); 00349 rpcIdMap.insert(make_pair(nonce, capiPutMsg)); 00350 }
void DHT::handleGetCAPIRequest | ( | DHTgetCAPICall * | capiPutMsg | ) | [protected] |
00353 { 00354 LookupCall* replicaMsg = new LookupCall(); 00355 replicaMsg->setKey(capiGetMsg->getKey()); 00356 replicaMsg->setNumSiblings(numReplica); 00357 int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE, 00358 replicaMsg, NULL, OverlayKey::UNSPECIFIED_KEY, -1, 0); 00359 rpcIdMap.insert(make_pair(nonce, capiGetMsg)); 00360 lastGetCall = simTime(); 00361 }
void DHT::handleLookupCAPIRequest | ( | DHTlookupCAPICall * | capiLookupMsg | ) | [protected] |
00364 { 00365 LookupCall* lookupMsg = new LookupCall(); 00366 lookupMsg->setKey(capiLookupMsg->getKey()); 00367 lookupMsg->setNumSiblings(capiLookupMsg->getNumSiblings()); 00368 int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE, 00369 lookupMsg, NULL, OverlayKey::UNSPECIFIED_KEY, -1, 0); 00370 rpcIdMap.insert(make_pair(nonce, capiLookupMsg)); 00371 }
void DHT::update | ( | const NodeHandle & | node, | |
bool | joined | |||
) | [protected, virtual] |
Common API function: informs application about neighbors and own nodeID.
node | new or lost neighbor | |
joined | new or lost? |
Reimplemented from BaseApp.
00490 { 00491 OverlayKey key; 00492 DHTPutCall* dhtMsg; 00493 bool err=false; 00494 DHTData entry; 00495 std::map<OverlayKey, DHTData>::iterator it = dataStorage->begin(); 00496 for (unsigned int i=0; i< dataStorage->getSize() ; i++) { 00497 key = it->first; 00498 entry = it->second; 00499 if (joined) { 00500 if (overlay->isSiblingFor(node, key, 1, &err)) { 00501 // we're responsible for this key 00502 if (overlay->isSiblingFor(node, key, numReplica, &err)) { 00503 dhtMsg = new DHTPutCall(); 00504 dhtMsg->setKey(key); 00505 dhtMsg->setValue(entry.value); 00506 dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime() 00507 - simulation.simTime())); 00508 dhtMsg->setIsModifiable(entry.is_modifiable); 00509 dhtMsg->setMaintenance(true); 00510 dhtMsg->setLength(PUTCALL_L(dhtMsg)); 00511 RECORD_STATS(maintenanceMessages++; 00512 numBytesMaintenance += dhtMsg->byteLength()); 00513 sendRpcMessage(RPC_TO_UDP, node, dhtMsg); 00514 } 00515 if (err) { 00516 EV << "Unable to know if key: " << key 00517 << " is in range of node: " << node << endl; 00518 } 00519 } else { 00520 //check if we were responsible for this key 00521 if (overlay->isSiblingFor(node, key, 1, &err) || err) { 00522 if (!err || entry.responsible) { 00523 // hack for chord, as we can't know if we were responsible 00524 dhtMsg = new DHTPutCall(); 00525 dhtMsg->setKey(key); 00526 dhtMsg->setValue(entry.value); 00527 dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime() 00528 - simulation.simTime())); 00529 dhtMsg->setIsModifiable(entry.is_modifiable); 00530 dhtMsg->setMaintenance(true); 00531 dhtMsg->setLength(PUTCALL_L(dhtMsg)); 00532 RECORD_STATS(maintenanceMessages++; 00533 numBytesMaintenance += dhtMsg->byteLength()); 00534 sendRpcMessage(RPC_TO_UDP, node, dhtMsg); 00535 } 00536 00537 } 00538 00539 } 00540 } 00541 else { 00542 //the update concerns a node who has leaved 00543 //replicate 00544 LookupCall* replicaMsg = new LookupCall(); 00545 replicaMsg->setKey(key); 00546 replicaMsg->setNumSiblings(numReplica); 00547 int nonce = sendRpcMessage(RPC_TO_LOWERTIER, 00548 NodeHandle::UNSPECIFIED_NODE, replicaMsg, 00549 NULL, OverlayKey::UNSPECIFIED_KEY, 00550 -1, 0); 00551 dhtMsg = new DHTPutCall(); 00552 dhtMsg->setKey(key); 00553 dhtMsg->setValue(entry.value); 00554 dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime() 00555 - simulation.simTime())); 00556 dhtMsg->setIsModifiable(entry.is_modifiable); 00557 dhtMsg->setMaintenance(true); 00558 dhtMsg->setLength(PUTCALL_L(dhtMsg)); 00559 00560 rpcIdMap.insert(make_pair(nonce, dhtMsg)); 00561 } 00562 entry.responsible = overlay->isSiblingFor(thisNode, key, 1, &err); 00563 it++; 00564 } 00565 }
void DHT::replicate | ( | LookupResponse * | lookupMsg | ) | [protected] |
00568 { 00569 std::map<unsigned int, BaseCallMessage*>::iterator it = 00570 rpcIdMap.find(lookupMsg->getNonce()); 00571 if (it == rpcIdMap.end() || it->second == NULL) 00572 return; 00573 00574 if (dynamic_cast<DHTlookupCAPICall*>(it->second)) { 00575 DHTlookupCAPICall* capiLookupMsg = 00576 dynamic_cast<DHTlookupCAPICall*>(it->second); 00577 rpcIdMap.erase(lookupMsg->getNonce()); 00578 00579 DHTlookupCAPIResponse* capiLookupRespMsg = 00580 new DHTlookupCAPIResponse(); 00581 capiLookupRespMsg->setKey(lookupMsg->getKey()); 00582 capiLookupRespMsg->setIsValid(lookupMsg->getIsValid()); 00583 capiLookupRespMsg->setSiblingsArraySize( 00584 lookupMsg->getSiblingsArraySize()); 00585 00586 for (uint i = 0; i < lookupMsg->getSiblingsArraySize(); i++) { 00587 capiLookupRespMsg->setSiblings(i, lookupMsg->getSiblings(i)); 00588 } 00589 00590 sendRpcResponse(RPC_TO_UPPERTIER, capiLookupMsg, capiLookupRespMsg); 00591 return; 00592 } else if (dynamic_cast<DHTputCAPICall*>(it->second)) { 00593 DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*>(it->second); 00594 rpcIdMap.erase(lookupMsg->getNonce()); 00595 00596 if ((lookupMsg->getIsValid() == false) 00597 || (lookupMsg->getSiblingsArraySize() == 0)) { 00598 00599 EV << "Unable to get replica list : invalid lookup" << endl; 00600 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse(); 00601 capiPutRespMsg->setKey(lookupMsg->getKey()); 00602 capiPutRespMsg->setIsSuccess(false); 00603 sendRpcResponse(RPC_TO_UPPERTIER, capiPutMsg, capiPutRespMsg); 00604 return; 00605 } 00606 00607 for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) { 00608 DHTPutCall* dhtMsg = new DHTPutCall(); 00609 dhtMsg->setKey(capiPutMsg->getKey()); 00610 dhtMsg->setValue(capiPutMsg->getValue()); 00611 dhtMsg->setTtl(capiPutMsg->getTtl()); 00612 dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable()); 00613 dhtMsg->setMaintenance(false); 00614 dhtMsg->setLength(PUTCALL_L(dhtMsg)); 00615 RECORD_STATS(normalMessages++; 00616 numBytesNormal += dhtMsg->byteLength()); 00617 int nonce = sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i), 00618 dhtMsg); 00619 if (i == 0) { 00620 rpcIdMap.insert(make_pair(nonce, capiPutMsg)); 00621 } 00622 } 00623 } 00624 else if (dynamic_cast<DHTgetCAPICall*>(it->second)) { 00625 DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second); 00626 rpcIdMap.erase(lookupMsg->getNonce()); 00627 00628 if ((lookupMsg->getIsValid() == false) 00629 || (lookupMsg->getSiblingsArraySize() == 0)) { 00630 00631 EV << "Unable to get replica list : invalid lookup" << endl; 00632 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse(); 00633 capiGetRespMsg->setKey(lookupMsg->getKey()); 00634 capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE); 00635 capiGetRespMsg->setIsSuccess(false); 00636 sendRpcResponse(RPC_TO_UPPERTIER, capiGetMsg, capiGetRespMsg); 00637 return; 00638 } 00639 00640 GetMapEntry mapEntry; 00641 00642 for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) { 00643 if (i < (unsigned int)numGetRequests) { 00644 DHTGetCall* dhtMsg = new DHTGetCall(); 00645 dhtMsg->setKey(capiGetMsg->getKey()); 00646 dhtMsg->setIsHash(true); 00647 dhtMsg->setLength(GETCALL_L(dhtMsg)); 00648 RECORD_STATS(normalMessages++; 00649 numBytesNormal += dhtMsg->byteLength()); 00650 sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i), dhtMsg); 00651 } 00652 else { 00653 //We don't send, we just store the remaining keys 00654 mapEntry.replica.push_back(lookupMsg->getSiblings(i)); 00655 } 00656 } 00657 00658 mapEntry.callMsg = check_and_cast<DHTgetCAPICall*>(it->second); 00659 mapEntry.numResponses = 0; 00660 mapEntry.hashVector = NULL; 00661 00662 getMap.insert(make_pair(capiGetMsg->getKey(), mapEntry)); 00663 } 00664 else if (dynamic_cast<DHTPutCall*>(it->second)) { 00665 DHTPutCall* putMsg = dynamic_cast<DHTPutCall*>(it->second); 00666 rpcIdMap.erase(lookupMsg->getNonce()); 00667 00668 if ((lookupMsg->getIsValid() == false) 00669 || (lookupMsg->getSiblingsArraySize() == 0)) { 00670 00671 EV << "Unable to get replica list : invalid lookup" << endl; 00672 delete putMsg; 00673 return; 00674 } 00675 00676 for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) { 00677 RECORD_STATS(maintenanceMessages++; 00678 numBytesMaintenance += putMsg->byteLength()); 00679 00680 sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i), 00681 new DHTPutCall(*putMsg)); 00682 } 00683 delete putMsg; 00684 } 00685 }
int DHT::numReplica [protected] |
int DHT::numGetRequests [protected] |
double DHT::ratioIdentical [protected] |
double DHT::numStored [protected] |
number of stored messages
double DHT::maintenanceMessages [protected] |
double DHT::normalMessages [protected] |
double DHT::numBytesMaintenance [protected] |
double DHT::numBytesNormal [protected] |
double DHT::lastGetCall [protected] |
std::map<unsigned int, BaseCallMessage*> DHT::rpcIdMap [protected] |
List of the Rpc Ids of the messages sent following the reception of an rpc request (the second member).
std::map<OverlayKey, GetMapEntry> DHT::getMap [protected] |
DHTDataStorage* DHT::dataStorage [protected] |
pointer to the dht data storage