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, int rpcId, simtime_t rtt)
 This method is called if an RPC response has been received.
void handleRpcTimeout (BaseCallMessage *msg, const TransportAddress &dest, 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 update (const NodeHandle &node, bool joined)
 Common API function: informs application about neighbors and own nodeID.
void replicate (LookupResponse *lookupMsg)

Protected Attributes

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


Constructor & Destructor Documentation

DHT::DHT (  ) 

00032 {
00033     dataStorage = NULL;
00034 }

DHT::~DHT (  )  [virtual]

00037 {
00038     std::map<unsigned int, BaseCallMessage*>::iterator it = rpcIdMap.begin();
00039     while(it != rpcIdMap.end()) {
00040         cancelAndDelete(it->second);
00041       it++;
00042     }
00043     
00044     rpcIdMap.clear();
00045     getMap.clear();
00046     
00047     if (dataStorage != NULL) {
00048         dataStorage->clear();
00049     }
00050 }


Member Function Documentation

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

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

00053 {
00054     if(stage != MIN_STAGE_APP)
00055         return;
00056 
00057     dataStorage = check_and_cast<DHTDataStorage*>
00058                   (parentModule()->submodule("dhtDataStorage"));
00059 
00060     numReplica = par("numReplica");
00061     numGetRequests = par("numGetRequests");
00062     ratioIdentical = par("ratioIdentical");
00063 
00064     if (numReplica > overlay->getMaxNumSiblings()) {
00065         opp_error("DHT::initialize(): numReplica bigger than what this overlay can handle (%d)", overlay->getMaxNumSiblings());
00066     }
00067     numStored = 0;
00068     maintenanceMessages = 0;
00069     normalMessages = 0;
00070     numBytesMaintenance = 0;
00071     numBytesNormal = 0;
00072     WATCH(numStored);
00073     WATCH(maintenanceMessages);
00074     WATCH(normalMessages);
00075     WATCH(numBytesNormal);
00076     WATCH(numBytesMaintenance);
00077     WATCH_MAP(rpcIdMap);
00078 }

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

collects statistical data of derived app

Reimplemented from BaseApp.

00653 {
00654     double time = simTime() - creationTime;
00655     globalStatistics->addStdDev("DHT: Stored Messages", numStored);
00656     globalStatistics->addStdDev("DHT: Maintenance Messages",
00657                                 maintenanceMessages);
00658     globalStatistics->addStdDev("DHT: Normal Messages", normalMessages);
00659     globalStatistics->addStdDev("DHT: Bytes/s Maintenance Sent",
00660                                 numBytesMaintenance / time);
00661     globalStatistics->addStdDev("DHT: Bytes/s Normal Sent",
00662                                 numBytesNormal / time);
00663 }

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.

00081 {
00082     DHTTtlTimer* msg_timer;
00083     if (msg->isName("ttl_timer")) {
00084         msg_timer = check_and_cast<DHTTtlTimer*>(msg);
00085 
00086         EV << "(DHT) received timer ttl, key: "
00087            << msg_timer->getKey().toString(16)
00088            << "\n (thisNode.key = "
00089            << thisNode.key.toString(16) << ")"
00090            << endl;
00091         
00092         dataStorage->removeData(msg_timer->getKey());
00093         delete msg_timer; 
00094     }
00095 }

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.

00098 {
00099     // delegate messages
00100     RPC_SWITCH_START( msg )
00101     // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00102     RPC_DELEGATE( DHTPut, handlePutRequest );
00103     RPC_DELEGATE( DHTGet, handleGetRequest );
00104     RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests coming from an upper tier
00105     RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest );
00106     RPC_SWITCH_END( )
00107 
00108     return RPC_HANDLED;
00109 }

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

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

Parameters:
msg The response message.
rpcId The RPC id.
rtt The Round-Trip-Time of this RPC

Reimplemented from RpcListener.

00113 {
00114     RPC_SWITCH_START(msg)
00115     RPC_ON_RESPONSE( DHTPut ) {
00116         handlePutResponse(_DHTPutResponse);
00117         EV << "DHT Put RPC Response received: id=" << rpcId
00118         << " msg=" << *_DHTPutResponse << " rtt=" << rtt << endl;
00119         break;
00120     }
00121     RPC_ON_RESPONSE( DHTGet ) {
00122         handleGetResponse(_DHTGetResponse);
00123         EV << "DHT Get RPC Response received: id=" << rpcId
00124         << " msg=" << *_DHTGetResponse << " rtt=" << rtt << endl;
00125         break;
00126     }
00127     RPC_ON_RESPONSE( Lookup ) {
00128         replicate(_LookupResponse);
00129         EV << "Replica Set RPC Response received: id=" << rpcId
00130         << " msg=" << *_LookupResponse << " rtt=" << rtt << endl;
00131         break;
00132     }
00133     RPC_SWITCH_END( )
00134 }

