#include <DHTTestApp.h>
A simple test application that does random put and get calls on the DHT layer
Public Member Functions | |
virtual | ~DHTTestApp () |
virtual destructor | |
Protected Member Functions | |
void | initializeApp (int stage) |
initializes derived class-attributes | |
OverlayKey | getRandomKey () |
Get a random key of the hashmap. | |
char * | generateRandomValue () |
generate a random char[21] | |
void | finishApp () |
collects statistical data of derived app | |
virtual void | handleGetResponse (DHTgetCAPIResponse *msg) |
processes get responses | |
virtual void | handlePutResponse (DHTputCAPIResponse *msg) |
processes put responses | |
virtual void | handleTimerEvent (cMessage *msg) |
processes self-messages | |
virtual void | handleTraceMessage (cMessage *msg) |
handleTraceMessage gets called of handleMessage(cMessage* msg) if a message arrives at trace_in. | |
void | handleRpcResponse (BaseResponseMessage *msg, int rpcId, simtime_t rtt) |
This method is called if an RPC response has been received. | |
Protected Attributes | |
UnderlayConfigurator * | underlayConfigurator |
pointer to UnderlayConfigurator in this node | |
BootstrapOracle * | bootstrapOracle |
pointer to BootstrapOracle in this node | |
GlobalStatistics * | globalStatistics |
pointer to GlobalStatistics module in this node | |
bool | debugOutput |
debug output yes/no? | |
double | mean |
mean time interval between sending test messages | |
double | deviation |
deviation of time interval | |
bool | activeNetwInitPhase |
is app active in network init phase? | |
int | numSent |
number of sent packets | |
int | numGetSent |
number of get sent | |
int | numGetError |
number of false get responses | |
int | numGetSuccess |
number of false get responses | |
int | numPutSent |
number of put sent | |
int | numPutError |
number of error in put responses | |
int | numPutSuccess |
number of success in put responses | |
simtime_t | lastPutTime |
simtime_t | lastGetTime |
void DHTTestApp::initializeApp | ( | int | stage | ) | [protected, virtual] |
initializes derived class-attributes
stage | the init stage |
Reimplemented from BaseApp.
00042 { 00043 if (stage != MIN_STAGE_APP) 00044 return; 00045 00046 // fetch parameters 00047 debugOutput = par("debugOutput"); 00048 activeNetwInitPhase = par("activeNetwInitPhase"); 00049 00050 mean = par("messageDelay"); 00051 deviation = mean / 10; 00052 00053 bootstrapOracle = BootstrapOracleAccess().get(); 00054 underlayConfigurator = UnderlayConfiguratorAccess().get(); 00055 globalStatistics = GlobalStatisticsAccess().get(); 00056 00057 // statistics 00058 numSent = 0; 00059 numGetSent = 0; 00060 numGetError = 0; 00061 numGetSuccess = 0; 00062 numPutSent = 0; 00063 numPutError = 0; 00064 numPutSuccess = 0; 00065 00066 initRpcs(); 00067 WATCH(numSent); 00068 WATCH(numGetSent); 00069 WATCH(numGetError); 00070 WATCH(numGetSuccess); 00071 WATCH(numPutSent); 00072 WATCH(numPutError); 00073 WATCH(numPutSuccess); 00074 00075 // initiate test message emision 00076 cMessage* dhttestput_timer = new cMessage("dhttest_put_timer"); 00077 cMessage* dhttestget_timer = new cMessage("dhttest_get_timer"); 00078 cMessage* dhttestmod_timer = new cMessage("dhttest_mod_timer"); 00079 00080 if (mean > 0) { 00081 scheduleAt(simulation.simTime() + truncnormal(mean, deviation), 00082 dhttestput_timer); 00083 scheduleAt(simulation.simTime() + truncnormal(mean+mean/3, deviation), 00084 dhttestget_timer); 00085 scheduleAt(simulation.simTime() + truncnormal(mean+2*mean/3, deviation), 00086 dhttestmod_timer); 00087 } 00088 }
OverlayKey DHTTestApp::getRandomKey | ( | ) | [protected] |
Get a random key of the hashmap.
00273 { 00274 BootstrapOracle::DataMap* dataMap = bootstrapOracle->getDataMap(); 00275 00276 if (dataMap->size() == 0) 00277 return OverlayKey::UNSPECIFIED_KEY; 00278 00279 // return random OverlayKey in O(log n) (taken from BootstrapOracle) 00280 std::map<OverlayKey, DHTEntry>::iterator it = dataMap->end(); 00281 DHTEntry tempEntry = { NULL, 0 }; 00282 00283 while (it == dataMap->end()) { 00284 OverlayKey randomKey = OverlayKey::random(); 00285 00286 it = dataMap->find(randomKey); 00287 00288 if (it == dataMap->end()) { 00289 it = dataMap->insert(std::make_pair(randomKey,tempEntry)).first; 00290 dataMap->erase(it++); 00291 } 00292 00293 if (it == dataMap->end()) 00294 it = dataMap->begin(); 00295 } 00296 return it->first; 00297 }
char * DHTTestApp::generateRandomValue | ( | ) | [protected] |
generate a random char[21]
00300 { 00301 char* value; 00302 value = (char *)malloc(sizeof(char)*21); 00303 int i, randvalue; 00304 00305 for (i=0; i < 20; i++) { 00306 randvalue = (int)intuniform(0, 25); 00307 value[i] = randvalue+'a'; 00308 } 00309 00310 value[20] = '\0'; 00311 return value; 00312 }
void DHTTestApp::finishApp | ( | ) | [protected, virtual] |
collects statistical data of derived app
Reimplemented from BaseApp.
00315 { 00316 // record scalar data 00317 globalStatistics->addStdDev("DHTTest: Sent Messages", numSent); 00318 globalStatistics->addStdDev("DHTTest: Get Messages sent", numGetSent); 00319 globalStatistics->addStdDev("DHTTest: Get Errors", numGetError); 00320 globalStatistics->addStdDev("DHTTest: Get Success", numGetSuccess); 00321 if (numGetSent > 0) { 00322 globalStatistics->addStdDev("DHTTest: Get Success Ratio", 00323 (double)numGetSuccess/(double)numGetSent); 00324 } else { 00325 globalStatistics->addStdDev("DHTTest: Get Success Ratio", 0); 00326 } 00327 globalStatistics->addStdDev("DHTTest: Put Messages sent", numPutSent); 00328 globalStatistics->addStdDev("DHTTest: Put Errors", numPutError); 00329 globalStatistics->addStdDev("DHTTest: Put Success", numPutSuccess); 00330 }
void DHTTestApp::handleGetResponse | ( | DHTgetCAPIResponse * | msg | ) | [protected, virtual] |
processes get responses
method to handle get responses should be overwritten in derived application if needed
msg | get response message |
00127 { 00128 OverlayKey key = msg->getKey(); 00129 globalStatistics->addStdDev("DHTTest: Get length (s)", 00130 simTime() - lastGetTime); 00131 00132 if (!(msg->getIsSuccess())) { 00133 numGetError++; 00134 return; 00135 } 00136 std::map<OverlayKey, DHTEntry>::iterator it = bootstrapOracle->getDataMap()->find(key); 00137 00138 if (it == bootstrapOracle->getDataMap()->end()) { 00139 //unexpected key 00140 numGetError++; 00141 return; 00142 } 00143 00144 DHTEntry entry = it->second; 00145 if (simulation.simTime() > entry.endtime) { 00146 //this key doesn't exist anymore in the DHT, delete it in our hashtable 00147 bootstrapOracle->getDataMap()->erase(key); 00148 if (msg->getValue() != BinaryValue::UNSPECIFIED_VALUE) { 00149 numGetError++; 00150 return; 00151 } else { 00152 numGetSuccess++; 00153 return; 00154 } 00155 } else { 00156 if (dynamic_cast< vector<char>& >((msg->getValue())) 00157 != dynamic_cast< vector<char>& >(*(entry.value))) { 00158 numGetError++; 00159 return; 00160 } else { 00161 numGetSuccess++; 00162 return; 00163 } 00164 } 00165 00166 }
void DHTTestApp::handlePutResponse | ( | DHTputCAPIResponse * | msg | ) | [protected, virtual] |
processes put responses
method to handle put responses should be overwritten in derived application if needed
msg | put response message |
00110 { 00111 OverlayKey key = msg->getKey(); 00112 globalStatistics->addStdDev("DHTTest: Put length (s)", simTime() 00113 - lastPutTime); 00114 if (!(msg->getIsSuccess())) { 00115 numPutError++; 00116 return; 00117 } 00118 numPutSuccess++; 00119 DHTEntry entry; 00120 entry.value = new BinaryValue(msg->getValue()); 00121 entry.endtime = simulation.simTime()+DEFAULT_TTL; 00122 bootstrapOracle->getDataMap()->erase(msg->getKey()); 00123 bootstrapOracle->getDataMap()->insert(make_pair(msg->getKey(), entry)); 00124 }
void DHTTestApp::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.
00215 { 00216 if (msg->isName("dhttest_put_timer")) { 00217 // schedule next timer event 00218 scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg); 00219 00220 // do nothing if the network is still in the initialization phase 00221 if ((!activeNetwInitPhase) && (underlayConfigurator->isInit())) 00222 return; 00223 00224 // create a put test message with random destination key 00225 OverlayKey destKey = OverlayKey::random(); 00226 DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); 00227 char * value = generateRandomValue(); 00228 dhtPutMsg->setKey(destKey); 00229 dhtPutMsg->setValue(value); 00230 dhtPutMsg->setTtl(DEFAULT_TTL); 00231 dhtPutMsg->setIsModifiable(true); 00232 free(value); 00233 00234 lastPutTime = simTime(); 00235 numSent++; 00236 numPutSent++; 00237 sendInternalRpcCall(TIER1_COMP, dhtPutMsg); 00238 } else if (msg->isName("dhttest_get_timer")) { 00239 scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg); 00240 OverlayKey key = getRandomKey(); 00241 00242 if (key.isUnspecified()) 00243 return; 00244 00245 DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall(); 00246 dhtGetMsg->setKey(key); 00247 lastGetTime = simTime(); 00248 numSent++; 00249 numGetSent++; 00250 sendInternalRpcCall(TIER1_COMP, dhtGetMsg); 00251 } else if (msg->isName("dhttest_mod_timer")) { 00252 scheduleAt(simulation.simTime() + truncnormal(mean, deviation), msg); 00253 OverlayKey key = getRandomKey(); 00254 00255 if (key.isUnspecified()) 00256 return; 00257 00258 DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); 00259 char * value = generateRandomValue(); 00260 dhtPutMsg->setKey(key); 00261 dhtPutMsg->setValue(value); 00262 dhtPutMsg->setTtl(DEFAULT_TTL); 00263 dhtPutMsg->setIsModifiable(true); 00264 free(value); 00265 lastPutTime = simTime(); 00266 numSent++; 00267 numPutSent++; 00268 sendInternalRpcCall(TIER1_COMP, dhtPutMsg); 00269 } 00270 }
void DHTTestApp::handleTraceMessage | ( | cMessage * | msg | ) | [protected, virtual] |
handleTraceMessage gets called of handleMessage(cMessage* msg) if a message arrives at trace_in.
The command included in this message should be parsed and handled.
msg | the command message to handle |
Reimplemented from BaseApp.
00169 { 00170 char* cmd = new char[strlen(msg->name())]; 00171 strcpy(cmd, msg->name()); 00172 if (strncmp(cmd, "PUT ", 4) == 0) { 00173 // Generate key 00174 char* buf = cmd + 4; 00175 while (!isspace(buf[0])) { 00176 if ( buf[0] == '\0' ) throw new cException("Error parsing PUT command"); 00177 buf++; 00178 } 00179 buf[0] = '\0'; 00180 BinaryValue b(cmd+4); 00181 OverlayKey destKey(OverlayKey::sha1(b)); 00182 00183 // get value 00184 buf++; 00185 00186 // build putMsg 00187 DHTputCAPICall* dhtPutMsg = new DHTputCAPICall(); 00188 dhtPutMsg->setKey(destKey); 00189 dhtPutMsg->setValue(buf); 00190 dhtPutMsg->setTtl(DEFAULT_TTL); 00191 dhtPutMsg->setIsModifiable(true); 00192 00193 numSent++; 00194 numPutSent++; 00195 sendInternalRpcCall(TIER1_COMP, dhtPutMsg); 00196 delete cmd; 00197 } else if (strncmp(cmd, "GET ", 4) == 0) { 00198 // Get key 00199 BinaryValue b(cmd+4); 00200 OverlayKey key(OverlayKey::sha1(b)); 00201 00202 DHTgetCAPICall* dhtGetMsg = new DHTgetCAPICall(); 00203 dhtGetMsg->setKey(key); 00204 lastGetTime = simTime(); 00205 numSent++; 00206 numGetSent++; 00207 sendInternalRpcCall(TIER1_COMP, dhtGetMsg); 00208 } else { 00209 throw new cRuntimeError("Unknown trace command; " 00210 "only GET and PUT are allowed"); 00211 } 00212 }
void DHTTestApp::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( DHTputCAPI ) { 00095 handlePutResponse(_DHTputCAPIResponse); 00096 EV << "DHT Put RPC Response received: id=" << rpcId 00097 << " msg=" << *_DHTputCAPIResponse << " rtt=" << rtt << endl; 00098 break; 00099 } 00100 RPC_ON_RESPONSE( DHTgetCAPI ) { 00101 handleGetResponse(_DHTgetCAPIResponse); 00102 EV << "DHT Get RPC Response received: id=" << rpcId 00103 << " msg=" << *_DHTgetCAPIResponse << " rtt=" << rtt << endl; 00104 break; 00105 } 00106 RPC_SWITCH_END( ) 00107 }
UnderlayConfigurator* DHTTestApp::underlayConfigurator [protected] |
BootstrapOracle* DHTTestApp::bootstrapOracle [protected] |
GlobalStatistics* DHTTestApp::globalStatistics [protected] |
bool DHTTestApp::debugOutput [protected] |
double DHTTestApp::mean [protected] |
mean time interval between sending test messages
double DHTTestApp::deviation [protected] |
deviation of time interval
bool DHTTestApp::activeNetwInitPhase [protected] |
is app active in network init phase?
int DHTTestApp::numSent [protected] |
int DHTTestApp::numGetSent [protected] |
number of get sent
int DHTTestApp::numGetError [protected] |
number of false get responses
int DHTTestApp::numGetSuccess [protected] |
number of false get responses
int DHTTestApp::numPutSent [protected] |
number of put sent
int DHTTestApp::numPutError [protected] |
number of error in put responses
int DHTTestApp::numPutSuccess [protected] |
number of success in put responses
simtime_t DHTTestApp::lastPutTime [protected] |
simtime_t DHTTestApp::lastGetTime [protected] |