DHT Class Reference

#include <DHT.h>

Inheritance diagram for DHT:

BaseApp BaseRpc RpcListener

List of all members.


Detailed Description

A Distributed Hash Table (DHT) for KBR protocols.

A Distributed Hash Table (DHT) for KBR protocols

Public Member Functions

 DHT ()
virtual ~DHT ()

Protected Member Functions

void initializeApp (int stage)
 initializes derived class-attributes
void finishApp ()
 collects statistical data of derived app
void handleTimerEvent (cMessage *msg)
 processes self-messages
bool handleRpc (BaseCallMessage *msg)
 Processes Remote-Procedure-Call invokation messages.
void handleRpcResponse (BaseResponseMessage *msg, cPolymorphic *context, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.
void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, cPolymorphic *context, int rpcId, const OverlayKey &destKey)
 This method is called if an RPC timeout has been reached.
void handleUpperMessage (cMessage *msg)
 handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function)
void handlePutRequest (DHTPutCall *dhtMsg)
void handleGetRequest (DHTGetCall *dhtMsg)
void handlePutResponse (DHTPutResponse *dhtMsg)
void handleGetResponse (DHTGetResponse *dhtMsg)
void handlePutCAPIRequest (DHTputCAPICall *capiPutMsg)
void handleGetCAPIRequest (DHTgetCAPICall *capiPutMsg)
void handleDumpDhtRequest (DHTdumpCall *call)
void update (const NodeHandle &node, bool joined)
 Common API function: informs application about neighbors and own nodeID.
void handleLookupResponse (LookupResponse *lookupMsg)

Protected Attributes

int numReplica
int numGetRequests
double ratioIdentical
double maintenanceMessages
double normalMessages
double numBytesMaintenance
double numBytesNormal
double lastGetCall
std::map< unsigned int,
BaseCallMessage * > 
rpcIdMap
 List of the Rpc Ids of the messages sent following the reception of an rpc request (the second member).
std::map< OverlayKey, GetMapEntrygetMap
DHTDataStoragedataStorage
 pointer to the dht data storage


Constructor & Destructor Documentation

DHT::DHT (  ) 

00037 {
00038     dataStorage = NULL;
00039 }

DHT::~DHT (  )  [virtual]

00042 {
00043     std::map<unsigned int, BaseCallMessage*>::iterator it;
00044 
00045     for (it = rpcIdMap.begin(); it != rpcIdMap.end(); it++) {
00046         cancelAndDelete(it->second);
00047         it->second = NULL;
00048     }
00049 
00050     std::map<OverlayKey, GetMapEntry>::iterator it2;
00051 
00052     for (it2 = getMap.begin(); it2 != getMap.end(); it2++) {
00053         cancelAndDelete(it2->second.callMsg);
00054         it2->second.callMsg = NULL;
00055     }
00056 
00057     rpcIdMap.clear();
00058     getMap.clear();
00059 
00060     if (dataStorage != NULL) {
00061         dataStorage->clear();
00062     }
00063 }


Member Function Documentation

void DHT::initializeApp ( int  stage  )  [protected, virtual]

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

00066 {
00067     if (stage != MIN_STAGE_APP)
00068         return;
00069 
00070     dataStorage = check_and_cast<DHTDataStorage*>
00071                       (parentModule()->submodule("dhtDataStorage"));
00072 
00073     numReplica = par("numReplica");
00074     numGetRequests = par("numGetRequests");
00075     ratioIdentical = par("ratioIdentical");
00076 
00077     if (numReplica > overlay->getMaxNumSiblings()) {
00078         opp_error("DHT::initialize(): numReplica bigger than what this "
00079                   "overlay can handle (%d)", overlay->getMaxNumSiblings());
00080     }
00081 
00082     maintenanceMessages = 0;
00083     normalMessages = 0;
00084     numBytesMaintenance = 0;
00085     numBytesNormal = 0;
00086     WATCH(maintenanceMessages);
00087     WATCH(normalMessages);
00088     WATCH(numBytesNormal);
00089     WATCH(numBytesMaintenance);
00090     WATCH_MAP(rpcIdMap);
00091 }

void DHT::finishApp (  )  [protected, virtual]

collects statistical data of derived app