void DHT::handleRpcTimeout ( BaseCallMessage *  msg,
const TransportAddress dest,
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
rpcId The RPC id.
destKey the destination OverlayKey

Reimplemented from RpcListener.

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

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.

00256 {
00257     error("DHT::handleUpperMessage(): Received message with unknown type!");
00258 
00259     delete msg;
00260 }

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

00263 {
00264     std::string tempString = "PUT_REQUEST received: " +
00265         std::string(dhtMsg->getKey().toString(16));
00266     parentModule()->parentModule()->bubble(tempString.c_str());
00267 
00268     if (!(dataStorage->isModifiable(dhtMsg->getKey()))) {
00269         //check if the put request came from the right node
00270         NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey());
00271         if (((!sourceNode.isUnspecified()) && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode != dhtMsg->getSrcNode()))
00272         || ((dhtMsg->getMaintenance()) && (dhtMsg->getOwnerNode() == sourceNode))) {
00273             // TODO: Set Owner!!!
00274             DHTPutResponse* responseMsg = new DHTPutResponse();
00275             responseMsg->setKey(dhtMsg->getKey());
00276             tempString = "Error, not allowed to modify this key";
00277             responseMsg->setValue(BinaryValue(tempString));
00278             responseMsg->setLength(PUTRESPONSE_L(responseMsg));
00279             RECORD_STATS(normalMessages++;
00280                          numBytesNormal += responseMsg->byteLength());
00281             sendRpcResponse(dhtMsg, responseMsg);
00282             return;
00283         }
00284 
00285     }
00286 
00287     // remove data item from local data storage
00288     cancelAndDelete(dataStorage->getTtlMessage(dhtMsg->getKey()));
00289     dataStorage->removeData(dhtMsg->getKey());
00290     if (dhtMsg->getValue().size() > 0) {
00291       //add ttl timer
00292       DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00293       timerMsg->setKey(dhtMsg->getKey());
00294       scheduleAt(simTime()+dhtMsg->getTtl(), timerMsg);
00295       // storage data item in local data storage
00296       bool err;
00297       dataStorage->addData(dhtMsg->getKey(), dhtMsg->getValue(), timerMsg,
00298                            dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(),
00299                            overlay->isSiblingFor(thisNode, dhtMsg->getKey(),
00300                                                  1, &err));
00301     }
00302 
00303     // send back
00304     DHTPutResponse* responseMsg = new DHTPutResponse();
00305     responseMsg->setKey(dhtMsg->getKey());
00306 
00307     responseMsg->setValue(dhtMsg->getValue());
00308     responseMsg->setLength(PUTRESPONSE_L(responseMsg));
00309     RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength());
00310 
00311     sendRpcResponse(dhtMsg, responseMsg);
00312 }

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

00315 {
00316     std::string tempString = "GET_REQUEST received: " +
00317         std::string(dhtMsg->getKey().toString(16));
00318     parentModule()->parentModule()->bubble(tempString.c_str());
00319 
00320     BinaryValue storedValue = dataStorage->getData(dhtMsg->getKey());
00321 
00322    
00323     // send back
00324     DHTGetResponse* responseMsg = new DHTGetResponse();
00325     responseMsg->setKey(dhtMsg->getKey());
00326     responseMsg->setIsHash(dhtMsg->getIsHash());
00327     if (storedValue == BinaryValue::UNSPECIFIED_VALUE) {
00328         responseMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00329     }
00330     else {
00331         if (dhtMsg->getIsHash()) {
00332             CSHA1 sha1;
00333             char temp[41];
00334             temp[0] = '\0';
00335             sha1.Reset();
00336             sha1.Update((uint8_t*)(&(*storedValue.begin())),
00337                         storedValue.size());
00338             sha1.Final();
00339             sha1.ReportHash(temp, CSHA1::REPORT_HEX);
00340 
00341             responseMsg->setValue(BinaryValue((char*)temp));
00342         }
00343         else {
00344             responseMsg->setValue(storedValue);
00345         }
00346     }
00347     responseMsg->setLength(GETRESPONSE_L(responseMsg));
00348     RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength());
00349     sendRpcResponse(dhtMsg, responseMsg);
00350 }

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

