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