Reimplemented from BaseApp.

00725 {
00726     simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00727 
00728     if (time != 0) {
00729         globalStatistics->addStdDev("DHT: Sent Maintenance Messages/s",
00730                                     maintenanceMessages / time);
00731         globalStatistics->addStdDev("DHT: Sent Normal Messages/s",
00732                                     normalMessages / time);
00733         globalStatistics->addStdDev("DHT: Sent Maintenance Bytes/s",
00734                                     numBytesMaintenance / time);
00735         globalStatistics->addStdDev("DHT: Sent Normal Bytes/s",
00736                                     numBytesNormal / time);
00737     }
00738 }

void DHT::handleTimerEvent ( cMessage *  msg  )  [protected, virtual]

processes self-messages

method to handle self-messages should be overwritten in derived application if needed

Parameters:
msg self-message

Reimplemented from BaseApp.

00094 {
00095     DHTTtlTimer* msg_timer;
00096 
00097     if (msg->isName("ttl_timer")) {
00098         msg_timer = check_and_cast<DHTTtlTimer*> (msg);
00099 
00100         EV << "(DHT) received timer ttl, key: "
00101            << msg_timer->getKey().toString(16)
00102            << "\n (overlay->getThisNode().key = "
00103            << overlay->getThisNode().key.toString(16) << ")"
00104            << endl;
00105 
00106         dataStorage->removeData(msg_timer->getKey());
00107         delete msg_timer;
00108     }
00109 }

bool DHT::handleRpc ( BaseCallMessage *  msg  )  [protected, virtual]

Processes Remote-Procedure-Call invokation messages.


This method should be overloaded when the overlay provides RPC functionality.

Returns:
true, if rpc has been handled

Reimplemented from BaseRpc.

00112 {
00113     // delegate messages
00114     RPC_SWITCH_START( msg )
00115         // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00116         RPC_DELEGATE( DHTPut, handlePutRequest );
00117         RPC_DELEGATE( DHTGet, handleGetRequest );
00118         RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests coming from an upper tier
00119         RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest );
00120         RPC_DELEGATE( DHTdump, handleDumpDhtRequest );
00121     RPC_SWITCH_END( )
00122 
00123     return RPC_HANDLED;
00124 }

void DHT::handleRpcResponse ( BaseResponseMessage *  msg,
cPolymorphic *  context,
int  rpcId,
simtime_t  rtt 
) [protected, virtual]

This method is called if an RPC response has been received.

Parameters:
msg The response message.
context Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

00128 {
00129     RPC_SWITCH_START(msg)
00130         RPC_ON_RESPONSE(DHTPut){
00131         handlePutResponse(_DHTPutResponse);
00132         EV << "DHT Put RPC Response received: id=" << rpcId
00133            << " msg=" << *_DHTPutResponse << " rtt=" << rtt << endl;
00134         break;
00135     }
00136     RPC_ON_RESPONSE(DHTGet) {
00137         handleGetResponse(_DHTGetResponse);
00138         EV << "DHT Get RPC Response received: id=" << rpcId
00139            << " msg=" << *_DHTGetResponse << " rtt=" << rtt << endl;
00140         break;
00141     }
00142     RPC_ON_RESPONSE(Lookup) {
00143         handleLookupResponse(_LookupResponse);
00144         EV << "Replica Set RPC Response received: id=" << rpcId
00145            << " msg=" << *_LookupResponse << " rtt=" << rtt << endl;
00146         break;
00147     }
00148     RPC_SWITCH_END()
00149 }

void DHT::handleRpcTimeout ( BaseCallMessage *  msg,
const TransportAddress dest,
cPolymorphic *  context,
int  rpcId,
const OverlayKey destKey 
) [protected, virtual]

This method is called if an RPC timeout has been reached.

Parameters:
msg The original RPC message.
dest The destination node
context Pointer to an optional state object. The object has to be handled/deleted by the handleRpcResponse() code
rpcId The RPC id.
destKey the destination OverlayKey

Reimplemented from RpcListener.

