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 contextVector.assign(2*targetOverlayTerminalNum, (cObject*)NULL);
00055
00056 for (int i = 0; i < targetOverlayTerminalNum; i++) {
00057
00058 scheduleCreateNodeAt(truncnormal(initialMean * i, initialDeviation),
00059 initFinishedTime + distributionFunction()
00060 - truncnormal(initialMean * i,
00061 initialDeviation), i);
00062
00063
00064 scheduleCreateNodeAt(initFinishedTime + distributionFunction(),
00065 distributionFunction(), targetOverlayTerminalNum + i);
00066 }
00067
00068 initFinishedTimer = new cMessage("initFinishedTimer");
00069
00070 scheduleAt(initFinishedTime, initFinishedTimer);
00071 }
00072
00073 void LifetimeChurn::handleMessage(cMessage* msg)
00074 {
00075 if (!msg->isSelfMessage()) {
00076 delete msg;
00077 return;
00078 }
00079
00080
00081 if (msg == initFinishedTimer) {
00082 underlayConfigurator->initFinished();
00083 cancelEvent(initFinishedTimer);
00084 delete initFinishedTimer;
00085 initFinishedTimer = NULL;
00086 return;
00087 }
00088
00089 ChurnMessage* churnMsg = check_and_cast<ChurnMessage*> (msg);
00090
00091 if (churnMsg->getCreateNode() == true) {
00092 createNode(churnMsg->getLifetime(), false, churnMsg->getContextPos());
00093 } else {
00094 deleteNode(churnMsg->getAddr(), churnMsg->getContextPos());
00095 }
00096
00097 delete msg;
00098 }
00099
00100 void LifetimeChurn::createNode(simtime_t lifetime, bool initialize,
00101 int contextPos)
00102 {
00103
00104 ChurnMessage* churnMsg = new ChurnMessage("DeleteNode");
00105 NodeType createType = type;
00106 createType.context = &(contextVector[contextPos]);
00107 TransportAddress* ta = underlayConfigurator->createNode(createType, initialize);
00108 churnMsg->setAddr(*ta);
00109 churnMsg->setContextPos(contextPos);
00110 delete ta;
00111 churnMsg->setCreateNode(false);
00112 scheduleAt(std::max(simTime(), simTime() + lifetime
00113 - underlayConfigurator->getGracefulLeaveDelay()), churnMsg);
00114
00115 RECORD_STATS(globalStatistics->recordOutVector(
00116 "LifetimeChurn: Session Time", SIMTIME_DBL(lifetime)));
00117 RECORD_STATS(globalStatistics->recordOutVector(
00118 "LifetimeChurn: Time between creates",
00119 SIMTIME_DBL(simTime() - lastCreate)));
00120
00121 lastCreate = simTime();
00122 }
00123
00124 void LifetimeChurn::deleteNode(TransportAddress& addr, int contextPos)
00125 {
00126 underlayConfigurator->preKillNode(NodeType(), &addr);
00127
00128 scheduleCreateNodeAt(simTime() + distributionFunction(),
00129 distributionFunction(), contextPos);
00130
00131 RECORD_STATS(globalStatistics->recordOutVector(
00132 "LifetimeChurn: Time between deletes",
00133 SIMTIME_DBL(simTime() - lastDelete)));
00134
00135 lastDelete = simTime();
00136 }
00137
00138 void LifetimeChurn::scheduleCreateNodeAt(simtime_t creationTime,
00139 simtime_t lifetime, int contextPos)
00140 {
00141 ChurnMessage* churnMsg = new ChurnMessage("CreateNode");
00142 churnMsg->setCreateNode(true);
00143 churnMsg->setLifetime(SIMTIME_DBL(lifetime));
00144 churnMsg->setContextPos(contextPos);
00145 scheduleAt(creationTime, churnMsg);
00146 }
00147
00148 double LifetimeChurn::distributionFunction()
00149 {
00150 double par;
00151
00152 if (lifetimeDistName == "weibull") {
00153 par = lifetimeMean / tgamma(1 + (1 / lifetimeDistPar1));
00154 return weibull(par, lifetimeDistPar1);
00155 } else if (lifetimeDistName == "pareto_shifted") {
00156 par = lifetimeMean * (lifetimeDistPar1 - 1) / lifetimeDistPar1;
00157 return pareto_shifted(lifetimeDistPar1, par, 0);
00158 } else if (lifetimeDistName == "truncnormal") {
00159 par = lifetimeMean;
00160 return truncnormal(par, par/3.0);
00161 } else {
00162 opp_error("LifetimeChurn::distribution function: Invalid value "
00163 "for parameter lifetimeDistName!");
00164 }
00165
00166 return 0;
00167 }
00168
00169 void LifetimeChurn::updateDisplayString()
00170 {
00171 char buf[80];
00172 sprintf(buf, "lifetime churn");
00173 getDisplayString().setTagArg("t", 0, buf);
00174 }
00175
00176 LifetimeChurn::~LifetimeChurn()
00177 {
00178 cancelAndDelete(initFinishedTimer);
00179 for (std::vector<cObject*>::iterator it = contextVector.begin();
00180 it != contextVector.end(); it++) {
00181 if (*it) {
00182 delete *it;
00183 }
00184 }
00185
00186 }