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


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)
 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, GetMapEntrygetMap
DHTDataStoragedataStorage
 pointer to the dht data storage


Member Function Documentation

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

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

00032 {
00033     if(stage != MIN_STAGE_APP)
00034         return;
00035 
00036     dataStorage = check_and_cast<DHTDataStorage*>
00037                   (parentModule()->submodule("dhtDataStorage"));
00038 
00039     numReplica = par("numReplica");
00040     numGetRequests = par("numGetRequests");
00041     ratioIdentical = par("ratioIdentical");
00042 
00043     if (numReplica > overlay->getMaxNumSiblings()) {
00044         opp_error("DHT::initialize(): numReplica bigger than what this overlay can handle (%d)", overlay->getMaxNumSiblings());
00045     }
00046     numStored = 0;
00047     maintenanceMessages = 0;
00048     normalMessages = 0;
00049     numBytesMaintenance = 0;
00050     numBytesNormal = 0;
00051     WATCH(numStored);
00052     WATCH(maintenanceMessages);
00053     WATCH(normalMessages);
00054     WATCH(numBytesNormal);
00055     WATCH(numBytesMaintenance);
00056     WATCH_MAP(rpcIdMap);
00057 }

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

collects statistical data of derived app

Reimplemented from BaseApp.

00540 {
00541     double time = simTime() - creationTime;
00542     globalStatistics->addStdDev("DHT: Stored Messages", numStored);
00543     globalStatistics->addStdDev("DHT: Maintenance Messages", maintenanceMessages);
00544     globalStatistics->addStdDev("DHT: Normal Messages", normalMessages);
00545     globalStatistics->addStdDev("DHT: Bytes/s Maintenance Sent", numBytesMaintenance / time);
00546     globalStatistics->addStdDev("DHT: Bytes/s Normal Sent", numBytesNormal / time);
00547 }

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.

00060 {
00061     DHTTtlTimer* msg_timer;
00062     if (msg->isName("ttl_timer")) {
00063       msg_timer = check_and_cast<DHTTtlTimer*>(msg);
00064         EV << "(DHT) received timer ttl, key: " << msg_timer->getKey().toString(16)
00065     << "\n (thisNode.key = "
00066     << thisNode.key.toString(16) << ")"
00067     << endl;
00068 
00069       dataStorage->removeData(msg_timer->getKey());
00070       delete msg_timer; 
00071 
00072     }
00073 
00074 }

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.

00077 {
00078     // delegate messages
00079     RPC_SWITCH_START( msg )
00080     // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00081     RPC_DELEGATE( DHTPut, handlePutRequest );
00082     RPC_DELEGATE( DHTGet, handleGetRequest );
00083     RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests comming from an upper tier
00084     RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest );
00085     RPC_SWITCH_END( )
00086 
00087     return RPC_HANDLED;
00088 }

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.

00092 {
00093     RPC_SWITCH_START(msg)
00094     RPC_ON_RESPONSE( DHTPut ) {
00095         handlePutResponse(_DHTPutResponse);
00096         EV << "DHT Put RPC Response received: id=" << rpcId
00097         << " msg=" << *_DHTPutResponse << " rtt=" << rtt << endl;
00098         break;
00099     }
00100     RPC_ON_RESPONSE( DHTGet ) {
00101         handleGetResponse(_DHTGetResponse);
00102         EV << "DHT Get RPC Response received: id=" << rpcId
00103         << " msg=" << *_DHTGetResponse << " rtt=" << rtt << endl;
00104         break;
00105     }
00106     RPC_ON_RESPONSE( Lookup ) {
00107         replicate(_LookupResponse);
00108         EV << "Replica Set RPC Response received: id=" << rpcId
00109         << " msg=" << *_LookupResponse << " rtt=" << rtt << endl;
00110         break;
00111     }
00112     RPC_SWITCH_END( )
00113 }

