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

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 handleLookupCAPIRequest (DHTlookupCAPICall *capiLookupMsg)
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


Constructor & Destructor Documentation

DHT::~DHT (  )  [virtual]

00032 {
00033     std::map<unsigned int, BaseCallMessage*>::iterator it = rpcIdMap.begin();
00034     while(it != rpcIdMap.end()) {
00035         cancelAndDelete(it->second);
00036       it++;
00037     }
00038     rpcIdMap.clear();
00039     
00040 
00041     getMap.clear();
00042     dataStorage->clear();
00043 }


Member Function Documentation

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

initializes derived class-attributes

Parameters:
stage the init stage

Reimplemented from BaseApp.

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

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

collects statistical data of derived app

Reimplemented from BaseApp.

00688 {
00689     double time = simTime() - creationTime;
00690     globalStatistics->addStdDev("DHT: Stored Messages", numStored);
00691     globalStatistics->addStdDev("DHT: Maintenance Messages",
00692                                 maintenanceMessages);
00693     globalStatistics->addStdDev("DHT: Normal Messages", normalMessages);
00694     globalStatistics->addStdDev("DHT: Bytes/s Maintenance Sent",
00695                                 numBytesMaintenance / time);
00696     globalStatistics->addStdDev("DHT: Bytes/s Normal Sent",
00697                                 numBytesNormal / time);
00698 }

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.

00074 {
00075     DHTTtlTimer* msg_timer;
00076     if (msg->isName("ttl_timer")) {
00077         msg_timer = check_and_cast<DHTTtlTimer*>(msg);
00078 
00079         EV << "(DHT) received timer ttl, key: "
00080            << msg_timer->getKey().toString(16)
00081            << "\n (thisNode.key = "
00082            << thisNode.key.toString(16) << ")"
00083            << endl;
00084         
00085         dataStorage->removeData(msg_timer->getKey());
00086         delete msg_timer; 
00087     }
00088 }

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.

00091 {
00092     // delegate messages
00093     RPC_SWITCH_START( msg )
00094     // RPC_DELEGATE( <messageName>[Call|Response], <methodToCall> )
00095     RPC_DELEGATE( DHTPut, handlePutRequest );
00096     RPC_DELEGATE( DHTGet, handleGetRequest );
00097     RPC_DELEGATE( DHTputCAPI, handlePutCAPIRequest ); //requests coming from an upper tier
00098     RPC_DELEGATE( DHTgetCAPI, handleGetCAPIRequest );
00099     RPC_DELEGATE( DHTlookupCAPI, handleLookupCAPIRequest );
00100     RPC_SWITCH_END( )
00101 
00102     return RPC_HANDLED;
00103 }

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.

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

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.

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

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.

00246 {
00247     error("DHT::handleUpperMessage(): Received message with unknown type!");
00248 
00249     delete msg;
00250 }

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

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

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

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

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

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

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

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

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

00342 {
00343     //asks the replica list
00344     LookupCall* replicaMsg = new LookupCall();
00345     replicaMsg->setKey(capiPutMsg->getKey());
00346     replicaMsg->setNumSiblings(numReplica);
00347     int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE,
00348                        replicaMsg, NULL, OverlayKey::UNSPECIFIED_KEY, -1, 0);
00349     rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00350 }

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

00353 {
00354     LookupCall* replicaMsg = new LookupCall();
00355     replicaMsg->setKey(capiGetMsg->getKey());
00356     replicaMsg->setNumSiblings(numReplica);
00357     int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE,
00358                        replicaMsg, NULL, OverlayKey::UNSPECIFIED_KEY, -1, 0);
00359     rpcIdMap.insert(make_pair(nonce, capiGetMsg));
00360     lastGetCall = simTime();
00361 }

void DHT::handleLookupCAPIRequest ( DHTlookupCAPICall *  capiLookupMsg  )  [protected]

00364 {
00365     LookupCall* lookupMsg = new LookupCall();
00366     lookupMsg->setKey(capiLookupMsg->getKey());
00367     lookupMsg->setNumSiblings(capiLookupMsg->getNumSiblings());
00368     int nonce = sendRpcMessage(RPC_TO_LOWERTIER, NodeHandle::UNSPECIFIED_NODE,
00369                        lookupMsg, NULL, OverlayKey::UNSPECIFIED_KEY, -1, 0);
00370     rpcIdMap.insert(make_pair(nonce, capiLookupMsg));
00371 }

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.