00154 {
00155 
00156     RPC_SWITCH_START(msg)
00157     RPC_ON_CALL(DHTPut){
00158         EV << "DHTPut Timeout" << endl;
00159         std::map<unsigned int, BaseCallMessage*>::iterator it =
00160             rpcIdMap.find(msg->getNonce());
00161         if (it == rpcIdMap.end() || it->second == NULL)
00162             return;
00163 
00164         DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00165         capiPutRespMsg->setKey(_DHTPutCall->getKey());
00166         capiPutRespMsg->setIsSuccess(false);
00167         sendRpcResponse(it->second, capiPutRespMsg);
00168         rpcIdMap.erase(msg->getNonce());
00169         break;
00170     }
00171     RPC_ON_CALL(DHTGet) {
00172         EV << "DHTGet Timeout" << endl;
00173 
00174         std::map<unsigned int, BaseCallMessage*>::iterator it =
00175             rpcIdMap.find(_DHTGetCall->getNonce());
00176         std::map<OverlayKey, GetMapEntry>::iterator it2 =
00177             getMap.find(_DHTGetCall->getKey());
00178 
00179         if (it2 == getMap.end()) { //unknown request
00180             return;
00181         }
00182 
00183         if (it != rpcIdMap.end()) {
00184             //we have sent a 'real' get request
00185             rpcIdMap.erase(_DHTGetCall->getNonce());
00186             //ask anyone else, if possible
00187 
00188             if ((it2->second.hashVector != NULL)
00189                 && (it2->second.hashVector->size()> 0)) {
00190 
00191                 DHTGetCall* getCall = new DHTGetCall();
00192                 getCall->setKey(_DHTGetCall->getKey());
00193                 getCall->setIsHash(false);
00194                 getCall->setLength(GETCALL_L(getCall));
00195                 RECORD_STATS(normalMessages++;
00196                              numBytesNormal += getCall->byteLength());
00197 
00198                 int nonce = sendRouteRpcCall(TIER1_COMP,
00199                                              it2->second.hashVector->back(),
00200                                              getCall);
00201                 rpcIdMap.insert(make_pair(nonce, (BaseCallMessage*)NULL));
00202                 it2->second.hashVector->pop_back();
00203             } else {
00204                 //no one else
00205                 DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00206                 capiGetRespMsg->setKey(_DHTGetCall->getKey());
00207                 capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00208                 capiGetRespMsg->setIsSuccess(false);
00209                 sendRpcResponse(it2->second.callMsg,
00210                                 capiGetRespMsg);
00211                 //cout << "DHT: GET failed: no one else" << endl;
00212                 getMap.erase(_DHTGetCall->getKey());
00213                 return;
00214             }
00215 
00216         } else {
00217             //try to ask another one of the replica list for the hash
00218             if (it2->second.replica.size() > 0) {
00219                 DHTGetCall* getCall = new DHTGetCall();
00220                 getCall->setKey(_DHTGetCall->getKey());
00221                 getCall->setIsHash(true);
00222                 getCall->setLength(GETCALL_L(getCall));
00223 
00224                 RECORD_STATS(normalMessages++;
00225                              numBytesNormal += getCall->byteLength());
00226 
00227                 sendRouteRpcCall(TIER1_COMP, it2->second.replica.back(), getCall);
00228                 it2->second.replica.pop_back();
00229             } else {
00230                 //no one else to ask, see what we can do with what we have
00231                 if (it2->second.numResponses > 0) {
00232                     unsigned int maxCount = 0;
00233                     ReplicaVector* hashVector = NULL;
00234                     std::map<BinaryValue, ReplicaVector>::iterator itHashes;
00235                     for (itHashes = it2->second.hashes.begin();
00236                          itHashes != it2->second.hashes.end(); itHashes++) {
00237 
00238                         if (itHashes->second.size()> maxCount) {
00239                             maxCount = itHashes->second.size();
00240                             hashVector = &(itHashes->second);
00241                         }
00242                     }
00243 
00244                     if ((double)maxCount/(double)it2->second.numResponses >= ratioIdentical) {
00245                         it2->second.hashVector = hashVector;
00246                     }
00247                 }
00248 
00249                 if ((it2->second.hashVector != NULL)
00250                      && (it2->second.hashVector->size()> 0)) {
00251 
00252                     DHTGetCall* getCall = new DHTGetCall();
00253                     getCall->setKey(_DHTGetCall->getKey());
00254                     getCall->setIsHash(false);
00255                     getCall->setLength(GETCALL_L(getCall));
00256                     RECORD_STATS(normalMessages++;
00257                                  numBytesNormal += getCall->byteLength());
00258                     int nonce = sendRouteRpcCall(TIER1_COMP,
00259                                                  it2->second.hashVector->back(),
00260                                                  getCall);
00261                     rpcIdMap.insert(make_pair(nonce, (BaseCallMessage*)NULL));
00262                     it2->second.hashVector->pop_back();
00263                 } else {
00264                     DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00265                     capiGetRespMsg->setKey(_DHTGetCall->getKey());
00266                     capiGetRespMsg->setIsSuccess(false);
00267                     sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00268                     //cout << "DHT: GET failed: timeout (no one else)" << endl;
00269                     getMap.erase(_DHTGetCall->getKey());
00270                 }
00271             }
00272         }
00273         break;
00274     }
00275     RPC_SWITCH_END( )
00276 }

