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