00490 {
00491     OverlayKey key;
00492     DHTPutCall* dhtMsg;
00493     bool err=false;
00494     DHTData entry;
00495     std::map<OverlayKey, DHTData>::iterator it = dataStorage->begin();
00496     for (unsigned int i=0; i< dataStorage->getSize() ; i++) {
00497         key = it->first;
00498         entry = it->second;
00499         if (joined) {
00500             if (overlay->isSiblingFor(node, key, 1, &err)) {
00501                 // we're responsible for this key
00502                 if (overlay->isSiblingFor(node, key, numReplica, &err)) {
00503                     dhtMsg = new DHTPutCall();
00504                     dhtMsg->setKey(key);
00505                     dhtMsg->setValue(entry.value);
00506                     dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00507                                          - simulation.simTime()));
00508                     dhtMsg->setIsModifiable(entry.is_modifiable);
00509                     dhtMsg->setMaintenance(true);
00510                     dhtMsg->setLength(PUTCALL_L(dhtMsg));
00511                     RECORD_STATS(maintenanceMessages++;
00512                                  numBytesMaintenance += dhtMsg->byteLength());
00513                     sendRpcMessage(RPC_TO_UDP, node, dhtMsg);
00514                 }
00515                 if (err) {
00516                     EV << "Unable to know if key: " << key
00517                        << " is in range of node: " << node << endl;
00518                 }
00519             } else {
00520                 //check if we were responsible for this key
00521                 if (overlay->isSiblingFor(node, key, 1, &err) || err) {
00522                     if (!err || entry.responsible) {
00523                     // hack for chord, as we can't know if we were responsible
00524                         dhtMsg = new DHTPutCall();
00525                         dhtMsg->setKey(key);
00526                         dhtMsg->setValue(entry.value);
00527                         dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00528                                              - simulation.simTime()));
00529                         dhtMsg->setIsModifiable(entry.is_modifiable);
00530                         dhtMsg->setMaintenance(true);
00531                         dhtMsg->setLength(PUTCALL_L(dhtMsg));
00532                         RECORD_STATS(maintenanceMessages++;
00533                              numBytesMaintenance += dhtMsg->byteLength());
00534                         sendRpcMessage(RPC_TO_UDP, node, dhtMsg);
00535                     }
00536 
00537                 }
00538 
00539             }
00540         }
00541         else {
00542             //the update concerns a node who has leaved
00543             //replicate 
00544             LookupCall* replicaMsg = new LookupCall();
00545             replicaMsg->setKey(key);
00546             replicaMsg->setNumSiblings(numReplica);
00547             int nonce = sendRpcMessage(RPC_TO_LOWERTIER,
00548                                        NodeHandle::UNSPECIFIED_NODE, replicaMsg,
00549                                        NULL, OverlayKey::UNSPECIFIED_KEY,
00550                                        -1, 0);
00551             dhtMsg = new DHTPutCall();
00552             dhtMsg->setKey(key);
00553             dhtMsg->setValue(entry.value);
00554             dhtMsg->setTtl((int)(entry.ttlMessage->arrivalTime()
00555                                  - simulation.simTime()));
00556             dhtMsg->setIsModifiable(entry.is_modifiable);
00557             dhtMsg->setMaintenance(true);
00558             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00559 
00560             rpcIdMap.insert(make_pair(nonce, dhtMsg));
00561         }
00562         entry.responsible = overlay->isSiblingFor(thisNode, key, 1, &err);
00563         it++;
00564     }
00565 }

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

