#include <DHT.h>
Inheritance diagram for DHT:
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, GetMapEntry > | getMap |
DHTDataStorage * | dataStorage |
pointer to the dht data storage |
void DHT::initializeApp | ( | int | stage | ) | [protected, virtual] |
initializes derived class-attributes
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
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.
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.
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.
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)
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.
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 }
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