void DHT::handleUpperMessage ( cMessage *  msg  )  [protected, virtual]

handleUpperMessage gets called of handleMessage(cMessage* msg) if msg arrivedOn from_upperTier (currently msg gets deleted in this function)

Parameters:
msg the message to handle

Reimplemented from BaseApp.

00279 {
00280     error("DHT::handleUpperMessage(): Received message with unknown type!");
00281 
00282     delete msg;
00283 }

void DHT::handlePutRequest ( DHTPutCall *  dhtMsg  )  [protected]

Referenced by handleRpc().

00286 {
00287     std::string tempString = "PUT_REQUEST received: "
00288             + std::string(dhtMsg->getKey().toString(16));
00289     parentModule()->parentModule()->bubble(tempString.c_str());
00290 
00291     if (!(dataStorage->isModifiable(dhtMsg->getKey()))) {
00292         //check if the put request came from the right node
00293         NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey());
00294         if (((!sourceNode.isUnspecified())
00295                 && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode
00296                 != dhtMsg->getSrcNode())) || ((dhtMsg->getMaintenance())
00297                 && (dhtMsg->getOwnerNode() == sourceNode))) {
00298             // TODO: set owner
00299             DHTPutResponse* responseMsg = new DHTPutResponse();
00300             responseMsg->setKey(dhtMsg->getKey());
00301             tempString = "Error, not allowed to modify this key";
00302             responseMsg->setValue(BinaryValue(tempString));
00303             responseMsg->setLength(PUTRESPONSE_L(responseMsg));
00304             RECORD_STATS(normalMessages++;
00305                          numBytesNormal += responseMsg->byteLength());
00306             sendRpcResponse(dhtMsg, responseMsg);
00307             return;
00308         }
00309 
00310     }
00311 
00312     // remove data item from local data storage
00313     cancelAndDelete(dataStorage->getTtlMessage(dhtMsg->getKey()));
00314     dataStorage->removeData(dhtMsg->getKey());
00315     if (dhtMsg->getValue().size() > 0) {
00316         // add ttl timer
00317         DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00318         timerMsg->setKey(dhtMsg->getKey());
00319         scheduleAt(simTime() + dhtMsg->getTtl(), timerMsg);
00320         // storage data item in local data storage
00321         bool err;
00322         dataStorage->addData(dhtMsg->getKey(), dhtMsg->getValue(), timerMsg,
00323                              dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(),
00324                              overlay->isSiblingFor(overlay->getThisNode(),
00325                                                    dhtMsg->getKey(),
00326                                                    1, &err));
00327     }
00328 
00329     // send back
00330     DHTPutResponse* responseMsg = new DHTPutResponse();
00331     responseMsg->setKey(dhtMsg->getKey());
00332 
00333     responseMsg->setValue(dhtMsg->getValue());
00334     responseMsg->setLength(PUTRESPONSE_L(responseMsg));
00335     RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength());
00336 
00337     sendRpcResponse(dhtMsg, responseMsg);
00338 }

void DHT::handleGetRequest ( DHTGetCall *  dhtMsg  )  [protected]

Referenced by handleRpc().

