CBR-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 "CBR-DHT.h"
00027 
00028 #include <RpcMacros.h>
00029 #include <BaseRpc.h>
00030 #include <GlobalStatistics.h>
00031 #include <CoordBasedRoutingAccess.h>
00032 #include <NeighborCache.h>
00033 
00034 Define_Module(CBRDHT);
00035 
00036 using namespace std;
00037 
00038 CBRDHT::CBRDHT()
00039 {
00040     dataStorage = NULL;
00041 }
00042 
00043 CBRDHT::~CBRDHT()
00044 {
00045     std::map<unsigned int, BaseCallMessage*>::iterator it;
00046 
00047     for (it = rpcIdMap.begin(); it != rpcIdMap.end(); it++) {
00048         delete it->second;
00049         it->second = NULL;
00050     }
00051 
00052     std::map<int, GetMapEntry>::iterator it2;
00053     for (it2 = getMap.begin(); it2 != getMap.end(); it2++) {
00054         //cancelAndDelete(it2->second.callMsg);
00055         delete it2->second.callMsg;
00056         it2->second.callMsg = NULL;
00057     }
00058 
00059     std::map<int, PutMapEntry>::iterator it3;
00060 
00061     for (it3 = putMap.begin(); it3 != putMap.end(); it3++) {
00062         //if (it3->second.callMsg != NULL) {
00063         //    cancelAndDelete(it3->second.callMsg);
00064         //}
00065         delete it3->second.callMsg;
00066         it3->second.callMsg = NULL;
00067     }
00068 
00069     rpcIdMap.clear();
00070     getMap.clear();
00071     putMap.clear();
00072 
00073     if (dataStorage != NULL) {
00074         dataStorage->clear();
00075     }
00076 }
00077 
00078 void CBRDHT::initializeApp(int stage)
00079 {
00080         if (stage != MIN_STAGE_APP)
00081         return;
00082 
00083     dataStorage = check_and_cast<DHTDataStorage*>
00084                       (getParentModule()->getSubmodule("dhtDataStorage"));
00085 
00086     coordBasedRouting = CoordBasedRoutingAccess().get();
00087     neighborCache = (NeighborCache*)getParentModule()
00088         ->getParentModule()->getSubmodule("neighborCache");
00089 
00090     numReplica = par("numReplica");
00091     numReplicaTeams = par("numReplicaTeams");
00092 
00093     if (numReplica > numReplicaTeams * overlay->getMaxNumSiblings()) {
00094         opp_error("DHT::initialize(): numReplica bigger than what this "
00095                   "overlay can handle (%d)", numReplicaTeams*overlay->getMaxNumSiblings());
00096     }
00097 
00098     maintenanceMessages = 0;
00099     normalMessages = 0;
00100     numBytesMaintenance = 0;
00101     numBytesNormal = 0;
00102     WATCH(maintenanceMessages);
00103     WATCH(normalMessages);
00104     WATCH(numBytesNormal);
00105     WATCH(numBytesMaintenance);
00106     WATCH_MAP(rpcIdMap);
00107 }
00108 
00109 void CBRDHT::handleTimerEvent(cMessage* msg)
00110 {
00111     DHTTtlTimer* msg_timer = dynamic_cast<DHTTtlTimer*> (msg);
00112 
00113     if (msg_timer) {
00114         EV << "[DHT::handleTimerEvent()]\n"
00115            << "    received timer ttl, key: "
00116            << msg_timer->getKey().toString(16)
00117            << "\n (overlay->getThisNode().key = "
00118            << overlay->getThisNode().getKey().toString(16) << ")"
00119            << endl;
00120 
00121         dataStorage->removeData(msg_timer->getKey(), msg_timer->getKind(),
00122                                 msg_timer->getId());
00123         //delete msg_timer;
00124     }
00125     /*DHTTtlTimer* msg_timer;
00126 
00127     if (msg->isName("ttl_timer")) {
00128         msg_timer = check_and_cast<DHTTtlTimer*> (msg);
00129 
00130         EV << "[DHT::handleTimerEvent()]\n"
00131            << "    received timer ttl, key: "
00132            << msg_timer->getKey().toString(16)
00133            << "\n (overlay->getThisNode().key = "
00134            << overlay->getThisNode().getKey().toString(16) << ")"
00135            << endl;
00136 
00137         dataStorage->removeData(msg_timer->getKey(), msg_timer->getKind(),
00138                                 msg_timer->getId());
00139         delete msg_timer;
00140     }*/
00141 }
00142 
00143 bool CBRDHT::handleRpcCall(BaseCallMessage* msg)
00144 {
00145     // delegate messages
00146     RPC_SWITCH_START( msg )
00147         // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00148         RPC_DELEGATE( DHTPut, handlePutRequest );
00149         RPC_DELEGATE( CBRDHTGet, handleGetRequest );
00150         RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests coming from an upper tier
00151         RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest );
00152         RPC_DELEGATE( DHTdump, handleDumpDhtRequest );
00153     RPC_SWITCH_END( )
00154 
00155     return RPC_HANDLED;
00156 }
00157 
00158 void CBRDHT::handleRpcResponse(BaseResponseMessage* msg, cPolymorphic* context,
00159                             int rpcId, simtime_t rtt)
00160 {
00161     RPC_SWITCH_START(msg)
00162         RPC_ON_RESPONSE(DHTPut){
00163         handlePutResponse(_DHTPutResponse, rpcId);
00164         EV << "[DHT::handleRpcResponse()]\n"
00165            << "    DHT Put RPC Response received: id=" << rpcId
00166            << " msg=" << *_DHTPutResponse << " rtt=" << rtt
00167            << endl;
00168         break;
00169     }
00170     RPC_ON_RESPONSE(CBRDHTGet) {
00171         handleGetResponse(_CBRDHTGetResponse, rpcId);
00172         EV << "[DHT::handleRpcResponse()]\n"
00173            << "    DHT Get RPC Response received: id=" << rpcId
00174            << " msg=" << *_CBRDHTGetResponse << " rtt=" << rtt
00175            << endl;
00176         break;
00177     }
00178     RPC_ON_RESPONSE(Lookup) {
00179         handleLookupResponse(_LookupResponse);
00180         EV << "[DHT::handleRpcResponse()]\n"
00181            << "    Replica Set RPC Response received: id=" << rpcId
00182            << " msg=" << *_LookupResponse << " rtt=" << rtt
00183            << endl;
00184         break;
00185     }
00186     RPC_SWITCH_END()
00187 }
00188 
00189 void CBRDHT::handleRpcTimeout(BaseCallMessage* msg, const TransportAddress& dest,
00190                            cPolymorphic* context, int rpcId,
00191                            const OverlayKey& destKey)
00192 {
00193     RPC_SWITCH_START(msg)
00194     RPC_ON_CALL(DHTPut){
00195         EV << "[DHT::handleRpcResponse()]\n"
00196            << "    DHTPut Timeout"
00197            << endl;
00198 
00199         std::map<int, PutMapEntry>::iterator it2 =
00200                 putMap.find(rpcId);
00201 
00202         if (it2 == putMap.end()) //unknown request
00203             return;
00204 
00205         it2->second.numFailed++;
00206 
00207         if (it2->second.numFailed / (double)it2->second.numSent >= 0.5) {
00208             DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00209             capiPutRespMsg->setIsSuccess(false);
00210             sendRpcResponse(it2->second.callMsg, capiPutRespMsg);
00211             it2->second.callMsg = NULL;
00212             putMap.erase(rpcId);
00213         }
00214         break;
00215     }
00216     RPC_ON_CALL(CBRDHTGet) {
00217         EV << "[DHT::handleRpcResponse()]\n"
00218            << "    DHTGet Timeout"
00219            << endl;
00220 
00221         std::map<int, GetMapEntry>::iterator it2 =
00222             getMap.find(rpcId);
00223 
00224         if (it2 == getMap.end()) //unknown request
00225             return;
00226 
00227         if (it2->second.replica.size() > 0) {
00228             // Received empty value, try fallback replica
00229             NodeHandle fallbackReplica = it2->second.replica.back();
00230             CBRDHTGetCall* dhtRecall = new CBRDHTGetCall();
00231             dhtRecall->setOriginalKey(_CBRDHTGetCall->getOriginalKey());
00232             dhtRecall->setKey(_CBRDHTGetCall->getKey());
00233             dhtRecall->setIsHash(false);
00234             dhtRecall->setBitLength(GETCALL_L(dhtRecall));
00235             RECORD_STATS(normalMessages++;
00236             numBytesNormal += dhtRecall->getByteLength());
00237             sendRouteRpcCall(TIER1_COMP, fallbackReplica, dhtRecall,
00238                              NULL, DEFAULT_ROUTING, -1, 0,
00239                              it2->second.callMsg->getNonce());
00240             it2->second.numSent++;
00241             it2->second.replica.pop_back();
00242             return;
00243         } else if (it2->second.teamNumber < (numReplicaTeams - 1)) {
00244             // No more fallback replica in this team, try next one
00245             it2->second.teamNumber++;
00246             handleGetCAPIRequest(it2->second.callMsg, it2->second.teamNumber);
00247             return;
00248         } else {
00249             // No more replica, no more teams, send success == false to Tier 2 :(
00250             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00251             //capiGetRespMsg->setKey(_CBRDHTGetCall->getOriginalKey());
00252             //capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00253             DhtDumpEntry result;
00254             result.setKey(_CBRDHTGetCall->getKey());
00255             result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00256             capiGetRespMsg->setResultArraySize(1);
00257             capiGetRespMsg->setResult(0, result);
00258             capiGetRespMsg->setIsSuccess(false);
00259             sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00260             getMap.erase(rpcId);
00261         }
00262         break;
00263     }
00264     RPC_SWITCH_END( )
00265 }
00266 
00267 void CBRDHT::handleUpperMessage(cMessage* msg)
00268 {
00269     error("DHT::handleUpperMessage(): Received message with unknown type!");
00270 
00271     delete msg;
00272 }
00273 
00274 void CBRDHT::handlePutRequest(DHTPutCall* dhtMsg)
00275 {
00276     std::string tempString = "PUT_REQUEST received: "
00277             + std::string(dhtMsg->getKey().toString(16));
00278     getParentModule()->getParentModule()->bubble(tempString.c_str());
00279 
00280     if (!(dataStorage->isModifiable(dhtMsg->getKey(), dhtMsg->getKind(),
00281                                     dhtMsg->getId()))) {
00282         //check if the put request came from the right node
00283         NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey(),
00284                                                            dhtMsg->getKind(), dhtMsg->getId());
00285         if (((!sourceNode.isUnspecified())
00286                 && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode
00287                 != dhtMsg->getSrcNode())) || ((dhtMsg->getMaintenance())
00288                 && (dhtMsg->getOwnerNode() == sourceNode))) {
00289             // TODO: set owner
00290             DHTPutResponse* responseMsg = new DHTPutResponse();
00291             responseMsg->setSuccess(false);
00292             responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00293             RECORD_STATS(normalMessages++;
00294                          numBytesNormal += responseMsg->getByteLength());
00295             sendRpcResponse(dhtMsg, responseMsg);
00296             return;
00297         }
00298 
00299     }
00300 
00301     // remove data item from local data storage
00302     //cancelAndDelete(dataStorage->getTtlMessage(dhtMsg->getKey()));
00303     //dataStorage->removeData(dhtMsg->getKey());
00304     dataStorage->removeData(dhtMsg->getKey(), dhtMsg->getKind(),
00305                                 dhtMsg->getId());
00306     if (dhtMsg->getValue().size() > 0) {
00307         // add ttl timer
00308         DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00309         timerMsg->setKey(dhtMsg->getKey());
00310         scheduleAt(simTime() + dhtMsg->getTtl(), timerMsg);
00311         // storage data item in local data storage
00312         bool err;
00313         dataStorage->addData(dhtMsg->getKey(), dhtMsg->getKind(),
00314                              dhtMsg->getId(), dhtMsg->getValue(), timerMsg,
00315                              dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(),
00316                              overlay->isSiblingFor(overlay->getThisNode(),
00317                                                    dhtMsg->getKey(),
00318                                                    1, &err));
00319     }
00320 
00321     // send back
00322     DHTPutResponse* responseMsg = new DHTPutResponse();
00323 
00324     responseMsg->setSuccess(true);
00325     responseMsg->setBitLength(PUTRESPONSE_L(responseMsg));
00326     RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->getByteLength());
00327 
00328     sendRpcResponse(dhtMsg, responseMsg);
00329 }
00330 
00331 void CBRDHT::handleGetRequest(CBRDHTGetCall* dhtMsg)
00332 {
00333     std::string tempString = "GET_REQUEST received: "
00334             + std::string(dhtMsg->getKey().toString(16));
00335 
00336     getParentModule()->getParentModule()->bubble(tempString.c_str());
00337 
00338     BinaryValue storedValue;
00339     DhtDataEntry* dataEntry = dataStorage->getDataEntry(dhtMsg->getKey(), 1, 1);
00340     if (dataEntry) {
00341         storedValue = dataStorage->getDataEntry(dhtMsg->getKey(), 1, 1)->value;
00342     } else {
00343         storedValue = BinaryValue::UNSPECIFIED_VALUE;
00344     }
00345 
00346     // send back
00347     CBRDHTGetResponse* responseMsg = new CBRDHTGetResponse();
00348 
00349     responseMsg->setKey(dhtMsg->getKey());
00350     responseMsg->setOriginalKey(dhtMsg->getOriginalKey());
00351     responseMsg->setIsHash(false);
00352     if (storedValue.isUnspecified()) {
00353         //responseMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00354         DhtDumpEntry result;
00355         result.setKey(dhtMsg->getKey());
00356         result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00357         responseMsg->setResultArraySize(1);
00358         responseMsg->setResult(0, result);
00359     } else {
00360         //responseMsg->setValue(storedValue);
00361         DhtDumpEntry result;
00362         result.setKey(dhtMsg->getKey());
00363         result.setValue(storedValue);
00364         responseMsg->setResultArraySize(1);
00365         responseMsg->setResult(0, result);
00366     }
00367     rpcIdMap.insert(make_pair(dhtMsg->getNonce(), (BaseCallMessage*)NULL));
00368 
00369     responseMsg->setBitLength(GETRESPONSE_L(responseMsg));
00370     RECORD_STATS(normalMessages++;
00371                  numBytesNormal += responseMsg->getByteLength());
00372     sendRpcResponse(dhtMsg, responseMsg);
00373 }
00374 
00375 void CBRDHT::handlePutCAPIRequest(DHTputCAPICall* capiPutMsg)
00376 {
00377     // provide copies of this message for other teams
00378     for (int i = 1; i < numReplicaTeams; i++) {
00379         DHTPutCall* teamCopyPutMsg = new DHTPutCall; //TODO memleak
00380 
00381         // transfer attributes of original DHTputCAPICall to DHTPutCall for teams
00382         teamCopyPutMsg->setValue(capiPutMsg->getValue());
00383         teamCopyPutMsg->setTtl(capiPutMsg->getTtl());
00384         teamCopyPutMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00385         teamCopyPutMsg->setKind(capiPutMsg->getKind());
00386         teamCopyPutMsg->setId(capiPutMsg->getId());
00387 
00388         // control info needs to be copied by value
00389         OverlayCtrlInfo controlInfo = *(check_and_cast<OverlayCtrlInfo*>(capiPutMsg->getControlInfo()));
00390         OverlayCtrlInfo* controlInfoCopy = new OverlayCtrlInfo;
00391         *controlInfoCopy = controlInfo;
00392         teamCopyPutMsg->setControlInfo(controlInfoCopy);
00393 
00394         // multiple SHA1 hashing of original key
00395         OverlayKey destKey = capiPutMsg->getKey();
00396         for (int j = 0; j < i; j++) {
00397             destKey = OverlayKey::sha1(BinaryValue(destKey.toString(16).c_str()));
00398         }
00399         teamCopyPutMsg->setKey(destKey);
00400 
00401         // rest is analog to handlePutCAPIRequest, but for DHTPutCall
00402         LookupCall* replicaMsg = new LookupCall();
00403         replicaMsg->setKey(teamCopyPutMsg->getKey());
00404         replicaMsg->setNumSiblings(floor(numReplica / numReplicaTeams));
00405         int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00406         rpcIdMap.insert(make_pair(nonce, teamCopyPutMsg));
00407     }
00408 
00409     //asks the replica list
00410     LookupCall* replicaMsg = new LookupCall();
00411     replicaMsg->setKey(capiPutMsg->getKey());
00412     replicaMsg->setNumSiblings(floor(numReplica / numReplicaTeams));
00413     int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00414     rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00415 }
00416 
00417 void CBRDHT::handleGetCAPIRequest(DHTgetCAPICall* capiGetMsg, int teamnum) {
00418     // Extended multi team version, default: teamnum = 0
00419         if (teamnum >= numReplicaTeams)
00420                 return;
00421 
00422         OverlayKey originalKey = capiGetMsg->getKey();
00423         std::vector<OverlayKey> possibleKeys;
00424 
00425         assert(!originalKey.isUnspecified());
00426         possibleKeys.push_back(originalKey);
00427 
00428         for (int i = 1; i < numReplicaTeams; i++) {
00429                 // multiple SHA1 hashing of original key
00430                 OverlayKey keyHash = originalKey;
00431                 for (int j = 0; j < i; j++) {
00432                         keyHash = OverlayKey::sha1(BinaryValue(keyHash.toString(16).c_str()));
00433                 }
00434                 assert(!keyHash.isUnspecified());
00435                 possibleKeys.push_back(keyHash);
00436         }
00437 
00438     // Order possible keys by euclidian distance to this node
00439     std::vector<OverlayKey> orderedKeys;
00440     OverlayKey compareKey = overlay->getThisNode().getKey();
00441 
00442     while (possibleKeys.size() > 0) {
00443         OverlayKey bestKey = possibleKeys[0];
00444         int bestpos = 0;
00445 
00446         // TODO: i = 1?
00447         for (uint i = 0; i < possibleKeys.size(); i++) {
00448             //std::cout << neighborCache->getOwnEuclidianDistanceToKey(possibleKeys[i]) << std::endl;
00449             if (coordBasedRouting
00450                     ->getEuclidianDistanceByKeyAndCoords(possibleKeys[i],
00451                                                          ((const Nps&)neighborCache->getNcsAccess()).getOwnCoordinates(), //TODO
00452                                                          overlay->getBitsPerDigit()) <
00453                 coordBasedRouting
00454                     ->getEuclidianDistanceByKeyAndCoords(bestKey,
00455                                                          ((const Nps&)neighborCache->getNcsAccess()).getOwnCoordinates(), //TODO
00456                                                          overlay->getBitsPerDigit())) {
00457                 bestKey = possibleKeys[i];
00458                 bestpos = i;
00459             }
00460         }
00461         //std::cout << neighborCache->getOwnEuclidianDistanceToKey(bestKey) << "\n" << std::endl;
00462         orderedKeys.push_back(bestKey);
00463         possibleKeys.erase(possibleKeys.begin()+bestpos);
00464     }
00465 
00466     /*
00467     std::cout << "NodeID: " << overlay->getThisNode().getKey().toString(16) << std::endl;
00468     std::cout << "Original Key: " << originalKey.toString(16) << std::endl;
00469     for (int i = 0; i < orderedKeys.size(); i++) {
00470         std::cout << "Sorted Key " << i << ": " << orderedKeys[i].toString(16) << " (" << overlay->getOwnEuclidianDistanceToKey(orderedKeys[i]) << ")" << std::endl;
00471     }
00472     */
00473 
00474     OverlayKey searchKey = orderedKeys[teamnum];
00475 
00476 #define DIRECT_ROUTE_GET
00477 #ifndef DIRECT_ROUTE_GET
00478 
00479     LookupCall* replicaMsg = new LookupCall();
00480     replicaMsg->setKey(searchKey);
00481     replicaMsg->setNumSiblings(floor(numReplica / numReplicaTeams));
00482     int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00483     rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00484     lastGetCall = SIMTIME_DBL(simTime());
00485 
00486 #else
00487 
00488     GetMapEntry mapEntry;
00489     mapEntry.numSent = 0;
00490 
00491     // Multi team version: Already mapEntry from earlier team?
00492     std::map<int, GetMapEntry>::iterator it2 =
00493         getMap.find(capiGetMsg->getNonce());
00494 
00495     if (it2 != getMap.end()) {
00496         mapEntry = it2->second;
00497     } else {
00498         mapEntry.teamNumber = 0;
00499     }
00500     mapEntry.numAvailableReplica = 1;//lookupMsg->getSiblingsArraySize();
00501     mapEntry.numResponses = 0;
00502     mapEntry.callMsg = capiGetMsg;
00503     mapEntry.hashVector = NULL;
00504     mapEntry.replica.clear();
00505     for (unsigned int i = 0; i < 1/*lookupMsg->getSiblingsArraySize()*/; i++) {
00506         // Simplified GET Request: Just one real request, rest is for fallback
00507         if (i == 0) {
00508             CBRDHTGetCall* dhtMsg = new CBRDHTGetCall();
00509 
00510             dhtMsg->setOriginalKey(capiGetMsg->getKey());
00511             dhtMsg->setKey(searchKey);//lookupMsg->getKey());
00512 
00513             dhtMsg->setIsHash(false);
00514             dhtMsg->setKind(capiGetMsg->getKind());
00515             dhtMsg->setId(capiGetMsg->getId());
00516             dhtMsg->setBitLength(GETCALL_L(dhtMsg));
00517             RECORD_STATS(normalMessages++;
00518             numBytesNormal += dhtMsg->getByteLength());
00519 
00520             /*int nonce = */sendRouteRpcCall(TIER1_COMP, searchKey, dhtMsg,
00521                                          NULL, DEFAULT_ROUTING, -1, 0,
00522                                          capiGetMsg->getNonce());
00523 
00524             //rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00525             //sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i), dhtMsg,
00526             //                 NULL, DEFAULT_ROUTING, -1, 0,
00527             //                 capiGetMsg->getNonce());
00528             mapEntry.numSent++;
00529         } else {
00530             //We don't send, we just store the remaining keys as fallback
00531             //mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00532         }
00533     }
00534     /*
00535                 std::cout << "New replica: " <<  std::endl;
00536                 for (int i = 0; i < mapEntry.replica.size(); i++) {
00537                     std::cout << mapEntry.replica[i] << std::endl;
00538                 }
00539                 std::cout << "*************************" << std::endl;
00540      */
00541     if (it2 != getMap.end())
00542         getMap.erase(it2);
00543     getMap.insert(make_pair(capiGetMsg->getNonce(), mapEntry));
00544 #endif
00545 }
00546 
00547 void CBRDHT::handleDumpDhtRequest(DHTdumpCall* call)
00548 {
00549     DHTdumpResponse* response = new DHTdumpResponse();
00550     DhtDumpVector* dumpVector = dataStorage->dumpDht();
00551 
00552     response->setRecordArraySize(dumpVector->size());
00553 
00554     for (uint i = 0; i < dumpVector->size(); i++) {
00555         response->setRecord(i, (*dumpVector)[i]);
00556     }
00557 
00558     delete dumpVector;
00559 
00560     sendRpcResponse(call, response);
00561 }
00562 
00563 void CBRDHT::handlePutResponse(DHTPutResponse* dhtMsg, int rpcId)
00564 {
00565     std::map<int, PutMapEntry>::iterator it2 =
00566             putMap.find(rpcId);
00567 
00568     if (it2 == putMap.end()) //unknown request
00569         return;
00570 
00571     if (dhtMsg->getSuccess()) {
00572         it2->second.numResponses++;
00573     } else {
00574         it2->second.numFailed++;
00575     }
00576 
00577     if (it2->second.numResponses / (double)it2->second.numSent > 0.5) {
00578         DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00579         capiPutRespMsg->setIsSuccess(true);
00580         sendRpcResponse(it2->second.callMsg, capiPutRespMsg);
00581         it2->second.callMsg = NULL;
00582         putMap.erase(rpcId);
00583     }
00584 }
00585 
00586 void CBRDHT::handleGetResponse(CBRDHTGetResponse* dhtMsg, int rpcId)
00587 {
00588         std::map<unsigned int, BaseCallMessage*>::iterator it =
00589             rpcIdMap.find(dhtMsg->getNonce());
00590     std::map<int, GetMapEntry>::iterator it2 =
00591             getMap.find(rpcId);
00592 
00593     //unknown request
00594     if (it2 == getMap.end()) {
00595         std::cout << "- 1 -" << std::endl;
00596         return;
00597     }
00598 
00599     if (!dhtMsg->getIsHash()) {
00600         //std::cout << "[" << overlay->getThisNode().getAddress() << "] " << "Received an answer! Sending up key " << dhtMsg->getKey().toString(16) << "(orig: " << dhtMsg->getOriginalKey().toString(16) << ") -- value " << dhtMsg->getHashValue() << std::endl;
00601         //std::cout << "Replica left: " << it2->second.replica.size() << std::endl;
00602 
00603         if (dhtMsg->getHashValue().size() > 0 || dhtMsg->getResultArraySize() > 0) {
00604             // Successful Lookup, received a value
00605             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00606             //capiGetRespMsg->setKey(dhtMsg->getOriginalKey());
00607             //capiGetRespMsg->setValue(dhtMsg->getHashValue());
00608             DhtDumpEntry result;
00609             result.setKey(dhtMsg->getKey());
00610             result.setValue(dhtMsg->getResult(0).getValue());//getHashValue());
00611             capiGetRespMsg->setResultArraySize(1);
00612             capiGetRespMsg->setResult(0, result);
00613 
00614             //std::cout << "[" << overlay->getThisNode().getAddress() << "] " << "SUCCESSFUL LOOKUP! Sending up key " << dhtMsg->getKey().toString(16) << "(orig: " << dhtMsg->getOriginalKey().toString(16) << ") -- value " << dhtMsg->getHashValue() << std::endl;
00615 
00616             capiGetRespMsg->setIsSuccess(true);
00617             sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00618             getMap.erase(rpcId);
00619             return;
00620         } else if (it2->second.replica.size() > 0) {
00621             // Received empty value, try fallback replica
00622             NodeHandle fallbackReplica = it2->second.replica.back();
00623 
00624             std::cout << "[" << overlay->getThisNode().getAddress() << "] " << "Empty value received. Asking replica now ("<< it2->second.replica.size()<<" left)!" << std::endl;
00625 
00626             CBRDHTGetCall* dhtRecall = new CBRDHTGetCall();
00627             dhtRecall->setOriginalKey(dhtMsg->getOriginalKey());
00628             dhtRecall->setKey(dhtMsg->getKey());
00629             dhtRecall->setIsHash(false);
00630             dhtRecall->setBitLength(GETCALL_L(dhtRecall));
00631             RECORD_STATS(normalMessages++;
00632             numBytesNormal += dhtRecall->getByteLength());
00633             sendRouteRpcCall(TIER1_COMP, fallbackReplica, dhtRecall,
00634                              NULL, DEFAULT_ROUTING, -1, 0,
00635                              it2->second.callMsg->getNonce());
00636             it2->second.numSent++;
00637             it2->second.replica.pop_back();
00638             return;
00639         } else if (it2->second.teamNumber < (numReplicaTeams - 1)) {
00640             // No more fallback replica in this team, try next one
00641 
00642             std::cout << "it2->second.teamNumber (" << it2->second.teamNumber << ") < (numReplicaTeams - 1) (" << (numReplicaTeams - 1) << ")" << std::endl;
00643             std::cout << "[" << overlay->getThisNode().getAddress() << "] " << "No more fallback replica in this team "<< it2->second.teamNumber<<". Trying next one ("<< it2->second.teamNumber+1 <<  ")..." << std::endl;
00644 
00645             it2->second.teamNumber++;
00646             handleGetCAPIRequest(it2->second.callMsg, it2->second.teamNumber);
00647             return;
00648         } else {
00649             // No more replica, no more teams, send success == false to Tier 2 :(
00650 
00651             std::cout << "[" << overlay->getThisNode().getAddress() << "] " << "No more fallback replica. Lookup failed. :(" << std::endl;
00652 
00653             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00654             //capiGetRespMsg->setKey(dhtMsg->getOriginalKey());
00655             //capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00656             DhtDumpEntry result;
00657             result.setKey(dhtMsg->getKey());
00658             result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00659             capiGetRespMsg->setResultArraySize(1);
00660             capiGetRespMsg->setResult(0, result);
00661             capiGetRespMsg->setIsSuccess(false);
00662             sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00663             getMap.erase(rpcId);
00664         }
00665     }
00666 }
00667 
00668 void CBRDHT::update(const NodeHandle& node, bool joined)
00669 {
00670     OverlayKey key;
00671     DHTPutCall* dhtMsg;
00672     bool err = false;
00673     //DHTData entry;
00674     DhtDataEntry entry;
00675     //std::map<OverlayKey, DHTData>::iterator it = dataStorage->begin();
00676     DhtDataMap::iterator it = dataStorage->begin();
00677     for (unsigned int i = 0; i < dataStorage->getSize(); i++) {
00678         key = it->first;
00679         entry = it->second;
00680         if (joined) {
00681             if (entry.responsible && (overlay->isSiblingFor(node, key,
00682                                                             numReplica, &err)
00683                     || err)) { // hack for Chord, if we've got a new predecessor
00684 
00685                 dhtMsg = new DHTPutCall();
00686                 dhtMsg->setKey(key);
00687                 dhtMsg->setValue(entry.value);
00688                 dhtMsg->setKind(entry.kind);
00689                 dhtMsg->setId(entry.id);
00690 
00691                 //dhtMsg->setTtl((int) (entry.ttlMessage->arrivalTime()
00692                 //        - simTime()));
00693                 dhtMsg->setTtl((int)SIMTIME_DBL(entry.ttlMessage->getArrivalTime()
00694                                                 - simTime()));
00695                 dhtMsg->setIsModifiable(entry.is_modifiable);
00696                 dhtMsg->setMaintenance(true);
00697                 dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00698                 RECORD_STATS(maintenanceMessages++;
00699                         numBytesMaintenance += dhtMsg->getByteLength());
00700                 sendRouteRpcCall(TIER1_COMP, node, dhtMsg);
00701             }
00702 
00703             if (err) {
00704                 EV << "[DHT::update()]\n"
00705                    << "    Unable to know if key: " << key
00706                    << " is in range of node: " << node
00707                    << endl;
00708             }
00709         } else {
00710 #if 0
00711             //the update concerns a node who has left
00712             //replicate
00713             LookupCall* replicaMsg = new LookupCall();
00714             replicaMsg->setKey(key);
00715             replicaMsg->setNumSiblings(numReplica);
00716             int nonce = sendInternalRpcCall(OVERLAY_COMP,
00717                                             replicaMsg);
00718             dhtMsg = new DHTPutCall();
00719             dhtMsg->setKey(key);
00720             dhtMsg->setValue(entry.value);
00721             dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00722                     - simulation.simTime()));
00723             dhtMsg->setIsModifiable(entry.is_modifiable);
00724             dhtMsg->setMaintenance(true);
00725             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00726 
00727             rpcIdMap.insert(make_pair(nonce, dhtMsg));
00728 #endif
00729         }
00730 
00731         entry.responsible = overlay->isSiblingFor(overlay->getThisNode(),
00732                                                   key, 1, &err);
00733         it++;
00734     }
00735 }
00736 
00737 void CBRDHT::handleLookupResponse(LookupResponse* lookupMsg)
00738 {
00739         std::map<unsigned int, BaseCallMessage*>::iterator it =
00740             rpcIdMap.find(lookupMsg->getNonce());
00741 
00742     if (it == rpcIdMap.end() || it->second == NULL)
00743         return;
00744 
00745     if (dynamic_cast<DHTputCAPICall*> (it->second)) {
00746 
00747         #if 0
00748         cout << "DHT::handleLookupResponse(): PUT "
00749              << lookupMsg->getKey() << " ("
00750              << overlay->getThisNode().getKey() << ")" << endl;
00751 
00752         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00753             cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00754         }
00755 #endif
00756 
00757         DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*> (it->second);
00758         rpcIdMap.erase(lookupMsg->getNonce());
00759 
00760 
00761         if ((lookupMsg->getIsValid() == false)
00762                 || (lookupMsg->getSiblingsArraySize() == 0)) {
00763 
00764             EV << "[DHT::handleLookupResponse()]\n"
00765                << "    Unable to get replica list : invalid lookup"
00766                << endl;
00767             DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00768             capiPutRespMsg->setIsSuccess(false);
00769             sendRpcResponse(capiPutMsg, capiPutRespMsg);
00770             return;
00771         }
00772 
00773         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00774             DHTPutCall* dhtMsg = new DHTPutCall();
00775             dhtMsg->setKey(capiPutMsg->getKey());
00776             dhtMsg->setValue(capiPutMsg->getValue());
00777             dhtMsg->setKind(capiPutMsg->getKind());
00778             dhtMsg->setId(capiPutMsg->getId());
00779             dhtMsg->setTtl(capiPutMsg->getTtl());
00780             dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00781             dhtMsg->setMaintenance(false);
00782             dhtMsg->setBitLength(PUTCALL_L(dhtMsg));
00783             RECORD_STATS(normalMessages++;
00784                          numBytesNormal += dhtMsg->getByteLength());
00785             sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00786                              dhtMsg, NULL, DEFAULT_ROUTING, -1,
00787                              0, capiPutMsg->getNonce());
00788         }
00789 
00790         PutMapEntry mapEntry;
00791         mapEntry.callMsg = capiPutMsg;
00792         mapEntry.numResponses = 0;
00793         mapEntry.numFailed = 0;
00794         mapEntry.numSent = lookupMsg->getSiblingsArraySize();
00795 
00796         putMap.insert(make_pair(capiPutMsg->getNonce(), mapEntry));
00797     }
00798     else if (dynamic_cast<DHTgetCAPICall*>(it->second)) {
00799 
00800 #if 0
00801         cout << "DHT::handleLookupResponse(): GET "
00802              << lookupMsg->getKey() << " ("
00803              << overlay->getThisNode().getKey() << ")" << endl;
00804 
00805         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00806             cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00807         }
00808 #endif
00809 
00810         DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second);
00811         rpcIdMap.erase(lookupMsg->getNonce());
00812 
00813         // Invalid lookup
00814         if ((lookupMsg->getIsValid() == false)
00815                 || (lookupMsg->getSiblingsArraySize() == 0)) {
00816 
00817             EV << "[DHT::handleLookupResponse()]\n"
00818                << "    Unable to get replica list : invalid lookup"
00819                << endl;
00820             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00821             //capiGetRespMsg->setKey(lookupMsg->getKey());
00822             //capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00823             DhtDumpEntry result;
00824             result.setKey(lookupMsg->getKey());
00825             result.setValue(BinaryValue::UNSPECIFIED_VALUE);
00826             capiGetRespMsg->setResultArraySize(1);
00827             capiGetRespMsg->setResult(0, result);
00828             capiGetRespMsg->setIsSuccess(false);
00829             sendRpcResponse(capiGetMsg, capiGetRespMsg);
00830             return;
00831         }
00832 
00833         // Valid lookup
00834         GetMapEntry mapEntry;
00835         mapEntry.numSent = 0;
00836 
00837         // Multi team version: Already mapEntry from earlier team?
00838 
00839         std::map<int, GetMapEntry>::iterator it2 =
00840             getMap.find(capiGetMsg->getNonce());
00841 
00842         if (it2 != getMap.end()) {
00843             mapEntry = it2->second;
00844         } else {
00845             mapEntry.teamNumber = 0;
00846         }
00847         mapEntry.numAvailableReplica = lookupMsg->getSiblingsArraySize();
00848         mapEntry.numResponses = 0;
00849         mapEntry.callMsg = capiGetMsg;
00850         mapEntry.hashVector = NULL;
00851         mapEntry.replica.clear();
00852         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00853             // Simplified GET Request: Just one real request, rest is for fallback
00854             if (i == 0) {
00855                 CBRDHTGetCall* dhtMsg = new CBRDHTGetCall();
00856 
00857                 dhtMsg->setOriginalKey(capiGetMsg->getKey());
00858                 dhtMsg->setKey(lookupMsg->getKey());
00859 
00860                 dhtMsg->setIsHash(false);
00861                 dhtMsg->setKind(capiGetMsg->getKind());
00862                 dhtMsg->setId(capiGetMsg->getId());
00863                 dhtMsg->setBitLength(GETCALL_L(dhtMsg));
00864                 RECORD_STATS(normalMessages++;
00865                 numBytesNormal += dhtMsg->getByteLength());
00866                 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i), dhtMsg,
00867                                  NULL, DEFAULT_ROUTING, -1, 0,
00868                                  capiGetMsg->getNonce());
00869                 mapEntry.numSent++;
00870             } else {
00871                 //We don't send, we just store the remaining keys as fallback
00872                 mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00873             }
00874         }
00875         /*
00876             std::cout << "New replica: " <<  std::endl;
00877             for (int i = 0; i < mapEntry.replica.size(); i++) {
00878                 std::cout << mapEntry.replica[i] << std::endl;
00879             }
00880             std::cout << "*************************" << std::endl;
00881          */
00882         if (it2 != getMap.end())
00883             getMap.erase(it2);
00884         getMap.insert(make_pair(capiGetMsg->getNonce(), mapEntry));
00885     } else if (dynamic_cast<DHTPutCall*>(it->second)) {
00886         DHTPutCall* putMsg = dynamic_cast<DHTPutCall*>(it->second);
00887         rpcIdMap.erase(lookupMsg->getNonce());
00888 
00889         if ((lookupMsg->getIsValid() == false)
00890             || (lookupMsg->getSiblingsArraySize() == 0)) {
00891 
00892             EV << "[DHT::handleLookupResponse()]\n"
00893                << "    Unable to get replica list : invalid lookup"
00894                << endl;
00895             delete putMsg;
00896             return;
00897         }
00898 
00899         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00900             RECORD_STATS(maintenanceMessages++;
00901                          numBytesMaintenance += putMsg->getByteLength());
00902 
00903             sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00904                              new DHTPutCall(*putMsg));
00905         }
00906 
00907         delete putMsg;
00908     }
00909 }
00910 
00911 void CBRDHT::finishApp()
00912 {
00913     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00914 
00915     if (time != 0) {
00916         // std::cout << dataStorage->getSize() << " " << overlay->getThisNode().getKey().toString(16) << std::endl;
00917         globalStatistics->addStdDev("DHT: Sent Maintenance Messages/s",
00918                                     maintenanceMessages / time);
00919         globalStatistics->addStdDev("DHT: Sent Normal Messages/s",
00920                                     normalMessages / time);
00921         globalStatistics->addStdDev("DHT: Sent Maintenance Bytes/s",
00922                                     numBytesMaintenance / time);
00923         globalStatistics->addStdDev("DHT: Sent Normal Bytes/s",
00924                                     numBytesNormal / time);
00925     }
00926 }
00927 
00928 int CBRDHT::resultValuesBitLength(DHTGetResponse* msg) {
00929     int bitSize = 0;
00930     for (uint i = 0; i < msg->getResultArraySize(); i++) {
00931         bitSize += msg->getResult(i).getValue().size();
00932 
00933     }
00934     return bitSize;
00935 }
00936 
Generated on Wed May 26 16:21:13 2010 for OverSim by  doxygen 1.6.3