OverSim
GlobalViewBuilder.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2010 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #include <iostream>
25 #include <fstream>
26 
27 #include <AbstractSendStrategy.h>
30 
31 #include "GlobalViewBuilder.h"
32 
34 
35  this->neighborCache = neighborCache;
36  this->overlay = overlay;
37  this->treeManager = neighborCache->getTreeManager();
38 
39  meanCoordSendInterval = neighborCache->par("gvbCoordSendInterval");
41 
42  capReady = false;
43  oldCcdSize = 0;
44  onlyAcceptCompleteCCD = neighborCache->par("gvbOnlyAcceptCompleteCCD");
45 
46  // initialize the send Strategy
47  activeStrategy = this->neighborCache->par("gvbSendStrategy").stdstringValue();
49  sendStrategy->initialize(this);
50 
51  coordSendTimer = new cMessage("coordSendTimer");
52  spreadCapTimer = new cMessage("spreadCapTimer");
53 
54  //start();
55 }
56 
57 
58 
60 {
61  neighborCache->cancelEvent(coordSendTimer);
62  neighborCache->scheduleAt(simTime() +
63  truncnormal(meanCoordSendInterval / 2.0, //TODO
64  deviation),
66 }
67 
68 
70 {
71  // TODO AbstractSendStrategy::initializeStrategy()
75 }
76 
77 
79 {
80  EV << "|DD|> GlobalViewBuilder::handleRpcCall (" << ") <||" << endl;
81 
82 
83  RPC_SWITCH_START( msg );
86  RPC_SWITCH_END( );
87 
88  //delete(msg);
89 
90  return RPC_HANDLED;
91 }
92 
94 {
95  if (overlay->getThisNode() == msg->getSrcNode()) {
96  //std::cout << treeManager->getCurrentTreeLevel() << " !!!" << std::endl;
97  delete msg;
98  return;
99  }
100  // CAP received
101  if (dynamic_cast<AreaDataCall*>(msg)) {
102  AreaDataCall* temp = static_cast<AreaDataCall*>(msg);
103  //treeManager->isParent(msg->getSrcNode())
105  (msg->getSrcNode() != treeManager->getParentNode())) {
106  std::cout << neighborCache->getThisNode().getIp()
107  << ": " << msg->getSrcNode().getIp() << " is not my parent! Deleting AreaDataCall!" << std::endl;
108  delete msg;
109  return;
110  }
111 
112  cap = temp->getAreaData().CBRAreaPool;
113  //std::vector<double> tempvec =
114  // neighborCache->getNcsAccess().getOwnNcsInfo().getCoords();
115  //for (uint8_t i = 0; i< tempvec.size(); ++i) {
116  // std::cout << tempvec[i] << std::endl;
117  //}
118  //std::cout << overlay->getThisNode().getKey() << " -> "
119  // << CoordBasedRoutingAccess().get()->getNodeId(tempvec, 4, 160, &cap) << "\n" << std::endl;
120 
121  neighborCache->getParentModule()->bubble("CAP received!");
122  capReady = true;
123 
124  AreaDataCall* newAreaCall = new AreaDataCall("AreaDataCall");
125  newAreaCall->setAreaData(temp->getAreaData());
126  newAreaCall->setBitLength(temp->getBitLength());
127 
128  //std::cout << treeManager->getCurrentTreeLevel() << std::endl;
129  treeManager->sendMessageToChildren(newAreaCall);
130  }
131  // coordinates received from child
132  else {
133  // check if this a child
134  if (treeManager->isChild(msg->getSrcNode())) {
136  } else {
137  //TODO do not delete msg if msg was sent to a key
138  std::cout << neighborCache->getThisNode().getIp()
139  << ": " << msg->getSrcNode().getIp() //<< " (" << msg->getDestKey()
140  << ") is no child of mine! Deleting Coordinates!" << std::endl;
141  delete msg;
142  return;
143  }
144  }
145 
146  GlobalViewBuilderResponse* gvbResponse = new GlobalViewBuilderResponse("GlobalViewBuilderResponse");
147  gvbResponse->setBitLength(GLOBALVIEWBUILDERRESPONSE_L(gvbResponse));
148 
149  neighborCache->sendRpcResponse(msg, gvbResponse);
150 }
151 
153 {
154  assert(!node.isUnspecified());
156  node,
157  new CapReqCall("CapRequestCall"),
158  NULL, DEFAULT_ROUTING, -1, 0, -1, this);
159 }
161  cPolymorphic* context,
162  int rpcId, simtime_t rtt)
163 {
164  RPC_SWITCH_START(msg)
165  RPC_ON_RESPONSE(CapReq) {
166  /*int bitsPerDigit = neighborCache->overlay->getBitsPerDigit();
167  neighborCache->thisNode.setKey(CoordBasedRoutingAccess().get()->getNodeId(neighborCache->getNcsAccess().getOwnNcsInfo().getCoords(),
168  bitsPerDigit,
169  OverlayKey::getLength(),
170  &_CapReqResponse->getAreaData().CBRAreaPool));
171 
172  EV << "[GlobalViewBuilder::handleRpcResponse() @ "
173  << neighborCache->thisNode.getIp()
174  << " (" << neighborCache->thisNode.getKey().toString(16) << ")]"
175  << "\n -> nodeID ( 2): "
176  << neighborCache->thisNode.getKey().toString(2)
177  << "\n -> nodeID (16): "
178  << neighborCache->thisNode.getKey().toString(16) << endl;
179 
180  // returning to BaseOverlay
181  neighborCache->overlay->join(neighborCache->thisNode.getKey());*/
182  cap = _CapReqResponse->getAreaData().CBRAreaPool;
183  //if (cap.size() > 0) //TODO
184  capReady = true; //TODO
186  }
187  RPC_SWITCH_END( )
188 }
189 
190 
192  const TransportAddress& dest,
193  cPolymorphic* context, int rpcId,
194  const OverlayKey& destKey)
195 {
196  std::cout << "THIS SHOULD NOT HAPPEN!!!" << std::endl;
197  assert(false);
198 }
199 
200 
202 {
203  AreaDataContainer tmpAreaDataContainer;
204  tmpAreaDataContainer.CBRAreaPool = cap;
205  CapReqResponse* response = new CapReqResponse();
206  response->setAreaData(tmpAreaDataContainer);
207  neighborCache->sendRpcResponse(call, response);
208 }
209 
211 {
212  if (msg == spreadCapTimer) {
213  if (treeManager->isRoot()) {
215  } else {
216  //std::cout << "msg == spreadCapTimer && !treeManager->isRoot()" << std::endl;
217  }
218  } else if (msg == coordSendTimer) {
219  //neighborCache->cancelEvent(spreadCapTimer);
221  }
222 }
223 
225 {
226  neighborCache->cancelEvent(msg);
227  neighborCache->scheduleAt(simTime() + meanCoordSendInterval,
228  //truncnormal(meanCoordSendInterval, deviation),
229  msg);
230 
231  const NodeHandle& thisNode = this->neighborCache->overlay->getThisNode();
232  if(thisNode.isUnspecified()) {
233  return;
234  }
235 
239 
241  std::stringstream nodeState;
242  nodeState.str("");
243  nodeState << "LVL: ";
244  nodeState << treeManager->getCurrentTreeLevel();
245  nodeState << ": ";
246  nodeState << sendStrategy->getStrategyDataStatus();
247 
248  if (!treeManager->isRoot() /*neighborCache->getTreeManager()->getParentNode().getKey() !=
249  neighborCache->overlay->getThisNode().getKey()*/) {
251  } else {
252  // this node is root
253  if(checkOverlayReady() == true) {
254  EV << "|DD|> GlobalViewBuilder::handleCoordSendTimer ("
255  << "Spread GlobaLViewData" << ") <||" << endl;
256  // wait some seconds before spreading the CAP
257  neighborCache->cancelEvent(spreadCapTimer);
258  neighborCache->scheduleAt(simTime() + 10, spreadCapTimer); //TODO parameter
259  //spreadGlobalView();
260  }
261  }
262 
263  //std::cout << treeManager->getCurrentTreeLevel() << "\n"
264  // << sendStrategy->getStrategyDataStatus() << std::endl;
265 
266  neighborCache->getParentModule()->getDisplayString().setTagArg("t", 0, nodeState.str().c_str());
267  } else {
268  std::cout << simTime() << " @ "
270  << ": I have no parent :-(" << std::endl;
272  }
273 }
274 
275 
277 {
278  //handleCoordSendTimer(coordSendTimer);
279 }
280 
281 
283 {
285  //return UnderlayConfiguratorAccess().get()->isTransitionTimeFinished() && !UnderlayConfiguratorAccess().get()->isInInitPhase();
286 }
287 
288 
290 {
292  //std::cout << "CCD: " << ccd.size() << std::endl;
293  uint32_t tempSize = 0;
294  if ((oldCcdSize == 0) ||
295  ((ccd.size() < (oldCcdSize * 1.5)) &&
296  (ccd.size() > (oldCcdSize * 0.5)))) {
297  tempSize = oldCcdSize;
298  oldCcdSize = ccd.size();
299  }
300 
302 
303  //special case: only accept complete CCD
304  if (onlyAcceptCompleteCCD &&
305  ((int)ccd.size() !=
307  EV << "[GlobalViewBuilder::spreadGlobalView() @ "
308  << overlay->getThisNode().getIp()
309  << " (" << overlay->getThisNode().getKey().toString(16)
310  << ")]\n CAP.size() " << ccd.size()
311  << " != numTerminalCount: no spreading!" << endl;
312  std::cout << "[GlobalViewBuilder::spreadGlobalView() @ "
313  << overlay->getThisNode().getIp()
314  << " (" << overlay->getThisNode().getKey().toString(16)
315  << ")]\n CCD.size() " << ccd.size()
316  << " != numTerminalCount: no spreading!" << std::endl;
317  return;
318  } else if (cbr->changeIdLater() &&
319  (simTime() > cbr->getChangeIdStart()) &&
320  (simTime() < (cbr->getChangeIdStop() + 3000))) {
321  EV << "[GlobalViewBuilder::spreadGlobalView() @ "
322  << overlay->getThisNode().getIp()
323  << " (" << overlay->getThisNode().getKey().toString(16)
324  << ")]\n CAP.size() " << ccd.size()
325  << " in id change phase, no spreading" << endl;
326  std::cout << "[GlobalViewBuilder::spreadGlobalView() @ "
327  << overlay->getThisNode().getIp()
328  << " (" << overlay->getThisNode().getKey().toString(16)
329  << ")]\n CAP.size() " << ccd.size()
330  << " in id change phase, no spreading" << std::endl;
331  return;
332 
333  } else tempSize = oldCcdSize = ccd.size();
334 
335  //std::cout << "tempSize: " << tempSize << std::endl;
336  // CCD size check
337  if ((ccd.size() > (tempSize * 1.2)) ||
338  (ccd.size() < (tempSize * 0.8))) {
339  EV << "[GlobalViewBuilder::spreadGlobalView() @ "
340  << overlay->getThisNode().getIp()
341  << " (" << overlay->getThisNode().getKey().toString(16)
342  << ")]\n CAP.size() is too fluctuant: no spreading!" << endl;
343  std::cout << "[GlobalViewBuilder::spreadGlobalView() @ "
344  << overlay->getThisNode().getIp()
345  << " (" << overlay->getThisNode().getKey().toString(16)
346  << ")]\n CAP.size() is too fluctuant: no spreading!" << std::endl;
347  return;
348  }
349 
350  /*
351  for (uint i = 0; i < ccd.size(); ++i) {
352  std::cout << ccd[i] << ", ";
353  }
354  std::cout << std::endl;
355 
356  uint32_t overlaySize = overlay->estimateOverlaySize();
357  if ((ccd.size() > (2.0 * overlaySize)) ||
358  (ccd.size() < (0.5 * overlaySize))) {
359  //oldCcdSize = ccd.size();
360  std::cout << "CCD: " << ccd.size()
361  << ", overlay->estimateOverlaySize(): " << overlaySize
362  << std::endl;
363  //return;
364  }
365  */
366 
367  //tmpAreaDataContainer.CBRAreaPool = c2aAdapter->getCBRAreas();
368 
369  /*
370  std::cout << "\n\n\nGlobalViewBuilder::spreadGlobalView(): The CCD with size = " << coordsVec.size() << ":" << std::endl;
371  for (uint32_t i = 0; i < coordsVec.size(); ++i) {
372  std::cout << coordsVec[i] << " ";
373  }
374  std::cout << endl;
375  */
376 
377  const AP* cap =
380 
381  /*
382  C2AAdapter* c2aAdapter = C2AAdapter::getInstance();
383  c2aAdapter->initialize(this, sendStrategy->getStrategyCombinedParams());
384  c2aAdapter->setCoordinates(coordsVec);
385  c2aAdapter->createAreas();
386 
387  const AP cap_test = c2aAdapter->getCBRAreas();
388 
389  std::cout << " >----- " << cap->size() << std::endl;
390  //assert (cap_test.size() == cap->size());
391  std::cout << "#nodes: " << coordsVec.size() << ", #areas: " << cap->size() << std::endl;
392  for (uint32_t i = 0; i < cap->size(); ++i) {
393  std::cout << cap->at(i)->prefix << " ("
394  << cap->at(i)->min[0] << ", "
395  << cap->at(i)->min[1] << ") - ("
396  << cap->at(i)->max[0] << ", "
397  << cap->at(i)->max[1] << ")"
398  << std::endl;
399  }
400 
401  std::cout << " ----- " << cap_test.size() << std::endl;
402  for (uint32_t i = 0; i < cap_test.size(); ++i) {
403  std::cout << cap_test[i]->prefix << " ("CBRArea
404  << cap_test[i]->min[0] << ", "
405  << cap_test[i]->min[1] << ") - ("
406  << cap_test[i]->max[0] << ", "
407  << cap_test[i]->max[1] << ")"
408  << std::endl;
409  }
410  std::cout << " -----< " << std::endl;
411  */
412 
413  if (cap == NULL) {
414  EV << "[GlobalViewBuilder::spreadGlobalView() @ " << overlay->getThisNode().getIp()
415  << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
416  << " No CAP available for spreading!" << endl;
417  std::cout << "[GlobalViewBuilder::spreadGlobalView() @ " << overlay->getThisNode().getIp()
418  << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
419  << " No CAP available for spreading!" << std::endl;
420  return;
421  }
422 
423 
424  // measurement of CAP size
425  /*
426  std::fstream f;
427  std::string name("CAP_");
428  name += simTime().str();
429  name += ".bin";
430  f.open(name.c_str(), std::ios::binary|std::ios::out);
431 
432  for (uint32_t i = 0; i < cap->size(); ++i) {
433  f.write((char*)&(cap->at(i).prefix), sizeof(cap->at(i).prefix));
434  f.write((char*)&(cap->at(i).min[0]), sizeof(cap->at(i).min[0]));
435  f.write((char*)&(cap->at(i).min[1]), sizeof(cap->at(i).min[1]));
436  f.write((char*)&(cap->at(i).max[0]), sizeof(cap->at(i).max[0]));
437  f.write((char*)&(cap->at(i).max[1]), sizeof(cap->at(i).max[1]));
438  }
439  f.close();
440  */
441 
442  AreaDataCall* msg = new AreaDataCall("AreaDataCall");
443  AreaDataContainer tmpAreaDataContainer;
444 
445  tmpAreaDataContainer.CBRAreaPool = *cap;
446  delete cap;
447 
448  std::cout << "\n " << simTime() << " CCD @ "
450  << ": size = " << ccd.size() << "\n" << std::endl;
451 
452  msg->setAreaData(tmpAreaDataContainer);
454 
455  neighborCache->globalStatistics->addStdDev("GlobalViewBuilder: CCD size",
456  ccd.size());
457 }
458 
459 
460 cPar& GlobalViewBuilder::parProxy(const char *parname)
461 {
462  return neighborCache->par(parname);
463 }
464