00341 {
00342     std::string tempString = "GET_REQUEST received: "
00343             + std::string(dhtMsg->getKey().toString(16));
00344 
00345     parentModule()->parentModule()->bubble(tempString.c_str());
00346 
00347     BinaryValue storedValue = dataStorage->getData(dhtMsg->getKey());
00348 
00349     // send back
00350     DHTGetResponse* responseMsg = new DHTGetResponse();
00351     responseMsg->setKey(dhtMsg->getKey());
00352     responseMsg->setIsHash(dhtMsg->getIsHash());
00353 
00354     if (storedValue.isUnspecified()) {
00355         responseMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00356     } else {
00357         if (dhtMsg->getIsHash()) {
00358             CSHA1 sha1;
00359             char temp[41];
00360             temp[0] = '\0';
00361             sha1.Reset();
00362             sha1.Update((uint8_t*) (&(*storedValue.begin())),
00363                         storedValue.size());
00364             sha1.Final();
00365             sha1.ReportHash(temp, CSHA1::REPORT_HEX);
00366 
00367             responseMsg->setValue(BinaryValue((char*) temp));
00368         } else {
00369             responseMsg->setValue(storedValue);
00370         }
00371     }
00372 
00373     responseMsg->setLength(GETRESPONSE_L(responseMsg));
00374     RECORD_STATS(normalMessages++;
00375                  numBytesNormal += responseMsg->byteLength());
00376     sendRpcResponse(dhtMsg, responseMsg);
00377 }

void DHT::handlePutResponse ( DHTPutResponse *  dhtMsg  )  [protected]

Referenced by handleRpcResponse().

00416 {
00417     std::map<unsigned int, BaseCallMessage*>::iterator it =
00418             rpcIdMap.find(dhtMsg->getNonce());
00419 
00420     if (it == rpcIdMap.end() || it->second == NULL)
00421         return;
00422 
00423     DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00424     capiPutRespMsg->setKey(dhtMsg->getKey());
00425     capiPutRespMsg->setValue(dhtMsg->getValue());
00426     capiPutRespMsg->setIsSuccess(true);
00427     sendRpcResponse(it->second, capiPutRespMsg);
00428     rpcIdMap.erase(dhtMsg->getNonce());
00429 }

void DHT::handleGetResponse ( DHTGetResponse *  dhtMsg  )  [protected]

Referenced by handleRpcResponse().