void DHT::handleRpcTimeout ( BaseCallMessage *  msg,
const TransportAddress dest,
int  rpcId 
) [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.

Reimplemented from RpcListener.

00116 {
00117 
00118     RPC_SWITCH_START( msg )
00119     RPC_ON_CALL( DHTPut ) {
00120         EV << "DHTPut Timeout" << endl;
00121         std::map<unsigned int, BaseCallMessage*>::iterator it =  rpcIdMap.find(msg->getNonce());
00122         if (it == rpcIdMap.end() || it->second == NULL)
00123           return;
00124         DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00125         capiPutRespMsg->setKey(_DHTPutCall->getKey());
00126         capiPutRespMsg->setIsSuccess(false);
00127         sendRpcResponse(RPC_TO_UPPERTIER, it->second, capiPutRespMsg);
00128         rpcIdMap.erase(msg->getNonce());
00129         break;
00130     }
00131     RPC_ON_CALL( DHTGet ) {
00132         EV << "DHTGet Timeout" << endl;
00133         std::map<unsigned int, BaseCallMessage*>::iterator it =  rpcIdMap.find(_DHTGetCall->getNonce());
00134         std::map<OverlayKey, GetMapEntry>::iterator it2 =  getMap.find(_DHTGetCall->getKey());
00135         if (it2 == getMap.end()) //unknow request
00136           return;
00137           
00138         if (!(it == rpcIdMap.end() || it->second == NULL)) { //we have sent a 'real' get request
00139           rpcIdMap.erase(_DHTGetCall->getNonce());
00140           //ask anyone else, if possible
00141           if ((it2->second.hashVector != NULL) && (it2->second.hashVector-size() > 0)) {
00142             DHTGetCall* getCall = new DHTGetCall();
00143             getCall->setKey(_DHTGetCall->getKey());
00144             getCall->setIsHash(false);
00145             getCall->setLength(GETCALL_L(getCall));
00146             RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength());
00147             int nonce = sendRpcMessage(RPC_TO_UDP, it2->second.hashVector->back(), getCall);
00148             rpcIdMap.insert(make_pair(nonce, it2->second.callMsg));
00149             it2->second.hashVector->pop_back();
00150           }
00151           else {
00152             //no one else
00153             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00154             capiGetRespMsg->setKey(_DHTGetCall->getKey());
00155             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00156             capiGetRespMsg->setIsSuccess(false);
00157             sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg);
00158             getMap.erase(_DHTGetCall->getKey());
00159             return;
00160           }
00161         }
00162         else {
00163           //try to ask another one of the replica list for the hash
00164           if (it2->second.replica.size() > 0) {
00165             DHTGetCall* getCall = new DHTGetCall();
00166             getCall->setKey(_DHTGetCall->getKey());
00167             getCall->setIsHash(true);
00168             getCall->setLength(GETCALL_L(getCall));
00169             RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength());
00170             sendRpcMessage(RPC_TO_UDP, it2->second.replica.back(), getCall);
00171             it2->second.replica.pop_back();
00172 
00173           }
00174           else {
00175             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00176             capiGetRespMsg->setKey(_DHTGetCall->getKey());
00177             capiGetRespMsg->setIsSuccess(false);
00178             sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg);
00179             getMap.erase(_DHTGetCall->getKey());
00180           }
00181         }
00182         
00183 
00184         break;
00185     }
00186     RPC_SWITCH_END( )
00187 
00188 }

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.

00192 {
00193     error("DHT::handleUpperMessage(): Received message with unknown type!");
00194 
00195     delete msg;
00196 }

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

00199 {
00200     std::string tempString = "PUT_REQUEST received: " +
00201         std::string(dhtMsg->getKey().toString(16));
00202     parentModule()->parentModule()->bubble(tempString.c_str());
00203 
00204     if (!(dataStorage->isModifiable(dhtMsg->getKey()))) {
00205         //check if the put request came from the right node
00206         NodeHandle sourceNode = dataStorage->getSourceNode(dhtMsg->getKey());
00207         if (((!sourceNode.isUnspecified()) && (!dhtMsg->getSrcNode().isUnspecified()) && (sourceNode != dhtMsg->getSrcNode()))
00208         || ((dhtMsg->getMaintenance()) && (dhtMsg->getOwnerNode() == sourceNode))) {
00209             DHTPutResponse* responseMsg = new DHTPutResponse();
00210             responseMsg->setKey(dhtMsg->getKey());
00211             tempString = "Error, not allowed to modify this key";
00212             responseMsg->setValue(BinaryValue(tempString));
00213             responseMsg->setLength(PUTRESPONSE_L(responseMsg));
00214             RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength());
00215             sendRpcResponse(RPC_TO_UDP, dhtMsg, responseMsg);
00216             return;
00217         }
00218 
00219     }
00220 
00221     // remove data item from local data storage
00222     cancelAndDelete(dataStorage->getTtlMessage(dhtMsg->getKey()));
00223     dataStorage->removeData(dhtMsg->getKey());
00224     if (dhtMsg->getValue().size() > 0) {
00225       //add ttl timer
00226       DHTTtlTimer *timerMsg = new DHTTtlTimer("ttl_timer");
00227       timerMsg->setKey(dhtMsg->getKey());
00228       scheduleAt(simTime()+dhtMsg->getTtl(), timerMsg);
00229       // storage data item in local data storage
00230       bool err;
00231       dataStorage->addData(dhtMsg->getKey(), dhtMsg->getValue(), timerMsg, dhtMsg->getIsModifiable(), dhtMsg->getSrcNode(), overlay->isSiblingFor(thisNode, dhtMsg->getKey(), 1, &err));
00232     }
00233 
00234     // send back
00235     DHTPutResponse* responseMsg = new DHTPutResponse();
00236     responseMsg->setKey(dhtMsg->getKey());
00237 
00238     responseMsg->setValue(dhtMsg->getValue());
00239     responseMsg->setLength(PUTRESPONSE_L(responseMsg));
00240     RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength());
00241 
00242     sendRpcResponse(RPC_TO_UDP, dhtMsg, responseMsg);
00243 }

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