00373 {
00374     std::map<unsigned int, BaseCallMessage*>::iterator it =
00375         rpcIdMap.find(dhtMsg->getNonce());
00376     if (it == rpcIdMap.end() || it->second == NULL)
00377       return;
00378     DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00379     capiPutRespMsg->setKey(dhtMsg->getKey());
00380     capiPutRespMsg->setValue(dhtMsg->getValue());
00381     capiPutRespMsg->setIsSuccess(true);
00382     sendRpcResponse(it->second, capiPutRespMsg);
00383     rpcIdMap.erase(dhtMsg->getNonce());
00384 }

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

00387 {
00388     std::map<unsigned int, BaseCallMessage*>::iterator it =
00389         rpcIdMap.find(dhtMsg->getNonce());
00390     std::map<OverlayKey, GetMapEntry>::iterator it2 =
00391         getMap.find(dhtMsg->getKey());
00392     if (it2 == getMap.end()) //unknown request
00393       return;
00394       
00395     if ((it != rpcIdMap.end()) && (it->second != NULL)) {
00396     //we have sent a 'real' get request
00397         rpcIdMap.erase(dhtMsg->getNonce());
00398         if (!dhtMsg->getIsHash()) {
00399             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00400             capiGetRespMsg->setKey(dhtMsg->getKey());
00401             capiGetRespMsg->setValue(dhtMsg->getValue());
00402             capiGetRespMsg->setIsSuccess(true);
00403             sendRpcResponse(it2->second.callMsg,
00404                             capiGetRespMsg);
00405             getMap.erase(dhtMsg->getKey());
00406             return;
00407         }
00408     }
00409     else {
00410         if (dhtMsg->getIsHash()) {
00411             std::map<BinaryValue, ReplicaVector>::iterator itHashes =  it2->second.hashes.find(dhtMsg->getValue());
00412             if (itHashes == it2->second.hashes.end()) //new hash
00413             {
00414                 ReplicaVector vect = ReplicaVector();
00415                 vect.push_back(dhtMsg->getSrcNode());
00416                 it2->second.hashes.insert(make_pair(dhtMsg->getValue(), vect));
00417             }
00418             else {
00419                 itHashes->second.push_back(dhtMsg->getSrcNode());
00420             }
00421             it2->second.numResponses++;
00422             if (it2->second.numResponses >= numGetRequests) {
00423                 //we've got all the answers we wanted
00424                 unsigned int maxCount = 0;
00425                 ReplicaVector* hashVector = NULL;
00426                 for (itHashes =  it2->second.hashes.begin(); itHashes != it2->second.hashes.end(); itHashes++) {
00427                     if (itHashes->second.size() > maxCount) {
00428                         maxCount = itHashes->second.size();
00429                         hashVector = &(itHashes->second);
00430                     }
00431                 }
00432                 if ((double)maxCount/(double)it2->second.numResponses >= ratioIdentical) {
00433                     it2->second.hashVector = hashVector;
00434                 }
00435                 else {
00436                     //we'll try to ask some other nodes
00437                     if (it2->second.replica.size() > 0) {
00438                         DHTGetCall* getCall = new DHTGetCall();
00439                         getCall->setKey(dhtMsg->getKey());
00440                         getCall->setIsHash(true);
00441                         getCall->setLength(GETCALL_L(getCall));
00442                         RECORD_STATS(normalMessages++;
00443                                      numBytesNormal += getCall->byteLength());
00444                         sendRouteRpcCall(TIER1_COMP,
00445                                          it2->second.replica.back(), getCall);
00446                         it2->second.replica.pop_back();
00447                     }
00448                     else { //we don't have anyone else to ask
00449                         DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00450                         capiGetRespMsg->setKey(dhtMsg->getKey());
00451                         capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00452                         capiGetRespMsg->setIsSuccess(false);
00453                         sendRpcResponse(it2->second.callMsg,
00454                                         capiGetRespMsg);
00455                         getMap.erase(dhtMsg->getKey());
00456                     }
00457 
00458 
00459                 }
00460             }
00461         }
00462     }
00463     
00464     if (it2->second.hashVector != NULL) {
00465     //we have already received all the response and chosen a hash
00466         if (it2->second.hashVector->size() > 0) {
00467             DHTGetCall* getCall = new DHTGetCall();
00468             getCall->setKey(dhtMsg->getKey());
00469             getCall->setIsHash(false);
00470             getCall->setLength(GETCALL_L(getCall));
00471             RECORD_STATS(normalMessages++;
00472                                      numBytesNormal += getCall->byteLength());
00473             int nonce = sendRouteRpcCall(TIER1_COMP,
00474                                          it2->second.hashVector->back(),
00475                                          getCall);
00476             rpcIdMap.insert(make_pair(nonce, it2->second.callMsg));
00477             it2->second.hashVector->pop_back();
00478         }
00479         else { //we don't have anyone else to ask
00480             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00481             capiGetRespMsg->setKey(dhtMsg->getKey());
00482             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00483             capiGetRespMsg->setIsSuccess(false);
00484             sendRpcResponse(it2->second.callMsg,
00485                             capiGetRespMsg);
00486             rpcIdMap.erase(dhtMsg->getNonce());
00487             getMap.erase(dhtMsg->getKey());
00488         }
00489     }
00490 }

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