00432 {
00433     std::map<unsigned int, BaseCallMessage*>::iterator it =
00434             rpcIdMap.find(dhtMsg->getNonce());
00435     std::map<OverlayKey, GetMapEntry>::iterator it2 =
00436             getMap.find(dhtMsg->getKey());
00437 
00438     if (it2 == getMap.end()) //unknown request
00439         return;
00440 
00441     if (it != rpcIdMap.end()) {
00442         //we have sent a 'real' get request
00443         rpcIdMap.erase(dhtMsg->getNonce());
00444         if (!dhtMsg->getIsHash()) {
00445             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00446             capiGetRespMsg->setKey(dhtMsg->getKey());
00447             capiGetRespMsg->setValue(dhtMsg->getValue());
00448             capiGetRespMsg->setIsSuccess(true);
00449             sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00450             getMap.erase(dhtMsg->getKey());
00451             return;
00452         }
00453     } else {
00454         if (dhtMsg->getIsHash()) {
00455             std::map<BinaryValue, ReplicaVector>::iterator itHashes =
00456                     it2->second.hashes.find(dhtMsg->getValue());
00457 
00458             if (itHashes == it2->second.hashes.end()) {
00459                 //new hash
00460                 ReplicaVector vect = ReplicaVector();
00461                 vect.push_back(dhtMsg->getSrcNode());
00462                 it2->second.hashes.insert(make_pair(dhtMsg->getValue(), vect));
00463             } else {
00464                 itHashes->second.push_back(dhtMsg->getSrcNode());
00465             }
00466 
00467             it2->second.numResponses++;
00468 
00469             if (it2->second.numResponses >= numGetRequests) {
00470                 //we've got all the answers we wanted
00471                 unsigned int maxCount = 0;
00472                 ReplicaVector* hashVector = NULL;
00473                 for (itHashes = it2->second.hashes.begin(); itHashes
00474                         != it2->second.hashes.end(); itHashes++) {
00475                     if (itHashes->second.size() > maxCount) {
00476                         maxCount = itHashes->second.size();
00477                         hashVector = &(itHashes->second);
00478                     }
00479                 }
00480 
00481                 if ((double) maxCount / (double) it2->second.numResponses
00482                         >= ratioIdentical) {
00483                     it2->second.hashVector = hashVector;
00484                 } else {
00485                     //we'll try to ask some other nodes
00486                     if (it2->second.replica.size() > 0) {
00487                         DHTGetCall* getCall = new DHTGetCall();
00488                         getCall->setKey(dhtMsg->getKey());
00489                         getCall->setIsHash(true);
00490                         getCall->setLength(GETCALL_L(getCall));
00491                         RECORD_STATS(normalMessages++;
00492                                      numBytesNormal += getCall->byteLength());
00493                         sendRouteRpcCall(TIER1_COMP,
00494                                          it2->second.replica.back(), getCall);
00495                         it2->second.replica.pop_back();
00496                     } else { //we don't have anyone else to ask
00497                         DHTgetCAPIResponse* capiGetRespMsg =
00498                                 new DHTgetCAPIResponse();
00499                         capiGetRespMsg->setKey(dhtMsg->getKey());
00500                         capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00501                         capiGetRespMsg->setIsSuccess(false);
00502                         sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00503                         //cout << "DHT: GET failed: hash (no one else)" << endl;
00504                         getMap.erase(dhtMsg->getKey());
00505                     }
00506 
00507                 }
00508             }
00509         }
00510     }
00511 
00512     if (it2->second.hashVector != NULL) {
00513         //we have already received all the response and chosen a hash
00514         if (it2->second.hashVector->size() > 0) {
00515             DHTGetCall* getCall = new DHTGetCall();
00516             getCall->setKey(dhtMsg->getKey());
00517             getCall->setIsHash(false);
00518             getCall->setLength(GETCALL_L(getCall));
00519             RECORD_STATS(normalMessages++;
00520                          numBytesNormal += getCall->byteLength());
00521             int nonce = sendRouteRpcCall(TIER1_COMP,
00522                                          it2->second.hashVector->back(),
00523                                          getCall);
00524             rpcIdMap.insert(make_pair(nonce, (BaseCallMessage*)NULL));
00525             it2->second.hashVector->pop_back();
00526         } else { //we don't have anyone else to ask
00527             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00528             capiGetRespMsg->setKey(dhtMsg->getKey());
00529             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00530             capiGetRespMsg->setIsSuccess(false);
00531             sendRpcResponse(it2->second.callMsg, capiGetRespMsg);
00532             //cout << "DHT: GET failed: hash2 (no one else)" << endl;
00533             getMap.erase(dhtMsg->getKey());
00534         }
00535     }
00536 }

void DHT::handlePutCAPIRequest ( DHTputCAPICall *  capiPutMsg  )  [protected]

Referenced by handleRpc().

00380 {
00381     //asks the replica list
00382     LookupCall* replicaMsg = new LookupCall();
00383     replicaMsg->setKey(capiPutMsg->getKey());
00384     replicaMsg->setNumSiblings(numReplica);
00385     int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00386     rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00387 }

void DHT::handleGetCAPIRequest ( DHTgetCAPICall *  capiPutMsg  )  [protected]

Referenced by handleRpc().

00390 {
00391     LookupCall* replicaMsg = new LookupCall();
00392     replicaMsg->setKey(capiGetMsg->getKey());
00393     replicaMsg->setNumSiblings(numReplica);
00394     int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00395     rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00396     lastGetCall = simTime();
00397 }

void DHT::handleDumpDhtRequest ( DHTdumpCall *  call  )  [protected]

Referenced by handleRpc().

00400 {
00401     DHTdumpResponse* response = new DHTdumpResponse();
00402     DhtDumpVector* dumpVector = dataStorage->dumpDht();
00403 
00404     response->setRecordArraySize(dumpVector->size());
00405 
00406     for (uint i = 0; i < dumpVector->size(); i++) {
00407         response->setRecord(i, (*dumpVector)[i]);
00408     }
00409 
00410     delete dumpVector;
00411 
00412     sendRpcResponse(call, response);
00413 }

