LifetimeChurn.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <algorithm>
00025
00026 #include "GlobalStatisticsAccess.h"
00027 #include "UnderlayConfigurator.h"
00028 #include "Churn_m.h"
00029
00030 #include "LifetimeChurn.h"
00031
00032 Define_Module(LifetimeChurn);
00033
00034 void LifetimeChurn::initializeChurn()
00035 {
00036 Enter_Method_Silent();
00037
00038 initialMean = par("initPhaseCreationInterval");
00039 initialDeviation = initialMean / 3;
00040 lifetimeMean = par("lifetimeMean");
00041 lifetimeDistName = par("lifetimeDistName").stdstringValue();
00042 lifetimeDistPar1 = par("lifetimeDistPar1");
00043
00044 WATCH(lifetimeMean);
00045
00046 globalStatistics = GlobalStatisticsAccess().get();
00047
00048 lastCreate = lastDelete = simTime();
00049
00050 simtime_t initFinishedTime = initialMean * targetOverlayTerminalNum;
00051
00052
00053 int targetOverlayTerminalNum = par("targetOverlayTerminalNum");
00054 for (int i = 0; i < targetOverlayTerminalNum; i++) {
00055
00056 scheduleCreateNodeAt(truncnormal(initialMean * i, initialDeviation),
00057 initFinishedTime + distributionFunction()
00058 - truncnormal(initialMean * i,
00059 initialDeviation));
00060
00061
00062 scheduleCreateNodeAt(initFinishedTime + distributionFunction(),
00063 distributionFunction());
00064 }
00065
00066 initFinishedTimer = new cMessage("initFinishedTimer");
00067
00068 scheduleAt(initFinishedTime, initFinishedTimer);
00069 }
00070
00071 void LifetimeChurn::handleMessage(cMessage* msg)
00072 {
00073 if (!msg->isSelfMessage()) {
00074 delete msg;
00075 return;
00076 }
00077
00078
00079 if (msg == initFinishedTimer) {
00080 underlayConfigurator->initFinished();
00081 cancelEvent(initFinishedTimer);
00082 delete initFinishedTimer;
00083 initFinishedTimer = NULL;
00084 return;
00085 }
00086
00087 ChurnMessage* churnMsg = check_and_cast<ChurnMessage*> (msg);
00088
00089 if (churnMsg->getCreateNode() == true) {
00090 createNode(churnMsg->getLifetime(), false);
00091 } else {
00092 deleteNode(churnMsg->getAddr());
00093 }
00094
00095 delete msg;
00096 }
00097
00098 void LifetimeChurn::createNode(simtime_t lifetime, bool initialize)
00099 {
00100
00101 ChurnMessage* churnMsg = new ChurnMessage("DeleteNode");
00102 TransportAddress* ta = underlayConfigurator->createNode(type, initialize);
00103 churnMsg->setAddr(*ta);
00104 delete ta;
00105 churnMsg->setCreateNode(false);
00106 scheduleAt(std::max(simTime(), simTime() + lifetime
00107 - underlayConfigurator->getGracefulLeaveDelay()), churnMsg);
00108
00109 RECORD_STATS(globalStatistics->recordOutVector(
00110 "LifetimeChurn: Session Time", SIMTIME_DBL(lifetime)));
00111 RECORD_STATS(globalStatistics->recordOutVector(
00112 "LifetimeChurn: Time between creates",
00113 SIMTIME_DBL(simTime() - lastCreate)));
00114
00115 lastCreate = simTime();
00116 }
00117
00118 void LifetimeChurn::deleteNode(TransportAddress& addr)
00119 {
00120 underlayConfigurator->preKillNode(NodeType(), &addr);
00121
00122 scheduleCreateNodeAt(simTime() + distributionFunction(),
00123 distributionFunction());
00124
00125 RECORD_STATS(globalStatistics->recordOutVector(
00126 "LifetimeChurn: Time between deletes",
00127 SIMTIME_DBL(simTime() - lastDelete)));
00128
00129 lastDelete = simTime();
00130 }
00131
00132 void LifetimeChurn::scheduleCreateNodeAt(simtime_t creationTime, simtime_t lifetime)
00133 {
00134 ChurnMessage* churnMsg = new ChurnMessage("CreateNode");
00135 churnMsg->setCreateNode(true);
00136 churnMsg->setLifetime(SIMTIME_DBL(lifetime));
00137 scheduleAt(creationTime, churnMsg);
00138 }
00139
00140 double LifetimeChurn::distributionFunction()
00141 {
00142 double par;
00143
00144 if (lifetimeDistName == "weibull") {
00145 par = lifetimeMean / tgamma(1 + (1 / lifetimeDistPar1));
00146 return weibull(par, lifetimeDistPar1);
00147 } else if (lifetimeDistName == "pareto_shifted") {
00148 par = lifetimeMean * (lifetimeDistPar1 - 1) / lifetimeDistPar1;
00149 return pareto_shifted(lifetimeDistPar1, par, 0);
00150 } else if (lifetimeDistName == "truncnormal") {
00151 par = lifetimeMean;
00152 return truncnormal(par, par/3.0);
00153 } else {
00154 opp_error("LifetimeChurn::distribution function: Invalid value "
00155 "for parameter lifetimeDistName!");
00156 }
00157
00158 return 0;
00159 }
00160
00161 void LifetimeChurn::updateDisplayString()
00162 {
00163 char buf[80];
00164 sprintf(buf, "lifetime churn");
00165 getDisplayString().setTagArg("t", 0, buf);
00166 }
00167
00168 LifetimeChurn::~LifetimeChurn()
00169 {
00170 cancelAndDelete(initFinishedTimer);
00171 }