00353 {
00354     //asks the replica list
00355     LookupCall* replicaMsg = new LookupCall();
00356     replicaMsg->setKey(capiPutMsg->getKey());
00357     replicaMsg->setNumSiblings(numReplica);
00358     int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00359     rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00360 }

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

00363 {
00364     LookupCall* replicaMsg = new LookupCall();
00365     replicaMsg->setKey(capiGetMsg->getKey());
00366     replicaMsg->setNumSiblings(numReplica);
00367     int nonce = sendInternalRpcCall(OVERLAY_COMP, replicaMsg);
00368     rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00369     lastGetCall = simTime();
00370 }

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.

00493 {
00494     OverlayKey key;
00495     DHTPutCall* dhtMsg;
00496     bool err=false;
00497     DHTData entry;
00498     std::map<OverlayKey, DHTData>::iterator it = dataStorage->begin();
00499     for (unsigned int i=0; i< dataStorage->getSize() ; i++) {
00500         key = it->first;
00501         entry = it->second;
00502         if (joined) {
00503             if (entry.responsible && (overlay->isSiblingFor(node, key, numReplica, &err)
00504                     || err)) { // hack for Chord, if we've got a new predecessor
00505 
00506                 dhtMsg = new DHTPutCall();
00507                 dhtMsg->setKey(key);
00508                 dhtMsg->setValue(entry.value);
00509                 dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00510                         - simulation.simTime()));
00511                 dhtMsg->setIsModifiable(entry.is_modifiable);
00512                 dhtMsg->setMaintenance(true);
00513                 dhtMsg->setLength(PUTCALL_L(dhtMsg));
00514                 RECORD_STATS(maintenanceMessages++;
00515                              numBytesMaintenance += dhtMsg->byteLength());
00516                 sendRouteRpcCall(TIER1_COMP, node, dhtMsg);
00517             }
00518             if (err) {
00519                 EV << "Unable to know if key: " << key
00520                 << " is in range of node: " << node << endl;
00521             }
00522             //}
00523         } else {
00524 #if 0
00525             //the update concerns a node who has left
00526             //replicate 
00527             LookupCall* replicaMsg = new LookupCall();
00528             replicaMsg->setKey(key);
00529             replicaMsg->setNumSiblings(numReplica);
00530             int nonce = sendInternalRpcCall(OVERLAY_COMP,
00531                                             replicaMsg);
00532             dhtMsg = new DHTPutCall();
00533             dhtMsg->setKey(key);
00534             dhtMsg->setValue(entry.value);
00535             dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00536                                  - simulation.simTime()));
00537             dhtMsg->setIsModifiable(entry.is_modifiable);
00538             dhtMsg->setMaintenance(true);
00539             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00540 
00541             rpcIdMap.insert(make_pair(nonce, dhtMsg));
00542 #endif
00543         }
00544         entry.responsible = overlay->isSiblingFor(thisNode, key, 1, &err);
00545         it++;
00546     }
00547 }

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