void DHT::update ( const NodeHandle node,
bool  joined 
) [protected, virtual]

Common API function: informs application about neighbors and own nodeID.

Parameters:
node new or lost neighbor
joined new or lost?

Reimplemented from BaseApp.

00539 {
00540     OverlayKey key;
00541     DHTPutCall* dhtMsg;
00542     bool err = false;
00543     DHTData entry;
00544     std::map<OverlayKey, DHTData>::iterator it = dataStorage->begin();
00545     for (unsigned int i = 0; i < dataStorage->getSize(); i++) {
00546         key = it->first;
00547         entry = it->second;
00548         if (joined) {
00549             if (entry.responsible && (overlay->isSiblingFor(node, key,
00550                                                             numReplica, &err)
00551                     || err)) { // hack for Chord, if we've got a new predecessor
00552 
00553                 dhtMsg = new DHTPutCall();
00554                 dhtMsg->setKey(key);
00555                 dhtMsg->setValue(entry.value);
00556                 dhtMsg->setTtl((int) (entry.ttlMessage->arrivalTime()
00557                         - simulation.simTime()));
00558                 dhtMsg->setIsModifiable(entry.is_modifiable);
00559                 dhtMsg->setMaintenance(true);
00560                 dhtMsg->setLength(PUTCALL_L(dhtMsg));
00561                 RECORD_STATS(maintenanceMessages++;
00562                         numBytesMaintenance += dhtMsg->byteLength());
00563                 sendRouteRpcCall(TIER1_COMP, node, dhtMsg);
00564             }
00565 
00566             if (err) {
00567                 EV << "Unable to know if key: " << key
00568                    << " is in range of node: " << node << endl;
00569             }
00570         } else {
00571 #if 0
00572             //the update concerns a node who has left
00573             //replicate
00574             LookupCall* replicaMsg = new LookupCall();
00575             replicaMsg->setKey(key);
00576             replicaMsg->setNumSiblings(numReplica);
00577             int nonce = sendInternalRpcCall(OVERLAY_COMP,
00578                                             replicaMsg);
00579             dhtMsg = new DHTPutCall();
00580             dhtMsg->setKey(key);
00581             dhtMsg->setValue(entry.value);
00582             dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00583                     - simulation.simTime()));
00584             dhtMsg->setIsModifiable(entry.is_modifiable);
00585             dhtMsg->setMaintenance(true);
00586             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00587 
00588             rpcIdMap.insert(make_pair(nonce, dhtMsg));
00589 #endif
00590         }
00591 
00592         entry.responsible = overlay->isSiblingFor(overlay->getThisNode(),
00593                                                   key, 1, &err);
00594         it++;
00595     }
00596 }

void DHT::handleLookupResponse ( LookupResponse *  lookupMsg  )  [protected]

Referenced by handleRpcResponse().

