00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <IPAddressResolver.h>
00025
00026 #include "DHT.h"
00027
00028 #include <RpcMacros.h>
00029 #include <BaseRpc.h>
00030 #include <GlobalStatistics.h>
00031
00032 Define_Module(DHT);
00033
00034 using namespace std;
00035
00036 DHT::DHT()
00037 {
00038 dataStorage = NULL;
00039 }
00040
00041 DHT::~DHT()
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<int, 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 std::map<int, PutMapEntry>::iterator it3;
00058
00059 for (it3 = putMap.begin(); it3 != putMap.end(); it3++) {
00060 cancelAndDelete(it3->second.callMsg);
00061 it3->second.callMsg = NULL;
00062 }
00063
00064 rpcIdMap.clear();
00065 getMap.clear();
00066 putMap.clear();
00067
00068 if (dataStorage != NULL) {
00069 dataStorage->clear();
00070 }
00071 }
00072
00073 void DHT::initializeApp(int stage)
00074 {
00075 if (stage != MIN_STAGE_APP)
00076 return;
00077
00078 dataStorage = check_and_cast<DHTDataStorage*>
00079 (getParentModule()->getSubmodule("dhtDataStorage"));
00080
00081 numReplica = par("numReplica");
00082 numGetRequests = par("numGetRequests");
00083 ratioIdentical = par("ratioIdentical");
00084
00085 if (numReplica > overlay->getMaxNumSiblings()) {
00086 opp_error("DHT::initialize(): numReplica bigger than what this "
00087 "overlay can handle (%d)", overlay->getMaxNumSiblings());
00088 }
00089
00090 maintenanceMessages = 0;
00091 normalMessages = 0;
00092 numBytesMaintenance = 0;
00093 numBytesNormal = 0;
00094 WATCH(maintenanceMessages);
00095 WATCH(normalMessages);
00096 WATCH(numBytesNormal);
00097 WATCH(numBytesMaintenance);
00098 WATCH_MAP(rpcIdMap);
00099 }
00100
00101 void DHT::handleTimerEvent(cMessage* msg)
00102 {
00103 DHTTtlTimer* msg_timer = dynamic_cast<DHTTtlTimer*> (msg);
00104
00105 if (msg_timer) {
00106 EV << "[DHT::handleTimerEvent()]\n"
00107 << " received timer ttl, key: "
00108 << msg_timer->getKey().toString(16)
00109 << "\n (overlay->getThisNode().getKey() = "
00110 << overlay->getThisNode().getKey().toString(16) << ")"
00111 << endl;
00112
00113 dataStorage->removeData(msg_timer->getKey(), msg_timer->getKind(),
00114 msg_timer->getId());
00115 }
00116 }
00117
00118 bool DHT::handleRpcCall(BaseCallMessage* msg)
00119 {
00120
00121 RPC_SWITCH_START( msg )
00122
00123 RPC_DELEGATE( DHTPut, handlePutRequest );
00124 RPC_DELEGATE( DHTGet, handleGetRequest );
00125 RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest );
00126 RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest );
00127 RPC_DELEGATE( DHTdump, handleDumpDhtRequest );
00128 RPC_SWITCH_END( )
00129
00130 return RPC_HANDLED;
00131 }
00132
00133 void DHT::handleRpcResponse(BaseResponseMessage* msg, cPolymorphic* context,
00134 int rpcId, simtime_t rtt)
00135 {
00136 RPC_SWITCH_START(msg)
00137 RPC_ON_RESPONSE(DHTPut){
00138 handlePutResponse(_DHTPutResponse, rpcId);
00139 EV << "[DHT::handleRpcResponse()]\n"
00140 << " DHT Put RPC Response received: id=" << rpcId
00141 << " msg=" << *_DHTPutResponse << " rtt=" << rtt
00142 << endl;
00143 break;
00144 }
00145 RPC_ON_RESPONSE(DHTGet) {
00146 handleGetResponse(_DHTGetResponse, rpcId);
00147 EV << "[DHT::handleRpcResponse()]\n"
00148 << " DHT Get RPC Response received: id=" << rpcId
00149 << " msg=" << *_DHTGetResponse << " rtt=" << rtt
00150 << endl;
00151 break;
00152 }
00153 RPC_ON_RESPONSE(Lookup) {
00154 handleLookupResponse(_LookupResponse);
00155 EV << "[DHT::handleRpcResponse()]\n"
00156 << " Replica Set RPC Response received: id=" << rpcId
00157 << " msg=" << *_LookupResponse << " rtt=" << rtt
00158 << endl;
00159 break;
00160 }
00161 RPC_SWITCH_END()
00162 }
00163
00164 void DHT::handleRpcTimeout(BaseCallMessage* msg, const TransportAddress& dest,
00165 cPolymorphic* context, int rpcId,
00166 const OverlayKey& destKey)
00167 {
00168
00169 RPC_SWITCH_START(msg)
00170 RPC_ON_CALL(DHTPut){
00171 EV << "[DHT::handleRpcResponse()]\n"
00172 << " DHTPut Timeout"
00173 << endl;
00174
00175 std::map<int, PutMapEntry>::iterator it2 =
00176 putMap.find(rpcId);
00177
00178 if (it2 == putMap.end())
00179 return;
00180
00181 it2->second.numFailed++;
00182
00183 if (it2->second.numFailed / (double)it2->second.numSent >= 0.5) {
00184 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00185 capiPutRespMsg->setKey(_DHTPutCall->getKey());
00186 capiPutRespMsg->setIsSuccess(false);
00187 sendRpcResponse(it2->second.callMsg, capiPutRespMsg);
00188
00189 it2->second.callMsg = NULL;
00190 putMap.erase(rpcId);
00191 }
00192
00193 break;
00194 }
00195 RPC_ON_CALL(DHTGet) {
00196 EV << "[DHT::handleRpcResponse()]\n"
00197 << " DHTGet Timeout"
00198 << endl;
00199
00200 std::map<unsigned int, BaseCallMessage*>::iterator it =
00201 rpcIdMap.find(_DHTGetCall->getNonce());
00202 std::map<int, GetMapEntry>::iterator it2 =
00203 getMap.find(rpcId);
00204
00205 if (it2 == getMap.end()) {
00206 return;
00207 }
00208
00209 if (it != rpcIdMap.end()) {
00210
00211 rpcIdMap.erase(_DHTGetCall->getNonce());
00212
00213
00214 if ((it2->second.hashVector != NULL)
00215 && (it2->second.hashVector->size()> 0)) {
00216
00217 DHTGetCall* getCall = new DHTGetCall();
00218 getCall->setKey(_DHTGetCall->getKey());
00219 getCall->setKind(_DHTGetCall->getKind());
00220 getCall->setId(_DHTGetCall->getId());
00221 getCall->setIsHash(false);
00222 getCall->setBitLength(GETCALL_L(getCall));
00223 RECORD_STATS(normalMessages++;
00224 numBytesNormal += getCall->getByteLength());
00225
00226 int nonce = sendRouteRpcCall(TIER1_COMP,
00227 it2->second.hashVector->back(),
00228 getCall, NULL, DEFAULT_ROUTING,
00229 -1, 0, rpcId);
00230 rpcIdMap.insert(make_pair(nonce, (BaseCallMessage*)NULL));
00231 it2->second.hashVector->pop_back();
00232 } else {
00233
00234 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00235 capiGetRespMsg->setIsSuccess(false);
00236 sendRpcResponse(it2->second.callMsg,
00237 capiGetRespMsg);
00238
00239 getMap.erase(rpcId);
00240 return;
00241 }
00242
00243 } else {
00244
00245 if (it2->second.replica.size() > 0) {
00246 DHTGetCall* getCall = new DHTGetCall();
00247 getCall->setKey(_DHTGetCall->getKey());
00248 getCall->setKind(_DHTGetCall->getKind());
00249 getCall->setId(_DHTGetCall->getId());
00250 getCall->setIsHash(true);
00251 getCall->setBitLength(GETCALL_L(getCall));
00252
00253 RECORD_STATS(normalMessages++;
00254 numBytesNormal += getCall->getByteLength());
00255
00256 sendRouteRpcCall(TIER1_COMP, it2->second.replica.back(),
00257 getCall, NULL, DEFAULT_ROUTING, -1, 0,
00258 rpcId);
00259 it2->second.replica.pop_back();
00260 } else {
00261
00262 if (it2->second.numResponses > 0) {
00263 unsigned int maxCount = 0;
00264 ReplicaVector* hashVector = NULL;
00265 std::map<BinaryValue, ReplicaVector>::iterator itHashes;
00266 for (itHashes = it2->second.hashes.begin();
00267 itHashes != it2->second.hashes.end(); itHashes++) {
00268
00269 if (itHashes->second.size()> maxCount) {
00270 maxCount = itHashes->second.size();
00271 hashVector = &(itHashes->second);
00272 }
00273 }
00274
00275 if ((double)maxCount/(double)it2->second.numResponses >=
00276 ratioIdentical) {
00277 it2->second.hashVector = hashVector;
00278 }
00279 }
00280
00281 if ((it2->second.hashVector != NULL)
00282 && (it2->second.hashVector->size()> 0)) {
00283
00284 DHTGetCall* getCall = new DHTGetCall();
00285 getCall->setKey(_DHTGetCall->getKey());
00286 getCall->setKind(_DHTGetCall->getKind());
00287 getCall->setId(_DHTGetCall->getId());
00288 getCall->setIsHash(false);
00289 getCall->setBitLength(GETCALL_L(getCall));
00290 RECORD_STATS(normalMessages++;
00291 numBytesNormal += getCall->getByteLength());
00292 int nonce = sendRouteRpcCall(TIER1_COMP,
00293 it2->second.hashVector->back(),
00294 getCall, NULL, DEFAULT_ROUTING,
00295 -1, 0, rpcId);
00296 rpcIdMap.insert(make_pair(nonce, (BaseCallMessage*)NULL));
00297 it2->second.hashVector->pop_back();
00298 } else {
00299 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00300 capiGetRespMsg->setIsSuccess(false);
00301 sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00302
00303 getMap.erase(rpcId);
00304 }
00305 }
00306 }
00307 break;
00308 }
00309 RPC_SWITCH_END( )
00310 }
00311
00312 void DHT::handlePutRequest(DHTPutCall* dhtMsg)
00313 {
00314 std::string tempString = "PUT_REQUEST received: "
00315 + std::string(dhtMsg->getKey().toString(16));
00316 getParentModule()->getParentModule()->bubble(tempString.c_str());
00317
00318 if (!(dataStorage->isModifiable(dhtMsg->getKey(), dhtMsg->getKind(),
00319 dhtMsg->getId()))) {
00320
00321 NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey(),
00322 dhtMsg->getKind(), dhtMsg->getId());
00323 if (((!sourceNode.isUnspecified())
00324 && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode
00325 != dhtMsg->getSrcNode())) || ((dhtMsg->getMaintenance())
00326 && (dhtMsg->getOwnerNode() == sourceNode))) {
00327
00328 DHTPutResponse* responseMsg = new DHTPutResponse();
00329 responseMsg->setKey(dhtMsg->getKey());
00330 tempString = "Error, not allowed to modify this key";
00331 responseMsg->setValue(BinaryValue(tempString));
00332 responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00333 RECORD_STATS(normalMessages++;
00334 numBytesNormal += responseMsg->getByteLength());
00335 sendRpcResponse(dhtMsg, responseMsg);
00336 return;
00337 }
00338
00339 }
00340
00341
00342 dataStorage->removeData(dhtMsg->getKey(), dhtMsg->getKind(),
00343 dhtMsg->getId());
00344
00345 if (dhtMsg->getValue().size() > 0) {
00346
00347 DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00348 timerMsg->setKey(dhtMsg->getKey());
00349 timerMsg->setKind(dhtMsg->getKind());
00350 timerMsg->setId(dhtMsg->getId());
00351 scheduleAt(simTime() + dhtMsg->getTtl(), timerMsg);
00352
00353 bool err;
00354 dataStorage->addData(dhtMsg->getKey(), dhtMsg->getKind(),
00355 dhtMsg->getId(), dhtMsg->getValue(), timerMsg,
00356 dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(),
00357 overlay->isSiblingFor(overlay->getThisNode(),
00358 dhtMsg->getKey(),
00359 1, &err));
00360 }
00361
00362
00363 DHTPutResponse* responseMsg = new DHTPutResponse();
00364 responseMsg->setKey(dhtMsg->getKey());
00365 responseMsg->setValue(dhtMsg->getValue());
00366 responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00367 RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->getByteLength());
00368
00369 sendRpcResponse(dhtMsg, responseMsg);
00370 }
00371
00372 void DHT::handleGetRequest(DHTGetCall* dhtMsg)
00373 {
00374 std::string tempString = "GET_REQUEST received: "
00375 + std::string(dhtMsg->getKey().toString(16));
00376
00377 getParentModule()->getParentModule()->bubble(tempString.c_str());
00378
00379 if (dhtMsg->getKey().isUnspecified()) {
00380 throw cRuntimeError("DHT::handleGetRequest: Unspecified key!");
00381 }
00382
00383 DhtDumpVector* dataVect = dataStorage->dumpDht(dhtMsg->getKey(),
00384 dhtMsg->getKind(),
00385 dhtMsg->getId());
00386
00387
00388 DHTGetResponse* responseMsg = new DHTGetResponse();
00389 responseMsg->setKey(dhtMsg->getKey());
00390 responseMsg->setIsHash(dhtMsg->getIsHash());
00391
00392 if (dataVect->size() == 0) {
00393 responseMsg->setHashValue(BinaryValue::UNSPECIFIED_VALUE);
00394 responseMsg->setResultArraySize(0);
00395 } else {
00396 if (dhtMsg->getIsHash()) {
00397
00398 BinaryValue resultValues;
00399 for (uint32_t i = 0; i < dataVect->size(); i++) {
00400 resultValues += (*dataVect)[i].getValue();
00401 }
00402
00403 CSHA1 sha1;
00404 BinaryValue hashValue(20);
00405 sha1.Reset();
00406 sha1.Update((uint8_t*) (&(*resultValues.begin())),
00407 resultValues.size());
00408 sha1.Final();
00409 sha1.GetHash((unsigned char*)&hashValue[0]);
00410
00411 responseMsg->setHashValue(hashValue);
00412 } else {
00413 responseMsg->setResultArraySize(dataVect->size());
00414
00415 for (uint32_t i = 0; i < dataVect->size(); i++) {
00416 responseMsg->setResult(i, (*dataVect)[i]);
00417 }
00418
00419 }
00420
00421 delete dataVect;
00422 }
00423
00424 responseMsg->setBitLength(GETRESPONSE_L(responseMsg));
00425 RECORD_STATS(normalMessages++;
00426 numBytesNormal += responseMsg->getByteLength());
00427 sendRpcResponse(dhtMsg, responseMsg);
00428 }
00429
00430 void DHT::handlePutCAPIRequest(DHTputCAPICall* capiPutMsg)
00431 {
00432
00433 LookupCall* replicaMsg = new LookupCall();
00434 replicaMsg->setKey(capiPutMsg->getKey());
00435 replicaMsg->setNumSiblings(numReplica);
00436 int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00437 rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00438 }
00439
00440 void DHT::handleGetCAPIRequest(DHTgetCAPICall* capiGetMsg)
00441 {
00442 LookupCall* replicaMsg = new LookupCall();
00443 replicaMsg->setKey(capiGetMsg->getKey());
00444 replicaMsg->setNumSiblings(numReplica);
00445 int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00446 rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00447 lastGetCall = simTime();
00448 }
00449
00450 void DHT::handleDumpDhtRequest(DHTdumpCall* call)
00451 {
00452 DHTdumpResponse* response = new DHTdumpResponse();
00453 DhtDumpVector* dumpVector = dataStorage->dumpDht();
00454
00455 response->setRecordArraySize(dumpVector->size());
00456
00457 for (uint32_t i = 0; i < dumpVector->size(); i++) {
00458 response->setRecord(i, (*dumpVector)[i]);
00459 }
00460
00461 delete dumpVector;
00462
00463 sendRpcResponse(call, response);
00464 }
00465
00466 void DHT::handlePutResponse(DHTPutResponse* dhtMsg, int rpcId)
00467 {
00468 std::map<int, PutMapEntry>::iterator it2 =
00469 putMap.find(rpcId);
00470
00471 if (it2 == putMap.end())
00472 return;
00473
00474 it2->second.numResponses++;
00475
00476 if (it2->second.numResponses / (double)it2->second.numSent > 0.5) {
00477 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00478 capiPutRespMsg->setKey(dhtMsg->getKey());
00479 capiPutRespMsg->setValue(dhtMsg->getValue());
00480 capiPutRespMsg->setIsSuccess(true);
00481 sendRpcResponse(it2->second.callMsg, capiPutRespMsg);
00482 it2->second.callMsg = NULL;
00483 putMap.erase(rpcId);
00484 }
00485 }
00486
00487 void DHT::handleGetResponse(DHTGetResponse* dhtMsg, int rpcId)
00488 {
00489 std::map<unsigned int, BaseCallMessage*>::iterator it =
00490 rpcIdMap.find(dhtMsg->getNonce());
00491 std::map<int, GetMapEntry>::iterator it2 =
00492 getMap.find(rpcId);
00493
00494 if (it2 == getMap.end())
00495 return;
00496
00497 if (it != rpcIdMap.end()) {
00498
00499 rpcIdMap.erase(dhtMsg->getNonce());
00500 if (!dhtMsg->getIsHash()) {
00501
00502 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00503 capiGetRespMsg->setResultArraySize(dhtMsg->getResultArraySize());
00504 for (uint i = 0; i < dhtMsg->getResultArraySize(); i++) {
00505 capiGetRespMsg->setResult(i, dhtMsg->getResult(i));
00506 }
00507 capiGetRespMsg->setIsSuccess(true);
00508 sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00509 getMap.erase(rpcId);
00510 return;
00511 }
00512 } else {
00513 if (dhtMsg->getIsHash()) {
00514 std::map<BinaryValue, ReplicaVector>::iterator itHashes =
00515 it2->second.hashes.find(dhtMsg->getHashValue());
00516
00517 if (itHashes == it2->second.hashes.end()) {
00518
00519 ReplicaVector vect = ReplicaVector();
00520 vect.push_back(dhtMsg->getSrcNode());
00521 it2->second.hashes.insert(make_pair(dhtMsg->getHashValue(),
00522 vect));
00523 } else {
00524 itHashes->second.push_back(dhtMsg->getSrcNode());
00525 }
00526
00527 it2->second.numResponses++;
00528
00529
00530 unsigned int maxCount = 0;
00531 ReplicaVector* hashVector = NULL;
00532 for (itHashes = it2->second.hashes.begin(); itHashes
00533 != it2->second.hashes.end(); itHashes++) {
00534 if (itHashes->second.size() > maxCount) {
00535 maxCount = itHashes->second.size();
00536 hashVector = &(itHashes->second);
00537 }
00538 }
00539
00540 if ((double) maxCount / (double) it2->second.numAvailableReplica
00541 >= ratioIdentical) {
00542 it2->second.hashVector = hashVector;
00543 } else if (it2->second.numResponses >= numGetRequests){
00544
00545 if (it2->second.replica.size() > 0) {
00546 DHTGetCall* getCall = new DHTGetCall();
00547 getCall->setKey(dhtMsg->getKey());
00548 getCall->setKind(dhtMsg->getKind());
00549 getCall->setId(dhtMsg->getId());
00550 getCall->setIsHash(true);
00551 getCall->setBitLength(GETCALL_L(getCall));
00552 RECORD_STATS(normalMessages++;
00553 numBytesNormal += getCall->getByteLength());
00554 sendRouteRpcCall(TIER1_COMP,
00555 it2->second.replica.back(), getCall,
00556 NULL, DEFAULT_ROUTING, -1, 0,
00557 it2->second.callMsg->getNonce());
00558 it2->second.replica.pop_back();
00559 } else {
00560 DHTgetCAPIResponse* capiGetRespMsg =
00561 new DHTgetCAPIResponse();
00562 DhtDumpEntry result;
00563 result.setKey(dhtMsg->getKey());
00564 result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00565 capiGetRespMsg->setResultArraySize(1);
00566 capiGetRespMsg->setResult(0, result);
00567 capiGetRespMsg->setIsSuccess(false);
00568 sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00569
00570 getMap.erase(rpcId);
00571 return;
00572 }
00573
00574 }
00575 }
00576 }
00577
00578 if (it2->second.hashVector != NULL) {
00579
00580 if (it2->second.hashVector->size() > 0) {
00581 DHTGetCall* getCall = new DHTGetCall();
00582 getCall->setKey(it2->second.callMsg->getKey());
00583 getCall->setKind(it2->second.callMsg->getKind());
00584 getCall->setId(it2->second.callMsg->getId());
00585 getCall->setIsHash(false);
00586 getCall->setBitLength(GETCALL_L(getCall));
00587 RECORD_STATS(normalMessages++;
00588 numBytesNormal += getCall->getByteLength());
00589 int nonce = sendRouteRpcCall(TIER1_COMP,
00590 it2->second.hashVector->back(),
00591 getCall, NULL, DEFAULT_ROUTING,
00592 -1, 0, it2->second.callMsg->getNonce());
00593 rpcIdMap.insert(make_pair(nonce, (BaseCallMessage*)NULL));
00594 it2->second.hashVector->pop_back();
00595 } else {
00596 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00597 DhtDumpEntry result;
00598 result.setKey(dhtMsg->getKey());
00599 result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00600 capiGetRespMsg->setResultArraySize(1);
00601 capiGetRespMsg->setResult(0, result);
00602 capiGetRespMsg->setIsSuccess(false);
00603 sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00604
00605 getMap.erase(rpcId);
00606 }
00607 }
00608 }
00609
00610 void DHT::update(const NodeHandle& node, bool joined)
00611 {
00612 OverlayKey key;
00613 DHTPutCall* dhtMsg;
00614 bool err = false;
00615 DhtDataEntry entry;
00616 std::map<OverlayKey, DhtDataEntry>::iterator it = dataStorage->begin();
00617 for (unsigned int i = 0; i < dataStorage->getSize(); i++) {
00618 key = it->first;
00619 entry = it->second;
00620 if (joined) {
00621 if (entry.responsible && (overlay->isSiblingFor(node, key,
00622 numReplica, &err)
00623 || err)) {
00624
00625 dhtMsg = new DHTPutCall();
00626 dhtMsg->setKey(key);
00627 dhtMsg->setKind(entry.kind);
00628 dhtMsg->setId(entry.id);
00629 dhtMsg->setValue(entry.value);
00630 dhtMsg->setTtl((int)SIMTIME_DBL(entry.ttlMessage->getArrivalTime()
00631 - simTime()));
00632 dhtMsg->setIsModifiable(entry.is_modifiable);
00633 dhtMsg->setMaintenance(true);
00634 dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00635 RECORD_STATS(maintenanceMessages++;
00636 numBytesMaintenance += dhtMsg->getByteLength());
00637 sendRouteRpcCall(TIER1_COMP, node, dhtMsg);
00638 }
00639
00640 if (err) {
00641 EV << "[DHT::update()]\n"
00642 << " Unable to know if key: " << key
00643 << " is in range of node: " << node
00644 << endl;
00645 }
00646 } else {
00647 #if 0
00648
00649
00650 LookupCall* replicaMsg = new LookupCall();
00651 replicaMsg->setKey(key);
00652 replicaMsg->setNumSiblings(numReplica);
00653 int nonce = sendInternalRpcCall(OVERLAY_COMP,
00654 replicaMsg);
00655 dhtMsg = new DHTPutCall();
00656 dhtMsg->setKey(key);
00657 dhtMsg->setValue(entry.value);
00658 dhtMsg->setTtl((int)(entry.ttlMessage->getArrivalTime()
00659 - simTime()));
00660 dhtMsg->setIsModifiable(entry.is_modifiable);
00661 dhtMsg->setMaintenance(true);
00662 dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00663
00664 rpcIdMap.insert(make_pair(nonce, dhtMsg));
00665 #endif
00666 }
00667
00668 entry.responsible = overlay->isSiblingFor(overlay->getThisNode(),
00669 key, 1, &err);
00670 it++;
00671 }
00672 }
00673
00674 void DHT::handleLookupResponse(LookupResponse* lookupMsg)
00675 {
00676 std::map<unsigned int, BaseCallMessage*>::iterator it =
00677 rpcIdMap.find(lookupMsg->getNonce());
00678
00679 if (it == rpcIdMap.end() || it->second == NULL)
00680 return;
00681
00682 if (dynamic_cast<DHTputCAPICall*> (it->second)) {
00683
00684 #if 0
00685 cout << "DHT::handleLookupResponse(): PUT "
00686 << lookupMsg->getKey() << " ("
00687 << overlay->getThisNode().getKey() << ")" << endl;
00688
00689 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00690 cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00691 }
00692 #endif
00693
00694 DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*> (it->second);
00695 rpcIdMap.erase(lookupMsg->getNonce());
00696
00697 if ((lookupMsg->getIsValid() == false)
00698 || (lookupMsg->getSiblingsArraySize() == 0)) {
00699
00700 EV << "[DHT::handleLookupResponse()]\n"
00701 << " Unable to get replica list : invalid lookup"
00702 << endl;
00703 DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00704 capiPutRespMsg->setKey(lookupMsg->getKey());
00705 capiPutRespMsg->setIsSuccess(false);
00706
00707 sendRpcResponse(capiPutMsg, capiPutRespMsg);
00708 return;
00709 }
00710
00711 if ((capiPutMsg->getId() == 0) && (capiPutMsg->getValue().size() > 0)) {
00712
00713
00714 capiPutMsg->setId(intuniform(1, 2147483647));
00715 }
00716
00717 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00718 DHTPutCall* dhtMsg = new DHTPutCall();
00719 dhtMsg->setKey(capiPutMsg->getKey());
00720 dhtMsg->setKind(capiPutMsg->getKind());
00721 dhtMsg->setId(capiPutMsg->getId());
00722 dhtMsg->setValue(capiPutMsg->getValue());
00723 dhtMsg->setTtl(capiPutMsg->getTtl());
00724 dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00725 dhtMsg->setMaintenance(false);
00726 dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00727 RECORD_STATS(normalMessages++;
00728 numBytesNormal += dhtMsg->getByteLength());
00729 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00730 dhtMsg, NULL, DEFAULT_ROUTING, -1,
00731 0, capiPutMsg->getNonce());
00732 }
00733
00734 PutMapEntry mapEntry;
00735 mapEntry.callMsg = capiPutMsg;
00736 mapEntry.numResponses = 0;
00737 mapEntry.numFailed = 0;
00738 mapEntry.numSent = lookupMsg->getSiblingsArraySize();
00739
00740 putMap.insert(make_pair(capiPutMsg->getNonce(), mapEntry));
00741 }
00742 else if (dynamic_cast<DHTgetCAPICall*>(it->second)) {
00743
00744 #if 0
00745 cout << "DHT::handleLookupResponse(): GET "
00746 << lookupMsg->getKey() << " ("
00747 << overlay->getThisNode().getKey() << ")" << endl;
00748
00749 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00750 cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00751 }
00752 #endif
00753
00754 DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second);
00755 rpcIdMap.erase(lookupMsg->getNonce());
00756
00757 if ((lookupMsg->getIsValid() == false)
00758 || (lookupMsg->getSiblingsArraySize() == 0)) {
00759
00760 EV << "[DHT::handleLookupResponse()]\n"
00761 << " Unable to get replica list : invalid lookup"
00762 << endl;
00763 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00764 DhtDumpEntry result;
00765 result.setKey(lookupMsg->getKey());
00766 result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00767 capiGetRespMsg->setResultArraySize(1);
00768 capiGetRespMsg->setResult(0, result);
00769 capiGetRespMsg->setIsSuccess(false);
00770
00771 sendRpcResponse(capiGetMsg, capiGetRespMsg);
00772 return;
00773 }
00774
00775 GetMapEntry mapEntry;
00776 mapEntry.numSent = 0;
00777
00778 for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00779 if (i < (unsigned int)numGetRequests) {
00780 DHTGetCall* dhtMsg = new DHTGetCall();
00781 dhtMsg->setKey(capiGetMsg->getKey());
00782 dhtMsg->setKind(capiGetMsg->getKind());
00783 dhtMsg->setId(capiGetMsg->getId());
00784 dhtMsg->setIsHash(true);
00785 dhtMsg->setBitLength(GETCALL_L(dhtMsg));
00786 RECORD_STATS(normalMessages++;
00787 numBytesNormal += dhtMsg->getByteLength());
00788 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i), dhtMsg,
00789 NULL, DEFAULT_ROUTING, -1, 0,
00790 capiGetMsg->getNonce());
00791 mapEntry.numSent++;
00792 } else {
00793
00794 mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00795 }
00796 }
00797
00798 mapEntry.numAvailableReplica = lookupMsg->getSiblingsArraySize();
00799 mapEntry.callMsg = capiGetMsg;
00800 mapEntry.numResponses = 0;
00801 mapEntry.hashVector = NULL;
00802
00803 getMap.insert(make_pair(capiGetMsg->getNonce(), mapEntry));
00804 }
00805 else if (dynamic_cast<DHTPutCall*>(it->second)) {
00806 DHTPutCall* putMsg = dynamic_cast<DHTPutCall*>(it->second);
00807 rpcIdMap.erase(lookupMsg->getNonce());
00808
00809 if ((lookupMsg->getIsValid() == false)
00810 || (lookupMsg->getSiblingsArraySize() == 0)) {
00811
00812 EV << "[DHT::handleLookupResponse()]\n"
00813 << " Unable to get replica list : invalid lookup"
00814 << endl;
00815 delete putMsg;
00816 return;
00817 }
00818
00819 for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00820 RECORD_STATS(maintenanceMessages++;
00821 numBytesMaintenance += putMsg->getByteLength());
00822
00823 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00824 new DHTPutCall(*putMsg));
00825 }
00826
00827 delete putMsg;
00828 }
00829 }
00830
00831 void DHT::finishApp()
00832 {
00833 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00834
00835 if (time >= GlobalStatistics::MIN_MEASURED) {
00836 globalStatistics->addStdDev("DHT: Sent Maintenance Messages/s",
00837 maintenanceMessages / time);
00838 globalStatistics->addStdDev("DHT: Sent Normal Messages/s",
00839 normalMessages / time);
00840 globalStatistics->addStdDev("DHT: Sent Maintenance Bytes/s",
00841 numBytesMaintenance / time);
00842 globalStatistics->addStdDev("DHT: Sent Normal Bytes/s",
00843 numBytesNormal / time);
00844 }
00845 }
00846
00847 int DHT::resultValuesBitLength(DHTGetResponse* msg) {
00848 int bitSize = 0;
00849 for (uint i = 0; i < msg->getResultArraySize(); i++) {
00850 bitSize += msg->getResult(i).getValue().size();
00851
00852 }
00853 return bitSize;
00854 }
00855