00246 {
00247     std::string tempString = "GET_REQUEST received: " +
00248         std::string(dhtMsg->getKey().toString(16));
00249     parentModule()->parentModule()->bubble(tempString.c_str());
00250 
00251     BinaryValue storedValue = dataStorage->getData(dhtMsg->getKey());
00252 
00253    
00254     // send back
00255     DHTGetResponse* responseMsg = new DHTGetResponse();
00256     responseMsg->setKey(dhtMsg->getKey());
00257     responseMsg->setIsHash(dhtMsg->getIsHash());
00258     if (storedValue == BinaryValue::UNSPECIFIED_VALUE) {
00259         responseMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00260     }
00261     else {
00262         if (dhtMsg->getIsHash()) {
00263             CSHA1 sha1;
00264             char temp[41];
00265             temp[0] = '\0';
00266             sha1.Reset();
00267             sha1.Update((uint8_t*)(&(*storedValue.begin())), storedValue.size());
00268             sha1.Final();
00269             sha1.ReportHash(temp, CSHA1::REPORT_HEX);
00270 
00271             responseMsg->setValue(BinaryValue((char*)temp));
00272         }
00273         else {
00274             responseMsg->setValue(storedValue);
00275         }
00276     }
00277     responseMsg->setLength(GETRESPONSE_L(responseMsg));
00278     RECORD_STATS(normalMessages++; numBytesNormal += responseMsg->byteLength());
00279     sendRpcResponse(RPC_TO_UDP, dhtMsg, responseMsg);
00280 }

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

00303 {
00304     std::map<unsigned int, BaseCallMessage*>::iterator it =  rpcIdMap.find(dhtMsg->getNonce());
00305     if (it == rpcIdMap.end() || it->second == NULL)
00306       return;
00307     DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00308     capiPutRespMsg->setKey(dhtMsg->getKey());
00309     capiPutRespMsg->setValue(dhtMsg->getValue());
00310     capiPutRespMsg->setIsSuccess(true);
00311     sendRpcResponse(RPC_TO_UPPERTIER, it->second, capiPutRespMsg);
00312     rpcIdMap.erase(dhtMsg->getNonce());
00313 }

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