00599 {
00600     std::map<unsigned int, BaseCallMessage*>::iterator it =
00601             rpcIdMap.find(lookupMsg->getNonce());
00602 
00603     if (it == rpcIdMap.end() || it->second == NULL)
00604         return;
00605 
00606     if (dynamic_cast<DHTputCAPICall*> (it->second)) {
00607 
00608         #if 0
00609         cout << "DHT::handleLookupResponse(): PUT "
00610              << lookupMsg->getKey() << " ("
00611              << overlay->getThisNode().key << ")" << endl;
00612 
00613         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00614             cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00615         }
00616 #endif
00617 
00618         DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*> (it->second);
00619         rpcIdMap.erase(lookupMsg->getNonce());
00620 
00621         if ((lookupMsg->getIsValid() == false)
00622                 || (lookupMsg->getSiblingsArraySize() == 0)) {
00623 
00624             EV << "Unable to get replica list : invalid lookup" << endl;
00625             DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00626             capiPutRespMsg->setKey(lookupMsg->getKey());
00627             capiPutRespMsg->setIsSuccess(false);
00628             sendRpcResponse(capiPutMsg, capiPutRespMsg);
00629             return;
00630         }
00631 
00632         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00633             DHTPutCall* dhtMsg = new DHTPutCall();
00634             dhtMsg->setKey(capiPutMsg->getKey());
00635             dhtMsg->setValue(capiPutMsg->getValue());
00636             dhtMsg->setTtl(capiPutMsg->getTtl());
00637             dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00638             dhtMsg->setMaintenance(false);
00639             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00640             RECORD_STATS(normalMessages++;
00641                          numBytesNormal += dhtMsg->byteLength());
00642             int nonce = sendRouteRpcCall(TIER1_COMP,
00643                                          lookupMsg->getSiblings(i),
00644                                          dhtMsg);
00645             if (i == 0) {
00646                 rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00647             }
00648         }
00649     }
00650     else if (dynamic_cast<DHTgetCAPICall*>(it->second)) {
00651 
00652 #if 0
00653         cout << "DHT::handleLookupResponse(): GET "
00654              << lookupMsg->getKey() << " ("
00655              << overlay->getThisNode().key << ")" << endl;
00656 
00657         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00658             cout << i << ": " << lookupMsg->getSiblings(i) << endl;
00659         }
00660 #endif
00661 
00662         DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second);
00663         rpcIdMap.erase(lookupMsg->getNonce());
00664 
00665         if ((lookupMsg->getIsValid() == false)
00666                 || (lookupMsg->getSiblingsArraySize() == 0)) {
00667 
00668             EV << "Unable to get replica list : invalid lookup" << endl;
00669             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00670             capiGetRespMsg->setKey(lookupMsg->getKey());
00671             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00672             capiGetRespMsg->setIsSuccess(false);
00673             sendRpcResponse(capiGetMsg, capiGetRespMsg);
00674             return;
00675         }
00676 
00677         GetMapEntry mapEntry;
00678 
00679         for (unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00680             if (i < (unsigned int)numGetRequests) {
00681                 DHTGetCall* dhtMsg = new DHTGetCall();
00682                 dhtMsg->setKey(capiGetMsg->getKey());
00683                 dhtMsg->setIsHash(true);
00684                 dhtMsg->setLength(GETCALL_L(dhtMsg));
00685                 RECORD_STATS(normalMessages++;
00686                              numBytesNormal += dhtMsg->byteLength());
00687                 sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i), dhtMsg);
00688             } else {
00689                 //We don't send, we just store the remaining keys
00690                 mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00691             }
00692         }
00693 
00694         mapEntry.callMsg = capiGetMsg;
00695         mapEntry.numResponses = 0;
00696         mapEntry.hashVector = NULL;
00697 
00698         getMap.insert(make_pair(capiGetMsg->getKey(), mapEntry));
00699     }
00700     else if (dynamic_cast<DHTPutCall*>(it->second)) {
00701         DHTPutCall* putMsg = dynamic_cast<DHTPutCall*>(it->second);
00702         rpcIdMap.erase(lookupMsg->getNonce());
00703 
00704         if ((lookupMsg->getIsValid() == false)
00705                 || (lookupMsg->getSiblingsArraySize() == 0)) {
00706 
00707             EV << "Unable to get replica list : invalid lookup" << endl;
00708             delete putMsg;
00709             return;
00710         }
00711 
00712         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00713             RECORD_STATS(maintenanceMessages++;
00714                          numBytesMaintenance += putMsg->byteLength());
00715 
00716             sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00717                              new DHTPutCall(*putMsg));
00718         }
00719 
00720         delete putMsg;
00721     }
00722 }


Member Data Documentation

int DHT::numReplica [protected]

int DHT::numGetRequests [protected]

double DHT::ratioIdentical [protected]

double DHT::maintenanceMessages [protected]

double DHT::normalMessages [protected]

double DHT::numBytesMaintenance [protected]

double DHT::numBytesNormal [protected]

double DHT::lastGetCall [protected]

Referenced by handleGetCAPIRequest().

std::map<unsigned int, BaseCallMessage*> DHT::rpcIdMap [protected]

List of the Rpc Ids of the messages sent following the reception of an rpc request (the second member).

Referenced by handleGetCAPIRequest(), handleGetResponse(), handleLookupResponse(), handlePutCAPIRequest(), handlePutResponse(), handleRpcTimeout(), initializeApp(), update(), and ~DHT().

std::map<OverlayKey, GetMapEntry> DHT::getMap [protected]


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:06 2008 for ITM OverSim by  doxygen 1.5.5