00568 {
00569     std::map<unsigned int, BaseCallMessage*>::iterator it =
00570         rpcIdMap.find(lookupMsg->getNonce());
00571     if (it == rpcIdMap.end() || it->second == NULL)
00572       return;
00573 
00574     if (dynamic_cast<DHTlookupCAPICall*>(it->second)) {
00575         DHTlookupCAPICall* capiLookupMsg =
00576             dynamic_cast<DHTlookupCAPICall*>(it->second);
00577         rpcIdMap.erase(lookupMsg->getNonce());
00578         
00579         DHTlookupCAPIResponse* capiLookupRespMsg =
00580                 new DHTlookupCAPIResponse();
00581         capiLookupRespMsg->setKey(lookupMsg->getKey());
00582         capiLookupRespMsg->setIsValid(lookupMsg->getIsValid());
00583         capiLookupRespMsg->setSiblingsArraySize(
00584             lookupMsg->getSiblingsArraySize());
00585 
00586         for (uint i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00587             capiLookupRespMsg->setSiblings(i, lookupMsg->getSiblings(i));
00588         }
00589 
00590         sendRpcResponse(RPC_TO_UPPERTIER, capiLookupMsg, capiLookupRespMsg);
00591         return;
00592     } else if (dynamic_cast<DHTputCAPICall*>(it->second)) {
00593         DHTputCAPICall* capiPutMsg = dynamic_cast<DHTputCAPICall*>(it->second);
00594         rpcIdMap.erase(lookupMsg->getNonce());
00595 
00596         if ((lookupMsg->getIsValid() == false)
00597             || (lookupMsg->getSiblingsArraySize() == 0)) {
00598 
00599             EV << "Unable to get replica list : invalid lookup" << endl;
00600             DHTputCAPIResponse* capiPutRespMsg = new DHTputCAPIResponse();
00601             capiPutRespMsg->setKey(lookupMsg->getKey());
00602             capiPutRespMsg->setIsSuccess(false);
00603             sendRpcResponse(RPC_TO_UPPERTIER, capiPutMsg, capiPutRespMsg);
00604             return;
00605         }
00606 
00607         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00608             DHTPutCall* dhtMsg = new DHTPutCall();
00609             dhtMsg->setKey(capiPutMsg->getKey());
00610             dhtMsg->setValue(capiPutMsg->getValue());
00611             dhtMsg->setTtl(capiPutMsg->getTtl());
00612             dhtMsg->setIsModifiable(capiPutMsg->getIsModifiable());
00613             dhtMsg->setMaintenance(false);
00614             dhtMsg->setLength(PUTCALL_L(dhtMsg));
00615             RECORD_STATS(normalMessages++;
00616                          numBytesNormal += dhtMsg->byteLength());
00617             int nonce = sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i),
00618                                        dhtMsg);
00619             if (i == 0) {
00620                 rpcIdMap.insert(make_pair(nonce, capiPutMsg));
00621             }
00622         }
00623     }
00624     else if (dynamic_cast<DHTgetCAPICall*>(it->second)) {
00625         DHTgetCAPICall* capiGetMsg = dynamic_cast<DHTgetCAPICall*>(it->second);
00626         rpcIdMap.erase(lookupMsg->getNonce());
00627 
00628         if ((lookupMsg->getIsValid() == false)
00629             || (lookupMsg->getSiblingsArraySize() == 0)) {
00630 
00631             EV << "Unable to get replica list : invalid lookup" << endl;
00632             DHTgetCAPIResponse* capiGetRespMsg = new DHTgetCAPIResponse();
00633             capiGetRespMsg->setKey(lookupMsg->getKey());
00634             capiGetRespMsg->setValue(BinaryValue::UNSPECIFIED_VALUE);
00635             capiGetRespMsg->setIsSuccess(false);
00636             sendRpcResponse(RPC_TO_UPPERTIER, capiGetMsg, capiGetRespMsg);
00637             return;
00638         }
00639 
00640         GetMapEntry mapEntry;
00641 
00642         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++) {
00643             if (i < (unsigned int)numGetRequests) {
00644               DHTGetCall* dhtMsg = new DHTGetCall();
00645               dhtMsg->setKey(capiGetMsg->getKey());
00646               dhtMsg->setIsHash(true);
00647               dhtMsg->setLength(GETCALL_L(dhtMsg));
00648               RECORD_STATS(normalMessages++;
00649                            numBytesNormal += dhtMsg->byteLength());
00650               sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i), dhtMsg);
00651             }
00652             else {
00653                 //We don't send, we just store the remaining keys
00654                 mapEntry.replica.push_back(lookupMsg->getSiblings(i));
00655             }
00656         }
00657 
00658         mapEntry.callMsg = check_and_cast<DHTgetCAPICall*>(it->second);
00659         mapEntry.numResponses = 0;
00660         mapEntry.hashVector = NULL;
00661 
00662         getMap.insert(make_pair(capiGetMsg->getKey(), mapEntry)); 
00663     }
00664     else if (dynamic_cast<DHTPutCall*>(it->second)) {
00665         DHTPutCall* putMsg = dynamic_cast<DHTPutCall*>(it->second);
00666         rpcIdMap.erase(lookupMsg->getNonce());
00667 
00668         if ((lookupMsg->getIsValid() == false)
00669             || (lookupMsg->getSiblingsArraySize() == 0)) {
00670 
00671             EV << "Unable to get replica list : invalid lookup" << endl;
00672             delete putMsg;
00673             return;
00674         }
00675 
00676         for( unsigned int i = 0; i < lookupMsg->getSiblingsArraySize(); i++ ) {
00677             RECORD_STATS(maintenanceMessages++;
00678                          numBytesMaintenance += putMsg->byteLength());
00679 
00680             sendRpcMessage(RPC_TO_UDP, lookupMsg->getSiblings(i),
00681                            new DHTPutCall(*putMsg));
00682         }
00683         delete putMsg;
00684     }
00685 }


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 Wed Sep 26 12:13:01 2007 for ITM OverSim by  doxygen 1.5.1