00316 {
00317     std::map<unsigned int, BaseCallMessage*>::iterator it =  rpcIdMap.find(dhtMsg->getNonce());
00318     std::map<OverlayKey, GetMapEntry>::iterator it2 =  getMap.find(dhtMsg->getKey());
00319     if (it2 == getMap.end()) //unknow request
00320       return;
00321       
00322     if ((it != rpcIdMap.end()) && (it->second != NULL)) { //we have sent a 'real' get request
00323         if (!dhtMsg->getIsHash()) {
00324             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00325             capiGetRespMsg->setKey(dhtMsg->getKey());
00326             capiGetRespMsg->setValue(dhtMsg->getValue());
00327             capiGetRespMsg->setIsSuccess(true);
00328             sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg);
00329             rpcIdMap.erase(dhtMsg->getNonce());
00330             getMap.erase(dhtMsg->getKey());
00331             return;
00332         }
00333         else {
00334             rpcIdMap.erase(dhtMsg->getNonce());
00335         }
00336     }
00337     else {
00338         if (dhtMsg->getIsHash()) {
00339             std::map<BinaryValue, ReplicaVector>::iterator itHashes =  it2->second.hashes.find(dhtMsg->getValue());
00340             if (itHashes == it2->second.hashes.end()) //new hash
00341             {
00342                 ReplicaVector vect = ReplicaVector();
00343                 vect.push_back(dhtMsg->getSrcNode());
00344                 it2->second.hashes.insert(make_pair(dhtMsg->getValue(), vect));
00345             }
00346             else {
00347                 itHashes->second.push_back(dhtMsg->getSrcNode());
00348             }
00349             it2->second.numResponses++;
00350             if (it2->second.numResponses >= numGetRequests) {
00351                 //we've got all the answers we wanted
00352                 unsigned int maxCount = 0;
00353                 ReplicaVector* hashVector = NULL;
00354                 for (itHashes =  it2->second.hashes.begin(); itHashes != it2->second.hashes.end(); itHashes++) {
00355                     if (itHashes->second.size() > maxCount) {
00356                         maxCount = itHashes->second.size();
00357                         hashVector = &(itHashes->second);
00358                     }
00359                 }
00360                 if ((double)maxCount/(double)it2->second.numResponses >= ratioIdentical) {
00361                     it2->second.hashVector = hashVector;
00362                 }
00363                 else {
00364                     //we'll try to ask some other nodes
00365                     if (it2->second.replica.size() > 0) {
00366                         DHTGetCall* getCall = new DHTGetCall();
00367                         getCall->setKey(dhtMsg->getKey());
00368                         getCall->setIsHash(true);
00369                         getCall->setLength(GETCALL_L(getCall));
00370                         RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength());
00371                         sendRpcMessage(RPC_TO_UDP, it2->second.replica.back(), getCall);
00372                         it2->second.replica.pop_back();
00373                     }
00374                     else { //we don't have anyone else to ask
00375                         DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00376                         capiGetRespMsg->setKey(dhtMsg->getKey());
00377                         capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00378                         capiGetRespMsg->setIsSuccess(false);
00379                         sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg);
00380                         rpcIdMap.erase(dhtMsg->getNonce());
00381                         getMap.erase(dhtMsg->getKey());
00382                     }
00383 
00384 
00385                 }
00386             }
00387         }
00388     }
00389     
00390     if (it2->second.hashVector != NULL) //we have already received all the response and choosen a hash
00391     {
00392         if (it2->second.hashVector->size() > 0) {
00393             DHTGetCall* getCall = new DHTGetCall();
00394             getCall->setKey(dhtMsg->getKey());
00395             getCall->setIsHash(false);
00396             getCall->setLength(GETCALL_L(getCall));
00397             RECORD_STATS(normalMessages++; numBytesNormal += getCall->byteLength());
00398             int nonce = sendRpcMessage(RPC_TO_UDP, it2->second.hashVector->back(), getCall);
00399             rpcIdMap.insert(make_pair(nonce, it2->second.callMsg));
00400             it2->second.hashVector->pop_back();
00401         }
00402         else { //we don't have anyone else to ask
00403             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00404             capiGetRespMsg->setKey(dhtMsg->getKey());
00405             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00406             capiGetRespMsg->setIsSuccess(false);
00407             sendRpcResponse(RPC_TO_UPPERTIER, it2->second.callMsg, capiGetRespMsg);
00408             rpcIdMap.erase(dhtMsg->getNonce());
00409             getMap.erase(dhtMsg->getKey());
00410         }
00411     }
00412 }

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

00283 {
00284     //asks the replica list
00285     LookupCall* replicaMsg = new LookupCall();
00286     replicaMsg->setKey(capiPutMsg->getKey());
00287     replicaMsg->setNumSiblings(numReplica);
00288     int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE, replicaMsg);
00289     rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00290 }

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

00293 {
00294     LookupCall* replicaMsg = new LookupCall();
00295     replicaMsg->setKey(capiGetMsg->getKey());
00296     replicaMsg->setNumSiblings(numReplica);
00297     int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE, replicaMsg);
00298     rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00299     lastGetCall = simTime();
00300 }

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.