00550 {
00551     std::map<unsigned int, BaseCallMessage*>::iterator it =
00552         rpcIdMap.find(lookupMsg->getNonce());
00553     if (it == rpcIdMap.end() || it->second == NULL)
00554       return;
00555 
00556     if (dynamic_cast<DHTputCAPICall*>(it->second)) {
00557         DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*>(it->second);
00558         rpcIdMap.erase(lookupMsg->getNonce());
00559 
00560         if ((lookupMsg->getIsValid() == false)
00561             || (lookupMsg->getSiblingsArraySize() == 0)) {
00562 
00563             EV << "Unable to get replica list : invalid lookup" << endl;
00564             DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00565             capiPutRespMsg->setKey(lookupMsg->getKey());
00566             capiPutRespMsg->setIsSuccess(false);
00567             sendRpcResponse(capiPutMsg, capiPutRespMsg);
00568             return;
00569         }
00570 
00571         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00572             DHTPutCall* dhtMsg = new DHTPutCall();
00573             dhtMsg->setKey(capiPutMsg->getKey());
00574             dhtMsg->setValue(capiPutMsg->getValue());
00575             dhtMsg->setTtl(capiPutMsg->getTtl());
00576             dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00577             dhtMsg->setMaintenance(false);
00578             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00579             RECORD_STATS(normalMessages++;
00580                         numBytesNormal += dhtMsg->byteLength());
00581             int nonce = sendRouteRpcCall(TIER1_COMP,
00582                                          lookupMsg->getSiblings(i),
00583                                          dhtMsg);
00584             if (i == 0) {
00585                 rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00586             }
00587         }
00588     }
00589     else if (dynamic_cast<DHTgetCAPICall*>(it->second)) {
00590         DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second);
00591         rpcIdMap.erase(lookupMsg->getNonce());
00592 
00593         if ((lookupMsg->getIsValid() == false)
00594             || (lookupMsg->getSiblingsArraySize() == 0)) {
00595 
00596             EV << "Unable to get replica list : invalid lookup" << endl;
00597             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00598             capiGetRespMsg->setKey(lookupMsg->getKey());
00599             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00600             capiGetRespMsg->setIsSuccess(false);
00601             sendRpcResponse(capiGetMsg, capiGetRespMsg);
00602             return;
00603         }
00604 
00605         GetMapEntry mapEntry;
00606 
00607         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00608             if (i < (unsigned int)numGetRequests) {
00609               DHTGetCall* dhtMsg = new DHTGetCall();
00610               dhtMsg->setKey(capiGetMsg->getKey());
00611               dhtMsg->setIsHash(true);
00612               dhtMsg->setLength(GETCALL_L(dhtMsg));
00613               RECORD_STATS(normalMessages++;
00614                                        numBytesNormal += dhtMsg->byteLength());
00615               sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i), dhtMsg);
00616             }
00617             else {
00618                 //We don't send, we just store the remaining keys
00619                 mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00620             }
00621         }
00622 
00623         mapEntry.callMsg = capiGetMsg;
00624         mapEntry.numResponses = 0;
00625         mapEntry.hashVector = NULL;
00626 
00627         getMap.insert(make_pair(capiGetMsg->getKey(), mapEntry)); 
00628     }
00629     else if (dynamic_cast<DHTPutCall*>(it->second)) {
00630         DHTPutCall* putMsg = dynamic_cast<DHTPutCall*>(it->second);
00631         rpcIdMap.erase(lookupMsg->getNonce());
00632 
00633         if ((lookupMsg->getIsValid() == false)
00634             || (lookupMsg->getSiblingsArraySize() == 0)) {
00635 
00636             EV << "Unable to get replica list : invalid lookup" << endl;
00637             delete putMsg;
00638             return;
00639         }
00640 
00641         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00642             RECORD_STATS(maintenanceMessages++;
00643                          numBytesMaintenance += putMsg->byteLength());
00644 
00645             sendRouteRpcCall(TIER1_COMP, lookupMsg->getSiblings(i),
00646                              new DHTPutCall(*putMsg));
00647         }
00648         delete putMsg;
00649     }
00650 }


Member Data Documentation

int DHT::numReplica [protected]

int DHT::numGetRequests [protected]

double DHT::ratioIdentical [protected]

double DHT::numStored [protected]

number of stored messages

double DHT::maintenanceMessages [protected]

double DHT::normalMessages [protected]

double DHT::numBytesMaintenance [protected]

double DHT::numBytesNormal [protected]

double DHT::lastGetCall [protected]

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).

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

DHTDataStorage* DHT::dataStorage [protected]

pointer to the dht data storage


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:28 2008 for ITM OverSim by  doxygen 1.5.3