DHT.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2007 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     // delegate messages
00121     RPC_SWITCH_START( msg )
00122         // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00123         RPC_DELEGATE( DHTPut, handlePutRequest );
00124         RPC_DELEGATE( DHTGet, handleGetRequest );
00125         RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests coming from an upper tier
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()) //unknown request
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             //cout << "timeout 1" << endl;
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()) { //unknown request
00206             return;
00207         }
00208 
00209         if (it != rpcIdMap.end()) {
00210             //we have sent a 'real' get request
00211             rpcIdMap.erase(_DHTGetCall->getNonce());
00212             //ask anyone else, if possible
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                 // no one else
00234                 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00235                 capiGetRespMsg->setIsSuccess(false);
00236                 sendRpcResponse(it2->second.callMsg,
00237                                 capiGetRespMsg);
00238                 //cout << "DHT: GET failed: no one else" << endl;
00239                 getMap.erase(rpcId);
00240                 return;
00241             }
00242 
00243         } else {
00244             //try to ask another one of the replica list for the hash
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                 // no one else to ask, see what we can do with what we have
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                     //cout << "DHT: GET failed: timeout (no one else)" << endl;
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         // check if the put request came from the right node
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             // TODO: set owner
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     // remove data item from local data storage
00342     dataStorage->removeData(dhtMsg->getKey(), dhtMsg->getKind(),
00343                             dhtMsg->getId());
00344 
00345     if (dhtMsg->getValue().size() > 0) {
00346         // add ttl timer
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         // storage data item in local data storage
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     // send back
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     // send back
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             // TODO: verify this
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     //asks the replica list
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()) //unknown request
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()) //unknown request
00495         return;
00496 
00497     if (it != rpcIdMap.end()) {
00498         //we have sent a 'real' get request
00499         rpcIdMap.erase(dhtMsg->getNonce());
00500         if (!dhtMsg->getIsHash()) {
00501             // TODO verify hash
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                 //new hash
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             //we've got all the answers we wanted
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                 //we'll try to ask some other nodes
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 { //we don't have anyone else to ask
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                     //cout << "DHT: GET failed: hash (no one else)" << endl;
00570                     getMap.erase(rpcId);
00571                     return;
00572                 }
00573 
00574             }
00575         }
00576     }
00577 
00578     if (it2->second.hashVector != NULL) {
00579         //we have already received all the response and chosen a hash
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 { //we don't have anyone else to ask
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             //cout << "DHT: GET failed: hash2 (no one else)" << endl;
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)) { // hack for Chord, if we've got a new predecessor
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             //the update concerns a node who has left
00649             //replicate
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             //cout << "DHT::lookup failed" << endl;
00707             sendRpcResponse(capiPutMsg, capiPutRespMsg);
00708             return;
00709         }
00710 
00711         if ((capiPutMsg->getId() == 0) && (capiPutMsg->getValue().size() > 0)) {
00712             // pick a random id before replication of the data item
00713             // id 0 is kept for delete requests (i.e. size = 0)
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             //cout << "DHT: lookup failed 2" << endl;
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                 //We don't send, we just store the remaining keys
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 

Generated on Tue Sep 8 17:26:52 2009 for OverSim by  doxygen 1.5.8