00415 {
00416     OverlayKey key;
00417     DHTPutCall* dhtMsg;
00418     bool err=false;
00419     DHTData entry;
00420     std::map<OverlayKey, DHTData>::iterator it = dataStorage->begin();
00421     for (unsigned int i=0; i< dataStorage->getSize() ; i++) {
00422         key = it->first;
00423         entry = it->second;
00424         if (joined) {
00425             if (overlay->isSiblingFor(node, key, 1, &err)) { // we're responsible for this key
00426                 if (overlay->isSiblingFor(node, key, numReplica, &err)) {
00427                     dhtMsg = new DHTPutCall();
00428                     dhtMsg->setKey(key);
00429                     dhtMsg->setValue(entry.value);
00430                     dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()-simulation.simTime()));
00431                     dhtMsg->setIsModifiable(entry.is_modifiable);
00432                     dhtMsg->setMaintenance(true);
00433                     dhtMsg->setLength(PUTCALL_L(dhtMsg));
00434                     RECORD_STATS(maintenanceMessages++; numBytesMaintenance += dhtMsg->byteLength());
00435                     sendRpcMessage(RPC_TO_UDP, node, dhtMsg);
00436                 }
00437                 if (err) {
00438                     EV << "Unable to know if key: " << key << " is in range of node: " << node << endl;
00439                 }
00440             }
00441             else {
00442                 //check if we were responsible for this key
00443                 if (overlay->isSiblingFor(node, key, 1, &err) || err) {
00444                     if (!err || entry.responsible) { // hack for chord, as we can't know if we we're responsible
00445                         dhtMsg = new DHTPutCall();
00446                         dhtMsg->setKey(key);
00447                         dhtMsg->setValue(entry.value);
00448                         dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()-simulation.simTime()));
00449                         dhtMsg->setIsModifiable(entry.is_modifiable);
00450                         dhtMsg->setMaintenance(true);
00451                         dhtMsg->setLength(PUTCALL_L(dhtMsg));
00452                         RECORD_STATS(maintenanceMessages++; numBytesMaintenance += dhtMsg->byteLength());
00453                         sendRpcMessage(RPC_TO_UDP, node, dhtMsg);
00454                     }
00455 
00456                 }
00457 
00458             }
00459         }
00460         else {
00461             //the update concerns a node who has leaved
00462             //replicate 
00463             LookupCall* replicaMsg = new LookupCall();
00464             replicaMsg->setKey(key);
00465             replicaMsg->setNumSiblings(numReplica);
00466             int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE, replicaMsg, NULL, key);
00467             dhtMsg = new DHTPutCall();
00468             dhtMsg->setKey(key);
00469             dhtMsg->setValue(entry.value);
00470             dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()-simulation.simTime()));
00471             dhtMsg->setIsModifiable(entry.is_modifiable);
00472             dhtMsg->setMaintenance(true);
00473             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00474 
00475             rpcIdMap.insert(make_pair(nonce, dhtMsg));
00476         }
00477         entry.responsible = overlay->isSiblingFor(thisNode, key, 1, &err);
00478         it++;
00479     }
00480 }

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

00483 {
00484     std::map<unsigned int, BaseCallMessage*>::iterator it =  rpcIdMap.find(lookupMsg->getNonce());
00485     if (it == rpcIdMap.end() || it->second == NULL)
00486       return;
00487     
00488     if (lookupMsg->getIsValid() == false) {
00489         EV << "Unable to get replica list : invalid lookup" << endl;
00490         rpcIdMap.erase(lookupMsg->getNonce());
00491         return;
00492     }
00493 
00494     if (dynamic_cast<DHTputCAPICall*>(it->second)) {
00495         DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*>(it->second);
00496         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00497             DHTPutCall* dhtMsg = new DHTPutCall();
00498             dhtMsg->setKey(capiPutMsg->getKey());
00499             dhtMsg->setValue(capiPutMsg->getValue());
00500             dhtMsg->setTtl(capiPutMsg->getTtl());
00501             dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00502             dhtMsg->setMaintenance(false);
00503             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00504             RECORD_STATS(normalMessages++; numBytesNormal += dhtMsg->byteLength());
00505 
00506             int nonce = sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i), dhtMsg);
00507             
00508             if (i == 0) {
00509                 rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00510             }
00511         }
00512     }
00513     else if (dynamic_cast<DHTgetCAPICall*>(it->second)) {
00514         DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second);
00515         GetMapEntry mapEntry;
00516         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00517             if (i < (unsigned int)numGetRequests) {
00518               DHTGetCall* dhtMsg = new DHTGetCall();
00519               dhtMsg->setKey(capiGetMsg->getKey());
00520               dhtMsg->setIsHash(true);
00521               dhtMsg->setLength(GETCALL_L(dhtMsg));
00522               RECORD_STATS(normalMessages++; numBytesNormal += dhtMsg->byteLength());
00523               sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i), dhtMsg);
00524             }
00525             else {
00526                 //We don't send, we just store the remaining keys
00527                 mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00528             }
00529         }
00530         mapEntry.callMsg = check_and_cast<DHTgetCAPICall*>(it->second);
00531         mapEntry.numResponses = 0;
00532         mapEntry.hashVector = NULL;
00533 
00534         getMap.insert(make_pair(capiGetMsg->getKey(), mapEntry)); 
00535     }
00536     rpcIdMap.erase(lookupMsg->getNonce());
00537 }


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 Tue Jul 24 16:51:18 2007 for ITM OverSim by  doxygen 1.5.1