## root / src / eventlog / sequencechartfacade.cc @ 8aeaaccc

History | View | Annotate | Download (38.2 KB)

1 | 01873262 | Georg Kunz | ```
//=========================================================================
``` |
---|---|---|---|

2 | ```
// SEQUENCECHARTFACADE.CC - part of
``` |
||

3 | ```
// OMNeT++/OMNEST
``` |
||

4 | ```
// Discrete System Simulation in C++
``` |
||

5 | ```
//
``` |
||

6 | ```
// Author: Levente Meszaros
``` |
||

7 | ```
//
``` |
||

8 | ```
//=========================================================================
``` |
||

9 | |||

10 | ```
/*--------------------------------------------------------------*
``` |
||

11 | ```
Copyright (C) 2006-2008 OpenSim Ltd.
``` |
||

12 | |||

13 | ```
This file is distributed WITHOUT ANY WARRANTY. See the file
``` |
||

14 | ```
`license' for details on this and other legal matters.
``` |
||

15 | ```
*--------------------------------------------------------------*/
``` |
||

16 | |||

17 | #include <stdio.h> |
||

18 | #include <algorithm> |
||

19 | #include <set> |
||

20 | #include <math.h> |
||

21 | #include "lcgrandom.h" |
||

22 | #include "ievent.h" |
||

23 | #include "ieventlog.h" |
||

24 | #include "event.h" |
||

25 | #include "messagedependency.h" |
||

26 | #include "sequencechartfacade.h" |
||

27 | |||

28 | USING_NAMESPACE |
||

29 | |||

30 | SequenceChartFacade::SequenceChartFacade(IEventLog *eventLog) : EventLogFacade(eventLog) |
||

31 | { |
||

32 | timelineMode = NONLINEAR; |
||

33 | ```
timelineCoordinateSystemVersion = -1;
``` |
||

34 | undefineTimelineCoordinateSystem(); |
||

35 | |||

36 | nonLinearMinimumTimelineCoordinateDelta = 0.1; |
||

37 | setNonLinearFocus(calculateNonLinearFocus()); |
||

38 | daf081df | Simon Tenbusch | |

39 | ```
smallestComplexity = -1;
``` |
||

40 | ```
largestComplexity = -1;
``` |
||

41 | ced95c57 | Simon Tenbusch | |

42 | ```
smallestDuration = -1;
``` |
||

43 | ```
largestDuration = -1;
``` |
||

44 | 1c72663d | Simon Tenbusch | |

45 | cachedParallelSet.clear(); |
||

46 | a3b7e786 | Simon Tenbusch | cachedCriticalPath.clear(); |

47 | 01873262 | Georg Kunz | } |

48 | |||

49 | ```
void SequenceChartFacade::synchronize(FileReader::FileChangedState change)
``` |
||

50 | { |
||

51 | ```
if (change != FileReader::UNCHANGED) {
``` |
||

52 | EventLogFacade::synchronize(change); |
||

53 | |||

54 | setNonLinearFocus(calculateNonLinearFocus()); |
||

55 | |||

56 | if (timelineCoordinateOriginEventNumber != -1) { |
||

57 | IEvent *event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber); |
||

58 | |||

59 | ```
if (event)
``` |
||

60 | relocateTimelineCoordinateSystem(event); |
||

61 | ```
else
``` |
||

62 | undefineTimelineCoordinateSystem(); |
||

63 | } |
||

64 | } |
||

65 | } |
||

66 | |||

67 | ```
double SequenceChartFacade::calculateNonLinearFocus()
``` |
||

68 | { |
||

69 | ```
if (!eventLog->isEmpty()) {
``` |
||

70 | ```
double lastEventSimulationTime = eventLog->getLastEvent()->getSimulationTime().dbl();
``` |
||

71 | ```
double firstEventSimulationTime = eventLog->getFirstEvent()->getSimulationTime().dbl();
``` |
||

72 | ```
double totalSimulationTimeDelta = lastEventSimulationTime - firstEventSimulationTime;
``` |
||

73 | |||

74 | if (totalSimulationTimeDelta == 0) |
||

75 | totalSimulationTimeDelta = firstEventSimulationTime; |
||

76 | |||

77 | if (totalSimulationTimeDelta == 0) |
||

78 | return 1; |
||

79 | ```
else
``` |
||

80 | return totalSimulationTimeDelta / eventLog->getApproximateNumberOfEvents() / 10; |
||

81 | } |
||

82 | ```
else
``` |
||

83 | return 1; |
||

84 | } |
||

85 | |||

86 | void SequenceChartFacade::setNonLinearMinimumTimelineCoordinateDelta(double value) |
||

87 | { |
||

88 | ```
Assert(value >= 0);
``` |
||

89 | nonLinearMinimumTimelineCoordinateDelta = value; |
||

90 | } |
||

91 | |||

92 | void SequenceChartFacade::setNonLinearFocus(double nonLinearFocus) |
||

93 | { |
||

94 | ```
Assert(nonLinearFocus >= 0);
``` |
||

95 | ```
this->nonLinearFocus = nonLinearFocus;
``` |
||

96 | } |
||

97 | |||

98 | ```
void SequenceChartFacade::undefineTimelineCoordinateSystem()
``` |
||

99 | { |
||

100 | timelineCoordinateSystemVersion++; |
||

101 | ```
timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = -1;
``` |
||

102 | timelineCoordinateOriginSimulationTime = simtime_nil; |
||

103 | bcffd494 | Simon Tenbusch | ```
timelineCoordinateOriginRealTime = 0;
``` |

104 | 01873262 | Georg Kunz | } |

105 | |||

106 | ```
void SequenceChartFacade::relocateTimelineCoordinateSystem(IEvent *event)
``` |
||

107 | { |
||

108 | Assert(event); |
||

109 | |||

110 | timelineCoordinateSystemVersion++; |
||

111 | timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = event->getEventNumber(); |
||

112 | timelineCoordinateOriginSimulationTime = event->getSimulationTime(); |
||

113 | 0596ce67 | Simon Tenbusch | timelineCoordinateOriginRealTime = event->getEarliestStartTime() / 1000000.0; |

114 | 01873262 | Georg Kunz | ```
event->cachedTimelineCoordinate = 0;
``` |

115 | event->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion; |
||

116 | } |
||

117 | |||

118 | ```
void SequenceChartFacade::setTimelineMode(TimelineMode timelineMode)
``` |
||

119 | { |
||

120 | ```
this->timelineMode = timelineMode;
``` |
||

121 | |||

122 | if (timelineCoordinateOriginEventNumber != -1) |
||

123 | relocateTimelineCoordinateSystem(eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber)); |
||

124 | } |
||

125 | |||

126 | ```
double SequenceChartFacade::IEvent_getTimelineCoordinate(ptr_t ptr)
``` |
||

127 | { |
||

128 | IEVENT_PTR(ptr); |
||

129 | ```
return getTimelineCoordinate((IEvent*)ptr);
``` |
||

130 | } |
||

131 | |||

132 | 382d8398 | Simon Tenbusch | ```
double SequenceChartFacade::IEvent_getTimelineEventEndCoordinate(ptr_t ptr)
``` |

133 | { |
||

134 | IEVENT_PTR(ptr); |
||

135 | ```
return getTimelineEventEndCoordinate((IEvent*)ptr);
``` |
||

136 | } |
||

137 | |||

138 | 01873262 | Georg Kunz | double SequenceChartFacade::getTimelineCoordinateDelta(double simulationTimeDelta) |

139 | { |
||

140 | ```
Assert(nonLinearFocus > 0);
``` |
||

141 | |||

142 | ```
if (timelineMode == STEP)
``` |
||

143 | return 1; |
||

144 | ```
else
``` |
||

145 | return nonLinearMinimumTimelineCoordinateDelta + (1 - nonLinearMinimumTimelineCoordinateDelta) * atan(fabs(simulationTimeDelta) / nonLinearFocus) / PI * 2; |
||

146 | } |
||

147 | |||

148 | double SequenceChartFacade::getTimelineCoordinate(ptr_t ptr, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) |
||

149 | { |
||

150 | IEVENT_PTR(ptr); |
||

151 | ```
return getTimelineCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);
``` |
||

152 | } |
||

153 | |||

154 | 382d8398 | Simon Tenbusch | double SequenceChartFacade::getTimelineEventEndCoordinate(ptr_t ptr, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) |

155 | { |
||

156 | IEVENT_PTR(ptr); |
||

157 | ```
return getTimelineEventEndCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);
``` |
||

158 | } |
||

159 | |||

160 | 01873262 | Georg Kunz | double SequenceChartFacade::getTimelineCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) |

161 | { |
||

162 | Assert(event); |
||

163 | Assert(event->getEventLog() == eventLog); |
||

164 | ```
Assert(timelineCoordinateSystemVersion != -1);
``` |
||

165 | ```
Assert(timelineCoordinateOriginEventNumber != -1);
``` |
||

166 | |||

167 | if (this->timelineCoordinateSystemVersion > event->cachedTimelineCoordinateSystemVersion) { |
||

168 | ```
double timelineCoordinate;
``` |
||

169 | |||

170 | ```
switch (timelineMode) {
``` |
||

171 | bcffd494 | Simon Tenbusch | ```
case REAL_TIME:
``` |

172 | 0596ce67 | Simon Tenbusch | timelineCoordinate = ((event->getEarliestStartTime()/1000000.0 - timelineCoordinateOriginRealTime)); |

173 | bcffd494 | Simon Tenbusch | ```
break;
``` |

174 | 01873262 | Georg Kunz | ```
case SIMULATION_TIME:
``` |

175 | timelineCoordinate = (event->getSimulationTime() - timelineCoordinateOriginSimulationTime).dbl(); |
||

176 | ```
break;
``` |
||

177 | ```
case EVENT_NUMBER:
``` |
||

178 | timelineCoordinate = event->getEventNumber() - timelineCoordinateOriginEventNumber; |
||

179 | ```
break;
``` |
||

180 | ```
case STEP:
``` |
||

181 | ```
case NONLINEAR:
``` |
||

182 | { |
||

183 | ```
IEvent *previousEvent = NULL;
``` |
||

184 | ```
// do we go forward from end or backward from start of known range
``` |
||

185 | ```
bool forward = event->getEventNumber() > timelineCoordinateRangeEndEventNumber;
``` |
||

186 | IEvent *currentEvent = eventLog->getEventForEventNumber(forward ? timelineCoordinateRangeEndEventNumber : timelineCoordinateRangeStartEventNumber); |
||

187 | |||

188 | Assert(event->getEventNumber() < timelineCoordinateRangeStartEventNumber || timelineCoordinateRangeEndEventNumber < event->getEventNumber()); |
||

189 | |||

190 | ```
// TODO: LONG RUNNING OPERATION
``` |
||

191 | ```
// does a linear search towards the event to calculate the non linear timeline coordinate
``` |
||

192 | ```
do {
``` |
||

193 | eventLog->progress(); |
||

194 | |||

195 | Assert(currentEvent); |
||

196 | previousEvent = currentEvent; |
||

197 | currentEvent = forward ? currentEvent->getNextEvent() : currentEvent->getPreviousEvent(); |
||

198 | Assert(currentEvent); |
||

199 | |||

200 | simtime_t previousSimulationTime = previousEvent->getSimulationTime(); |
||

201 | ```
double previousTimelineCoordinate = previousEvent->cachedTimelineCoordinate;
``` |
||

202 | simtime_t simulationTime = currentEvent->getSimulationTime(); |
||

203 | ```
double timelineCoordinateDelta = getTimelineCoordinateDelta((simulationTime - previousSimulationTime).dbl());
``` |
||

204 | |||

205 | ```
if (forward) {
``` |
||

206 | timelineCoordinate = previousTimelineCoordinate + timelineCoordinateDelta; |
||

207 | |||

208 | ```
if (timelineCoordinate > upperTimelineCoordinateCalculationLimit)
``` |
||

209 | ```
return NaN;
``` |
||

210 | } |
||

211 | ```
else {
``` |
||

212 | timelineCoordinate = previousTimelineCoordinate - timelineCoordinateDelta; |
||

213 | |||

214 | ```
if (timelineCoordinate < lowerTimelineCoordinateCalculationLimit)
``` |
||

215 | ```
return NaN;
``` |
||

216 | } |
||

217 | |||

218 | currentEvent->cachedTimelineCoordinate = timelineCoordinate; |
||

219 | currentEvent->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion; |
||

220 | } |
||

221 | ```
while (currentEvent != event);
``` |
||

222 | |||

223 | ```
if (forward)
``` |
||

224 | timelineCoordinateRangeEndEventNumber = event->getEventNumber(); |
||

225 | ```
else
``` |
||

226 | timelineCoordinateRangeStartEventNumber = event->getEventNumber(); |
||

227 | } |
||

228 | ```
break;
``` |
||

229 | ```
default:
``` |
||

230 | throw opp_runtime_error("Unknown timeline mode"); |
||

231 | } |
||

232 | |||

233 | event->cachedTimelineCoordinate = timelineCoordinate; |
||

234 | event->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion; |
||

235 | } |
||

236 | |||

237 | ```
return event->cachedTimelineCoordinate;
``` |
||

238 | } |
||

239 | |||

240 | 382d8398 | Simon Tenbusch | double SequenceChartFacade::getTimelineEventEndCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) |

241 | { |
||

242 | Assert(event); |
||

243 | Assert(event->getEventLog() == eventLog); |
||

244 | ```
if(!eventLog->isLegacyTrace()) {
``` |
||

245 | ```
return getTimelineCoordinate(event);
``` |
||

246 | } |
||

247 | ```
double timelineEventEndCoordinate;
``` |
||

248 | ```
switch (timelineMode) {
``` |
||

249 | bcffd494 | Simon Tenbusch | ```
case REAL_TIME:
``` |

250 | 0596ce67 | Simon Tenbusch | timelineEventEndCoordinate = (event->getEarliestProcessingTime()/ 1000000.0 - timelineCoordinateOriginRealTime) ; |

251 | bcffd494 | Simon Tenbusch | ```
break;
``` |

252 | 382d8398 | Simon Tenbusch | ```
case SIMULATION_TIME:
``` |

253 | timelineEventEndCoordinate = (event->getSimulationTime()+event->getEventEntry()->duration - timelineCoordinateOriginSimulationTime).dbl(); |
||

254 | ```
break;
``` |
||

255 | ```
default:
``` |
||

256 | ```
return getTimelineCoordinate(event);
``` |
||

257 | } |
||

258 | ```
return timelineEventEndCoordinate;
``` |
||

259 | } |
||

260 | |||

261 | 01873262 | Georg Kunz | ```
double SequenceChartFacade::getCachedTimelineCoordinate(IEvent *event)
``` |

262 | { |
||

263 | Assert(event); |
||

264 | ```
Assert(timelineCoordinateSystemVersion != -1);
``` |
||

265 | ```
Assert(timelineCoordinateOriginEventNumber != -1);
``` |
||

266 | |||

267 | if (this->timelineCoordinateSystemVersion > event->cachedTimelineCoordinateSystemVersion) |
||

268 | return -1; |
||

269 | ```
else
``` |
||

270 | ```
return event->cachedTimelineCoordinate;
``` |
||

271 | } |
||

272 | |||

273 | IEvent *SequenceChartFacade::getEventForNonLinearTimelineCoordinate(double timelineCoordinate, bool &forward) |
||

274 | { |
||

275 | ```
Assert(timelineCoordinateOriginEventNumber != -1);
``` |
||

276 | IEvent *timelineCoordinateRangeStartEvent = eventLog->getEventForEventNumber(timelineCoordinateRangeStartEventNumber); |
||

277 | IEvent *timelineCoordinateRangeEndEvent = eventLog->getEventForEventNumber(timelineCoordinateRangeEndEventNumber); |
||

278 | IEvent *currentEvent; |
||

279 | |||

280 | Assert(timelineCoordinateRangeStartEvent && timelineCoordinateRangeEndEvent); |
||

281 | |||

282 | ```
if (timelineCoordinate <= getTimelineCoordinate(timelineCoordinateRangeStartEvent)) {
``` |
||

283 | ```
forward = false;
``` |
||

284 | currentEvent = timelineCoordinateRangeStartEvent; |
||

285 | } |
||

286 | else if (getTimelineCoordinate(timelineCoordinateRangeEndEvent) <= timelineCoordinate) { |
||

287 | ```
forward = true;
``` |
||

288 | currentEvent = timelineCoordinateRangeEndEvent; |
||

289 | } |
||

290 | ```
else {
``` |
||

291 | ```
forward = true;
``` |
||

292 | currentEvent = timelineCoordinateRangeStartEvent; |
||

293 | } |
||

294 | |||

295 | ```
// TODO: LONG RUNNING OPERATION
``` |
||

296 | ```
// does a linear search towards requested non linear timeline coordinate
``` |
||

297 | ```
while (currentEvent && (forward ? getTimelineCoordinate(currentEvent) < timelineCoordinate :
``` |
||

298 | timelineCoordinate <= getTimelineCoordinate(currentEvent))) |
||

299 | { |
||

300 | eventLog->progress(); |
||

301 | currentEvent = forward ? currentEvent->getNextEvent() : currentEvent->getPreviousEvent(); |
||

302 | } |
||

303 | |||

304 | ```
return currentEvent;
``` |
||

305 | } |
||

306 | |||

307 | ```
IEvent *SequenceChartFacade::getLastEventNotAfterTimelineCoordinate(double timelineCoordinate)
``` |
||

308 | { |
||

309 | ```
if (eventLog->isEmpty())
``` |
||

310 | return NULL; |
||

311 | |||

312 | ```
switch (timelineMode) {
``` |
||

313 | bcffd494 | Simon Tenbusch | ```
case REAL_TIME:
``` |

314 | { |
||

315 | ```
//TODO MAKE THIS MORE EFFICIENT (i.e. sorted data structure)!
``` |
||

316 | IEvent* res = eventLog->getFirstEvent(); |
||

317 | ```
for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
``` |
||

318 | 0596ce67 | Simon Tenbusch | if ((double) current->getEarliestStartTime() / 1000000.0 < timelineCoordinate) { |

319 | bcffd494 | Simon Tenbusch | ```
if (current->getEarliestStartTime() > res->getEarliestStartTime()) {
``` |

320 | res = current; |
||

321 | } |
||

322 | } |
||

323 | } |
||

324 | ```
return res;
``` |
||

325 | } |
||

326 | 01873262 | Georg Kunz | ```
case SIMULATION_TIME:
``` |

327 | ```
return eventLog->getLastEventNotAfterSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
``` |
||

328 | ```
case EVENT_NUMBER:
``` |
||

329 | { |
||

330 | eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber; |
||

331 | |||

332 | if (eventNumber < 0) |
||

333 | return NULL; |
||

334 | ```
else
``` |
||

335 | ```
return eventLog->getLastEventNotAfterEventNumber(eventNumber);
``` |
||

336 | } |
||

337 | ```
case STEP:
``` |
||

338 | ```
case NONLINEAR:
``` |
||

339 | { |
||

340 | ```
bool forward;
``` |
||

341 | IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward); |
||

342 | currentEvent = forward ? (currentEvent ? currentEvent->getPreviousEvent() : eventLog->getLastEvent()) : currentEvent; |
||

343 | |||

344 | Assert(!currentEvent || getTimelineCoordinate(currentEvent) <= timelineCoordinate); |
||

345 | ```
return currentEvent;
``` |
||

346 | } |
||

347 | ```
default:
``` |
||

348 | throw opp_runtime_error("Unknown timeline mode"); |
||

349 | } |
||

350 | } |
||

351 | |||

352 | ```
IEvent *SequenceChartFacade::getFirstEventNotBeforeTimelineCoordinate(double timelineCoordinate)
``` |
||

353 | { |
||

354 | ```
if (eventLog->isEmpty())
``` |
||

355 | return NULL; |
||

356 | |||

357 | ```
switch (timelineMode) {
``` |
||

358 | bcffd494 | Simon Tenbusch | ```
case REAL_TIME:
``` |

359 | { |
||

360 | ```
//TODO MAKE THIS MORE EFFICIENT (i.e. sorted data structure)!
``` |
||

361 | IEvent* res = eventLog->getLastEvent(); |
||

362 | ```
for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
``` |
||

363 | 0596ce67 | Simon Tenbusch | if ((double) current->getEarliestStartTime() / 1000000.0 > timelineCoordinate) { |

364 | bcffd494 | Simon Tenbusch | ```
if (current->getEarliestStartTime() < res->getEarliestStartTime()) {
``` |

365 | res = current; |
||

366 | } |
||

367 | } |
||

368 | } |
||

369 | ```
return res;
``` |
||

370 | } |
||

371 | 01873262 | Georg Kunz | ```
case SIMULATION_TIME:
``` |

372 | ```
return eventLog->getFirstEventNotBeforeSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
``` |
||

373 | ```
case EVENT_NUMBER:
``` |
||

374 | { |
||

375 | eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber; |
||

376 | |||

377 | if (eventNumber < 0) |
||

378 | ```
return eventLog->getFirstEvent();
``` |
||

379 | ```
else
``` |
||

380 | ```
return eventLog->getFirstEventNotBeforeEventNumber(eventNumber);
``` |
||

381 | } |
||

382 | ```
case STEP:
``` |
||

383 | ```
case NONLINEAR:
``` |
||

384 | { |
||

385 | ```
bool forward;
``` |
||

386 | IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward); |
||

387 | currentEvent = forward ? currentEvent : (currentEvent ? currentEvent->getNextEvent() : eventLog->getFirstEvent()); |
||

388 | |||

389 | Assert(!currentEvent || getTimelineCoordinate(currentEvent) >= timelineCoordinate); |
||

390 | ```
return currentEvent;
``` |
||

391 | } |
||

392 | ```
default:
``` |
||

393 | throw opp_runtime_error("Unknown timeline mode"); |
||

394 | } |
||

395 | } |
||

396 | |||

397 | ```
void SequenceChartFacade::extractSimulationTimesAndTimelineCoordinates(
``` |
||

398 | IEvent *event, IEvent *&nextEvent, |
||

399 | ```
simtime_t &eventSimulationTime, double &eventTimelineCoordinate,
``` |
||

400 | ```
simtime_t &nextEventSimulationTime, double &nextEventTimelineCoordinate,
``` |
||

401 | ```
simtime_t &simulationTimeDelta, double &timelineCoordinateDelta)
``` |
||

402 | { |
||

403 | ```
// if before the first event
``` |
||

404 | ```
if (event) {
``` |
||

405 | 0596ce67 | Simon Tenbusch | ```
if (timelineMode==REAL_TIME) {
``` |

406 | eventSimulationTime = event->getEarliestStartTime() / 1000000.0; |
||

407 | ```
} else {
``` |
||

408 | eventSimulationTime = event->getSimulationTime(); |
||

409 | } |
||

410 | 01873262 | Georg Kunz | eventTimelineCoordinate = getTimelineCoordinate(event); |

411 | } |
||

412 | ```
else {
``` |
||

413 | eventSimulationTime = BigDecimal::Zero; |
||

414 | IEvent *firstEvent = eventLog->getFirstEvent(); |
||

415 | eventTimelineCoordinate = getTimelineCoordinate(firstEvent); |
||

416 | |||

417 | ```
if (timelineMode == EVENT_NUMBER)
``` |
||

418 | ```
eventTimelineCoordinate -= 1;
``` |
||

419 | 0596ce67 | Simon Tenbusch | else if (timelineMode == REAL_TIME) |

420 | ```
eventTimelineCoordinate -= getTimelineCoordinateDelta(0);
``` |
||

421 | 01873262 | Georg Kunz | ```
else
``` |

422 | eventTimelineCoordinate -= getTimelineCoordinateDelta(firstEvent->getSimulationTime().dbl()); |
||

423 | } |
||

424 | |||

425 | ```
// linear approximation between two enclosing events
``` |
||

426 | nextEvent = event ? event->getNextEvent() : eventLog->getFirstEvent(); |
||

427 | |||

428 | ```
if (nextEvent) {
``` |
||

429 | 0596ce67 | Simon Tenbusch | ```
if(timelineMode==REAL_TIME) {
``` |

430 | nextEventSimulationTime = nextEvent->getEarliestStartTime() / 1000000.0; |
||

431 | ```
} else {
``` |
||

432 | nextEventSimulationTime = nextEvent->getSimulationTime(); |
||

433 | } |
||

434 | |||

435 | 01873262 | Georg Kunz | nextEventTimelineCoordinate = getTimelineCoordinate(nextEvent); |

436 | |||

437 | simulationTimeDelta = nextEventSimulationTime - eventSimulationTime; |
||

438 | timelineCoordinateDelta = nextEventTimelineCoordinate - eventTimelineCoordinate; |
||

439 | } |
||

440 | } |
||

441 | |||

442 | simtime_t SequenceChartFacade::getSimulationTimeForTimelineCoordinate(double timelineCoordinate, bool upperLimit) |
||

443 | { |
||

444 | Assert(!isNaN(timelineCoordinate)); |
||

445 | |||

446 | ```
if (eventLog->isEmpty())
``` |
||

447 | ```
return BigDecimal::Zero;
``` |
||

448 | |||

449 | simtime_t simulationTime; |
||

450 | |||

451 | ```
switch (timelineMode)
``` |
||

452 | { |
||

453 | bcffd494 | Simon Tenbusch | ```
case REAL_TIME:
``` |

454 | { |
||

455 | 0596ce67 | Simon Tenbusch | simtime_t lastEventSimulationTime = (eventLog->getLastEvent()->getEarliestStartTime())/1000000.0; |

456 | bcffd494 | Simon Tenbusch | ```
//NOTE: This sometimes crashes the Sequencechart because the returned value might be too big
``` |

457 | 0596ce67 | Simon Tenbusch | simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, (timelineCoordinate + timelineCoordinateOriginRealTime))); |

458 | bcffd494 | Simon Tenbusch | } |

459 | 0596ce67 | Simon Tenbusch | ```
break;
``` |

460 | 01873262 | Georg Kunz | ```
case SIMULATION_TIME:
``` |

461 | { |
||

462 | simtime_t lastEventSimulationTime = eventLog->getLastEvent()->getSimulationTime(); |
||

463 | simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, timelineCoordinate + timelineCoordinateOriginSimulationTime)); |
||

464 | } |
||

465 | ```
break;
``` |
||

466 | ```
case EVENT_NUMBER:
``` |
||

467 | ```
case STEP:
``` |
||

468 | ```
case NONLINEAR:
``` |
||

469 | { |
||

470 | IEvent *nextEvent; |
||

471 | simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta; |
||

472 | ```
double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;
``` |
||

473 | |||

474 | IEvent *event = getLastEventNotAfterTimelineCoordinate(timelineCoordinate); |
||

475 | extractSimulationTimesAndTimelineCoordinates(event, nextEvent, |
||

476 | eventSimulationTime, eventTimelineCoordinate, |
||

477 | nextEventSimulationTime, nextEventTimelineCoordinate, |
||

478 | simulationTimeDelta, timelineCoordinateDelta); |
||

479 | |||

480 | ```
if (nextEvent) {
``` |
||

481 | if (timelineCoordinateDelta == 0) { |
||

482 | ```
// IMPORTANT NOTE: this is just an approximation
``` |
||

483 | ```
if (upperLimit)
``` |
||

484 | simulationTime = nextEventSimulationTime; |
||

485 | ```
else
``` |
||

486 | simulationTime = eventSimulationTime; |
||

487 | } |
||

488 | ```
else {
``` |
||

489 | timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate)); |
||

490 | simulationTime = eventSimulationTime + simulationTimeDelta * (timelineCoordinate - eventTimelineCoordinate) / timelineCoordinateDelta; |
||

491 | simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime)); |
||

492 | } |
||

493 | } |
||

494 | ```
else
``` |
||

495 | simulationTime = eventSimulationTime; |
||

496 | } |
||

497 | ```
break;
``` |
||

498 | ```
default:
``` |
||

499 | throw opp_runtime_error("Unknown timeline mode"); |
||

500 | } |
||

501 | |||

502 | Assert(!simulationTime.isNaN()); |
||

503 | Assert(simulationTime >= BigDecimal::Zero); |
||

504 | 0596ce67 | Simon Tenbusch | ```
if (timelineMode != REAL_TIME)
``` |

505 | Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime()); |
||

506 | 01873262 | Georg Kunz | |

507 | ```
return simulationTime;
``` |
||

508 | } |
||

509 | |||

510 | double SequenceChartFacade::getTimelineCoordinateForSimulationTime(simtime_t simulationTime, bool upperLimit) |
||

511 | { |
||

512 | Assert(!simulationTime.isNaN()); |
||

513 | |||

514 | ```
if (eventLog->isEmpty())
``` |
||

515 | return 0; |
||

516 | |||

517 | Assert(simulationTime >= BigDecimal::Zero); |
||

518 | 0596ce67 | Simon Tenbusch | ```
if (timelineMode != REAL_TIME)
``` |

519 | Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime()); |
||

520 | |||

521 | 01873262 | Georg Kunz | |

522 | ```
double timelineCoordinate;
``` |
||

523 | |||

524 | ```
switch (timelineMode)
``` |
||

525 | { |
||

526 | bcffd494 | Simon Tenbusch | ```
case REAL_TIME:
``` |

527 | 0596ce67 | Simon Tenbusch | ```
//treat simulationTime as real time:
``` |

528 | timelineCoordinate = simulationTime.dbl() - timelineCoordinateOriginRealTime; |
||

529 | ```
break;
``` |
||

530 | 01873262 | Georg Kunz | ```
case SIMULATION_TIME:
``` |

531 | timelineCoordinate = (simulationTime - timelineCoordinateOriginSimulationTime).dbl(); |
||

532 | ```
break;
``` |
||

533 | ```
case EVENT_NUMBER:
``` |
||

534 | ```
case STEP:
``` |
||

535 | ```
case NONLINEAR:
``` |
||

536 | { |
||

537 | IEvent *nextEvent; |
||

538 | simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta; |
||

539 | ```
double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;
``` |
||

540 | |||

541 | IEvent *event = eventLog->getLastEventNotAfterSimulationTime(simulationTime); |
||

542 | extractSimulationTimesAndTimelineCoordinates(event, nextEvent, |
||

543 | eventSimulationTime, eventTimelineCoordinate, |
||

544 | nextEventSimulationTime, nextEventTimelineCoordinate, |
||

545 | simulationTimeDelta, timelineCoordinateDelta); |
||

546 | |||

547 | ```
if (nextEvent) {
``` |
||

548 | ```
if (simulationTimeDelta == BigDecimal::Zero) {
``` |
||

549 | ```
// IMPORTANT NOTE: this is just an approximation
``` |
||

550 | ```
if (upperLimit)
``` |
||

551 | timelineCoordinate = nextEventTimelineCoordinate; |
||

552 | ```
else
``` |
||

553 | timelineCoordinate = eventTimelineCoordinate; |
||

554 | } |
||

555 | ```
else {
``` |
||

556 | simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime)); |
||

557 | timelineCoordinate = eventTimelineCoordinate + timelineCoordinateDelta * (simulationTime - eventSimulationTime).dbl() / simulationTimeDelta.dbl(); |
||

558 | timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate)); |
||

559 | } |
||

560 | } |
||

561 | ```
else
``` |
||

562 | timelineCoordinate = eventTimelineCoordinate; |
||

563 | } |
||

564 | ```
break;
``` |
||

565 | ```
default:
``` |
||

566 | throw opp_runtime_error("Unknown timeline mode"); |
||

567 | } |
||

568 | |||

569 | Assert(!isNaN(timelineCoordinate)); |
||

570 | |||

571 | ```
return timelineCoordinate;
``` |
||

572 | } |
||

573 | |||

574 | double SequenceChartFacade::getTimelineCoordinateForSimulationTimeAndEventInModule(simtime_t simulationTime, int moduleId) |
||

575 | { |
||

576 | IEvent *event = eventLog->getLastEventNotAfterSimulationTime(simulationTime); |
||

577 | |||

578 | ```
while (event && event->getSimulationTime() == simulationTime) {
``` |
||

579 | ```
if (event->getModuleId() == moduleId)
``` |
||

580 | ```
return getTimelineCoordinate(event);
``` |
||

581 | |||

582 | event = event->getNextEvent(); |
||

583 | } |
||

584 | |||

585 | ```
return getTimelineCoordinateForSimulationTime(simulationTime);
``` |
||

586 | } |
||

587 | |||

588 | std::vector<ptr_t> *SequenceChartFacade::getModuleMethodBeginEntries(ptr_t startEventPtr, ptr_t endEventPtr) |
||

589 | { |
||

590 | IEvent *startEvent = (IEvent *)startEventPtr; |
||

591 | IEvent *endEvent = (IEvent *)endEventPtr; |
||

592 | Assert(startEvent); |
||

593 | Assert(endEvent); |
||

594 | ```
std::vector<ptr_t> *moduleMethodBeginEntries = new std::vector<ptr_t>();
``` |
||

595 | |||

596 | ```
for (IEvent *event = startEvent;; event = event->getNextEvent()) {
``` |
||

597 | eventLog->progress(); |
||

598 | |||

599 | for (int i = 0; i < event->getNumEventLogEntries(); i++) { |
||

600 | EventLogEntry *eventLogEntry = event->getEventLogEntry(i); |
||

601 | |||

602 | if (dynamic_cast<ModuleMethodBeginEntry *>(eventLogEntry)) |
||

603 | moduleMethodBeginEntries->push_back((ptr_t)eventLogEntry); |
||

604 | } |
||

605 | |||

606 | ```
if (event == endEvent)
``` |
||

607 | ```
break;
``` |
||

608 | } |
||

609 | |||

610 | ```
return moduleMethodBeginEntries;
``` |
||

611 | } |
||

612 | |||

613 | std::vector<ptr_t> *SequenceChartFacade::getIntersectingMessageDependencies(ptr_t startEventPtr, ptr_t endEventPtr) |
||

614 | { |
||

615 | IEvent *startEvent = (IEvent *)startEventPtr; |
||

616 | IEvent *endEvent = (IEvent *)endEventPtr; |
||

617 | Assert(startEvent); |
||

618 | Assert(endEvent); |
||

619 | std::set<ptr_t> messageDependencies; |
||

620 | eventnumber_t startEventNumber = startEvent->getEventNumber(); |
||

621 | |||

622 | ```
// TODO: LONG RUNNING OPERATION
``` |
||

623 | ```
// this might take a while if start and end events are far away from each other
``` |
||

624 | ```
// if not completed then some dependencies will not be included
``` |
||

625 | ```
for (IEvent *event = startEvent;; event = event->getNextEvent()) {
``` |
||

626 | eventLog->progress(); |
||

627 | IMessageDependencyList *causes = event->getCauses(); |
||

628 | |||

629 | ```
for (IMessageDependencyList::iterator it = causes->begin(); it != causes->end(); it++) {
``` |
||

630 | IMessageDependency *messageDependency = *it; |
||

631 | |||

632 | ```
if (messageDependency->getCauseEventNumber() < startEventNumber)
``` |
||

633 | messageDependencies.insert((ptr_t)messageDependency); |
||

634 | } |
||

635 | |||

636 | IMessageDependencyList *consequences = event->getConsequences(); |
||

637 | |||

638 | ```
for (IMessageDependencyList::iterator it = consequences->begin(); it != consequences->end(); it++)
``` |
||

639 | messageDependencies.insert((ptr_t)*it); |
||

640 | |||

641 | ```
if (event == endEvent)
``` |
||

642 | ```
break;
``` |
||

643 | } |
||

644 | |||

645 | ```
std::vector<ptr_t> *result = new std::vector<ptr_t>;
``` |
||

646 | result->resize(messageDependencies.size()); |
||

647 | std::copy(messageDependencies.begin(), messageDependencies.end(), result->begin()); |
||

648 | |||

649 | ```
return result;
``` |
||

650 | } |
||

651 | |||

652 | std::vector<int> SequenceChartFacade::getApproximateMessageDependencyCountAdjacencyMatrix(std::map<int, int> *moduleIdToAxisIndexMap, int numberOfSamples, int messageSendWeight, int messageReuseWeight) |
||

653 | { |
||

654 | LCGRandom lcgRandom; |
||

655 | ```
std::vector<int> adjacencyMatrix;
``` |
||

656 | ```
std::set<int> axisIndexSet;
``` |
||

657 | std::map<eventnumber_t, IEvent *> eventNumberToEventMap; |
||

658 | |||

659 | for (std::map<int, int>::iterator it = moduleIdToAxisIndexMap->begin(); it != moduleIdToAxisIndexMap->end(); it++) |
||

660 | axisIndexSet.insert(it->second); |
||

661 | |||

662 | ```
int numberOfAxes = axisIndexSet.size();
``` |
||

663 | adjacencyMatrix.resize(numberOfAxes * numberOfAxes); |
||

664 | |||

665 | for (int i = 0; i < numberOfSamples; i++) |
||

666 | { |
||

667 | ```
// draw random
``` |
||

668 | ```
double percentage = lcgRandom.next01();
``` |
||

669 | IEvent *event = eventLog->getApproximateEventAt(percentage); |
||

670 | eventNumberToEventMap[event->getEventNumber()] = event; |
||

671 | |||

672 | ```
// look before origin
``` |
||

673 | if (timelineCoordinateOriginEventNumber != -1) { |
||

674 | if (timelineCoordinateOriginEventNumber - i >= 0) { |
||

675 | event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber - i); |
||

676 | ```
if (event)
``` |
||

677 | eventNumberToEventMap[event->getEventNumber()] = event; |
||

678 | } |
||

679 | |||

680 | ```
// look after origin
``` |
||

681 | event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber + i); |
||

682 | ```
if (event)
``` |
||

683 | eventNumberToEventMap[event->getEventNumber()] = event; |
||

684 | } |
||

685 | } |
||

686 | |||

687 | ```
for (std::map<eventnumber_t, IEvent *>::iterator it = eventNumberToEventMap.begin(); it != eventNumberToEventMap.end(); it++) {
``` |
||

688 | IEvent *event = it->second; |
||

689 | IMessageDependencyList *causes = event->getCauses(); |
||

690 | |||

691 | ```
for (IMessageDependencyList::iterator it = causes->begin(); it != causes->end(); it++) {
``` |
||

692 | IMessageDependency *messageDependency = *it; |
||

693 | IEvent *causeEvent = messageDependency->getCauseEvent(); |
||

694 | IEvent *consequenceEvent = messageDependency->getConsequenceEvent(); |
||

695 | ```
int weight = messageDependency->getIsReuse() ? messageReuseWeight : messageSendWeight;
``` |
||

696 | |||

697 | if (causeEvent && consequenceEvent && weight != 0) { |
||

698 | ```
int causeModuleId = causeEvent->getModuleId();
``` |
||

699 | ```
int consequenceModuleId = consequenceEvent->getModuleId();
``` |
||

700 | |||

701 | std::map<int, int>::iterator causeModuleIdIt = moduleIdToAxisIndexMap->find(causeModuleId); |
||

702 | std::map<int, int>::iterator consequenceModuleIdIt = moduleIdToAxisIndexMap->find(consequenceModuleId); |
||

703 | |||

704 | ```
if (causeModuleIdIt != moduleIdToAxisIndexMap->end() && consequenceModuleIdIt != moduleIdToAxisIndexMap->end())
``` |
||

705 | adjacencyMatrix.at(causeModuleIdIt->second * numberOfAxes + consequenceModuleIdIt->second) += weight; |
||

706 | } |
||

707 | } |
||

708 | } |
||

709 | |||

710 | ```
return adjacencyMatrix;
``` |
||

711 | } |
||

712 | daf081df | Simon Tenbusch | |

713 | |||

714 | ```
long SequenceChartFacade::getSmallestEventComplexity() {
``` |
||

715 | long complexity = 0; |
||

716 | if (smallestComplexity < 0) { |
||

717 | ```
for (IEvent *event = eventLog->getFirstEvent();event != eventLog->getLastEvent(); event = event->getNextEvent()) {
``` |
||

718 | ```
if (event->getEventEndEntry()) {
``` |
||

719 | complexity = event->getEventEndEntry()->complexity; |
||

720 | 61338f86 | Simon Tenbusch | ```
} else {
``` |

721 | ```
continue;
``` |
||

722 | daf081df | Simon Tenbusch | } |

723 | if (complexity < smallestComplexity || smallestComplexity < 0) { |
||

724 | smallestComplexity = complexity; |
||

725 | } |
||

726 | if (complexity > largestComplexity || largestComplexity < 0) { |
||

727 | largestComplexity = complexity; |
||

728 | } |
||

729 | } |
||

730 | } |
||

731 | if (smallestComplexity < 0) { |
||

732 | ```
smallestComplexity = 0;
``` |
||

733 | } |
||

734 | ```
return smallestComplexity;
``` |
||

735 | } |
||

736 | |||

737 | ```
long SequenceChartFacade::getLargestEventComplexity() {
``` |
||

738 | if (largestComplexity < 0) { |
||

739 | getSmallestEventComplexity(); |
||

740 | } |
||

741 | if (largestComplexity < 0) { |
||

742 | ```
largestComplexity = 0;
``` |
||

743 | } |
||

744 | ```
return largestComplexity;
``` |
||

745 | } |
||

746 | 391dcea0 | Simon Tenbusch | |

747 | ced95c57 | Simon Tenbusch | simtime_t SequenceChartFacade::getSmallestEventDuration() { |

748 | ```
simtime_t duration = 0;
``` |
||

749 | if (smallestDuration < 0) { |
||

750 | ```
for (IEvent *event = eventLog->getFirstEvent();event != eventLog->getLastEvent(); event = event->getNextEvent()) {
``` |
||

751 | ```
if (event->getEventEntry()) {
``` |
||

752 | duration = event->getEventEntry()->duration; |
||

753 | ```
} else {
``` |
||

754 | ```
continue;
``` |
||

755 | } |
||

756 | if (duration < smallestDuration || smallestDuration < 0) { |
||

757 | smallestDuration = duration; |
||

758 | } |
||

759 | if (duration > largestDuration || largestDuration < 0) { |
||

760 | largestDuration = duration; |
||

761 | } |
||

762 | } |
||

763 | } |
||

764 | if (smallestDuration < 0) { |
||

765 | ```
smallestDuration = 0;
``` |
||

766 | } |
||

767 | ```
return smallestDuration;
``` |
||

768 | } |
||

769 | |||

770 | simtime_t SequenceChartFacade::getLargestEventDuration() { |
||

771 | if (largestDuration < 0) { |
||

772 | getSmallestEventComplexity(); |
||

773 | } |
||

774 | if (largestDuration < 0) { |
||

775 | ```
largestDuration = 0;
``` |
||

776 | } |
||

777 | ```
return largestDuration;
``` |
||

778 | } |
||

779 | |||

780 | 391dcea0 | Simon Tenbusch | |

781 | IEvent* SequenceChartFacade::getPreviousBottleneck(IEvent* e, unsigned int threshold) { |
||

782 | IEvent* next = e->getPreviousEvent(); |
||

783 | ```
while (next) {
``` |
||

784 | ```
if (isBottleneck(next,threshold)) {
``` |
||

785 | ```
return next;
``` |
||

786 | } |
||

787 | next = next->getPreviousEvent(); |
||

788 | } |
||

789 | ```
return e;
``` |
||

790 | } |
||

791 | |||

792 | IEvent* SequenceChartFacade::getNextBottleneck(IEvent* e, unsigned int threshold) { |
||

793 | IEvent* next = e->getNextEvent(); |
||

794 | ```
while (next) {
``` |
||

795 | ```
if (isBottleneck(next,threshold)) {
``` |
||

796 | ```
return next;
``` |
||

797 | } |
||

798 | next = next->getNextEvent(); |
||

799 | } |
||

800 | ```
return e;
``` |
||

801 | } |
||

802 | |||

803 | ```
/*
``` |
||

804 | ```
* Returns whether an event not part of a set of parallel events with more than treshold elements.
``` |
||

805 | ```
*/
``` |
||

806 | bool SequenceChartFacade::isBottleneck(IEvent* event, unsigned int threshold) |
||

807 | { |
||

808 | ```
return getLargestParallelSetSize(event) <= threshold;
``` |
||

809 | } |
||

810 | 1c72663d | Simon Tenbusch | ```
/*
``` |

811 | ```
* Returns whether event is in the largest parallel set of selected.
``` |
||

812 | ```
*/
``` |
||

813 | ```
bool SequenceChartFacade::isParallelWithEvent(IEvent* event, IEvent* selected) {
``` |
||

814 | |||

815 | ```
if (lastSelected != selected) {
``` |
||

816 | getLargestParallelSet(selected, &cachedParallelSet); |
||

817 | } |
||

818 | ```
return cachedParallelSet.find((ptr_t)event) != cachedParallelSet.end();
``` |
||

819 | } |
||

820 | e2b044ac | Simon Tenbusch | ```
/*
``` |

821 | ```
* Returns the size of the largest set that is parallel with event.
``` |
||

822 | ```
*
``` |
||

823 | ```
* Works by calculating the first parallel set which does not contain event by
``` |
||

824 | ```
* successively going backwards through all events starting from event.
``` |
||

825 | ```
*/
``` |
||

826 | 391dcea0 | Simon Tenbusch | unsigned int SequenceChartFacade::getLargestParallelSetSize(IEvent* event) |

827 | { |
||

828 | IEvent* prev = event; |
||

829 | std::set<ptr_t> parallelSet; |
||

830 | parallelSet.clear(); |
||

831 | unsigned int previousSize = 0; |
||

832 | ```
while (prev)
``` |
||

833 | { |
||

834 | previousSize = parallelSet.size(); |
||

835 | |||

836 | getParallelSet(prev, ¶llelSet); |
||

837 | |||

838 | ```
if (parallelSet.find((ptr_t) event) == parallelSet.end())
``` |
||

839 | { |
||

840 | e2b044ac | Simon Tenbusch | ```
//The current set does not contain event.
``` |

841 | ```
//Therefore the previous set was the largest Parallel Set.
``` |
||

842 | 391dcea0 | Simon Tenbusch | ```
break;
``` |

843 | } |
||

844 | prev = prev->getPreviousEvent(); |
||

845 | } |
||

846 | ```
return previousSize;
``` |
||

847 | } |
||

848 | e2b044ac | Simon Tenbusch | ```
/*
``` |

849 | ```
* Returns the largest set that is parallel with event.
``` |
||

850 | ```
*
``` |
||

851 | ```
* Works by calculating the first parallel set which does not contain event by
``` |
||

852 | ```
* successively going backwards through all events starting from event.
``` |
||

853 | ```
*/
``` |
||

854 | 1c72663d | Simon Tenbusch | std::set<ptr_t>* SequenceChartFacade::getLargestParallelSet(IEvent* event, std::set<ptr_t>* parallelSet) { |

855 | IEvent* prev = event; |
||

856 | parallelSet->clear(); |
||

857 | ```
while (prev)
``` |
||

858 | { |
||

859 | getParallelSet(prev, parallelSet); |
||

860 | ```
if (parallelSet->find((ptr_t) event) == parallelSet->end())
``` |
||

861 | { |
||

862 | e2b044ac | Simon Tenbusch | ```
//The current set does not contain event.
``` |

863 | ```
//Therefore the previous set was the largest Parallel Set.
``` |
||

864 | 1c72663d | Simon Tenbusch | ```
break;
``` |

865 | } |
||

866 | prev = prev->getPreviousEvent(); |
||

867 | } |
||

868 | ```
if (prev != event) {
``` |
||

869 | getParallelSet(prev->getNextEvent(), parallelSet); |
||

870 | } |
||

871 | ```
return parallelSet;
``` |
||

872 | } |
||

873 | |||

874 | e2b044ac | Simon Tenbusch | ```
/*
``` |

875 | ```
* Calculates a set of those events that start after event but are still in parallel to event.
``` |
||

876 | ```
* This means that no other event must end before the latest start time in this set.
``` |
||

877 | ```
*/
``` |
||

878 | 391dcea0 | Simon Tenbusch | ```
void SequenceChartFacade::getParallelSet(IEvent* event,
``` |

879 | std::set<ptr_t>* parallelSet) |
||

880 | { |
||

881 | IEvent* next = event->getNextEvent(); |
||

882 | simtime_t smallestParallelEndtime = getSmallestParallelEndtime(event); |
||

883 | parallelSet->clear(); |
||

884 | parallelSet->insert((ptr_t) event); |
||

885 | ```
while (next)
``` |
||

886 | { |
||

887 | ```
if ((next->getSimulationTime() >= event->getSimulationTime())
``` |
||

888 | && (smallestParallelEndtime >= next->getSimulationTime())) |
||

889 | { |
||

890 | 95d5c2d3 | Simon Tenbusch | ```
if(parallelSet->find((ptr_t)(next->getCauseEvent())) == parallelSet->end()) {
``` |

891 | parallelSet->insert((ptr_t) next); |
||

892 | } |
||

893 | 391dcea0 | Simon Tenbusch | } |

894 | ```
else
``` |
||

895 | { |
||

896 | ```
break;
``` |
||

897 | } |
||

898 | next = next->getNextEvent(); |
||

899 | } |
||

900 | } |
||

901 | e2b044ac | Simon Tenbusch | ```
/*
``` |

902 | ```
*
``` |
||

903 | ```
*/
``` |
||

904 | 391dcea0 | Simon Tenbusch | simtime_t SequenceChartFacade::getSmallestParallelEndtime(IEvent* event) |

905 | { |
||

906 | simtime_t minimum = event->getSimulationTime() |
||

907 | + event->getEventEntry()->duration; |
||

908 | ```
for (IEvent *current = eventLog->getFirstEvent(); current; current
``` |
||

909 | = current->getNextEvent()) |
||

910 | { |
||

911 | ```
if (current->getSimulationTime() >= event->getSimulationTime())
``` |
||

912 | { |
||

913 | ```
if ((current->getSimulationTime()
``` |
||

914 | + current->getEventEntry()->duration) |
||

915 | > event->getSimulationTime()) |
||

916 | { |
||

917 | ```
if (minimum > (current->getSimulationTime()
``` |
||

918 | + current->getEventEntry()->duration)) |
||

919 | { |
||

920 | minimum = current->getSimulationTime() |
||

921 | + current->getEventEntry()->duration; |
||

922 | } |
||

923 | } |
||

924 | ```
if (current->getSimulationTime() > minimum)
``` |
||

925 | ```
{ // After this, no overlapping can follow
``` |
||

926 | ```
break;
``` |
||

927 | } |
||

928 | } |
||

929 | } |
||

930 | ```
return minimum;
``` |
||

931 | } |
||

932 | a3b7e786 | Simon Tenbusch | |

933 | ```
/*
``` |
||

934 | ```
* Determines whether the event lies on the critical path
``` |
||

935 | ```
*/
``` |
||

936 | ```
bool SequenceChartFacade::isOnCriticalPath(IEvent* event) {
``` |
||

937 | ```
if (cachedCriticalPath.empty()) {
``` |
||

938 | calculateCriticalPath(); |
||

939 | } |
||

940 | ```
return (cachedCriticalPath.find((ptr_t)event) != cachedCriticalPath.end());
``` |
||

941 | } |
||

942 | |||

943 | ```
/*
``` |
||

944 | ```
* Calculates the critical path of the run and stores it in the set cachedCriticalPath
``` |
||

945 | ```
*/
``` |
||

946 | ```
void SequenceChartFacade::calculateCriticalPath() {
``` |
||

947 | long maxEarliestProcessingTime = 0; |
||

948 | IEvent* maxEarliestProcessingTimeEvent; |
||

949 | |||

950 | ```
for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
``` |
||

951 | simtime_t startTime = current->getSimulationTime(); |
||

952 | e2b044ac | Simon Tenbusch | ```
int moduleId = current->getModuleId();
``` |

953 | a3b7e786 | Simon Tenbusch | ```
if(current->getEventEndEntry()) {
``` |

954 | bcffd494 | Simon Tenbusch | current->_earliestProcessingTime = current->getComplexity(); |

955 | a3b7e786 | Simon Tenbusch | } |

956 | 0596ce67 | Simon Tenbusch | |

957 | current->setCriticalPredecessor(eventLog->getFirstEvent()); |
||

958 | |||

959 | a3b7e786 | Simon Tenbusch | ```
for (IEvent *antecessor = eventLog->getFirstEvent(); antecessor; antecessor = antecessor->getNextEvent()) {
``` |

960 | ```
if(antecessor==current) {
``` |
||

961 | break; //We have to consider earlier events only |
||

962 | } |
||

963 | d91c8332 | Simon Tenbusch | ```
if(antecessor->getModuleId() != moduleId && current->getCauseEvent() != antecessor) {
``` |

964 | a3b7e786 | Simon Tenbusch | continue; // Check if this is an antecesor |

965 | } |
||

966 | bcffd494 | Simon Tenbusch | ```
if(antecessor->_earliestProcessingTime+current->getComplexity() > current->_earliestProcessingTime) {
``` |

967 | current->_earliestProcessingTime = antecessor->_earliestProcessingTime+current->getComplexity(); |
||

968 | 0596ce67 | Simon Tenbusch | current->setCriticalPredecessor(antecessor); |

969 | a3b7e786 | Simon Tenbusch | } |

970 | } |
||

971 | ```
// Memorize max event
``` |
||

972 | bcffd494 | Simon Tenbusch | ```
if (maxEarliestProcessingTime < current->_earliestProcessingTime) {
``` |

973 | maxEarliestProcessingTime = current->_earliestProcessingTime; |
||

974 | a3b7e786 | Simon Tenbusch | maxEarliestProcessingTimeEvent = current; |

975 | } |
||

976 | } |
||

977 | 0596ce67 | Simon Tenbusch | ```
//Now produce the convex hull of critical antecessors/predecessors:
``` |

978 | a3b7e786 | Simon Tenbusch | cachedCriticalPath.clear(); |

979 | 0596ce67 | Simon Tenbusch | ```
for (IEvent *predecessor = maxEarliestProcessingTimeEvent; predecessor ; predecessor = predecessor->getCriticalPredecessor()) {
``` |

980 | a3b7e786 | Simon Tenbusch | cachedCriticalPath.insert((ptr_t)predecessor); |

981 | e2b044ac | Simon Tenbusch | if(predecessor->getEventNumber() == 0) { |

982 | ```
break;
``` |
||

983 | } |
||

984 | a3b7e786 | Simon Tenbusch | } |

985 | } |
||

986 | |||

987 | 8aeaaccc | Simon Tenbusch | ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr, ptr_t endEventPtr) { |

988 | IEvent *startEvent = (IEvent *)startEventPtr; |
||

989 | IEvent *endEvent = (IEvent *)endEventPtr; |
||

990 | ```
switch (timelineMode)
``` |
||

991 | { |
||

992 | ```
case REAL_TIME:
``` |
||

993 | { |
||

994 | long largest = 0; |
||

995 | IEvent* largestEvent = startEvent; |
||

996 | |||

997 | ```
for (IEvent* current = startEvent; current; current = current->getNextEvent()) {
``` |
||

998 | ```
long temp = current->getEarliestProcessingTime();
``` |
||

999 | ```
if (temp > largest) {
``` |
||

1000 | largest = temp; |
||

1001 | largestEvent = current; |
||

1002 | } |
||

1003 | ```
if (current==endEvent) {
``` |
||

1004 | ```
break;
``` |
||

1005 | } |
||

1006 | } |
||

1007 | ```
return (ptr_t) largestEvent;
``` |
||

1008 | } |
||

1009 | ```
case SIMULATION_TIME:
``` |
||

1010 | ```
case EVENT_NUMBER:
``` |
||

1011 | ```
case STEP:
``` |
||

1012 | ```
case NONLINEAR:
``` |
||

1013 | ```
default:
``` |
||

1014 | ```
return endEventPtr;
``` |
||

1015 | } |
||

1016 | |||

1017 | } |