root / src / eventlog / sequencechartfacade.cc @ 12288d0e
History  View  Annotate  Download (44 KB)
1 
//=========================================================================


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) 20062008 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 <list> 
21 
#include <math.h> 
22 
#include "lcgrandom.h" 
23 
#include "ievent.h" 
24 
#include "ieventlog.h" 
25 
#include "event.h" 
26 
#include "messagedependency.h" 
27 
#include "sequencechartfacade.h" 
28  
29 
USING_NAMESPACE 
30  
31 
SequenceChartFacade::SequenceChartFacade(IEventLog *eventLog) : EventLogFacade(eventLog) 
32 
{ 
33 
timelineMode = NONLINEAR; 
34 
timelineCoordinateSystemVersion = 1;

35 
undefineTimelineCoordinateSystem(); 
36  
37 
nonLinearMinimumTimelineCoordinateDelta = 0.1; 
38 
setNonLinearFocus(calculateNonLinearFocus()); 
39  
40 
smallestComplexity = 1;

41 
largestComplexity = 1;

42  
43 
smallestDuration = 1;

44 
largestDuration = 1;

45  
46 
maximumOverlapping = 1;

47  
48 
biggestEarliestProcessingTime = 0;

49  
50 
biggestEndTimeEvent = NULL;

51  
52 
cachedParallelSet.clear(); 
53 
cachedCriticalPath.clear(); 
54 
} 
55  
56 
void SequenceChartFacade::synchronize(FileReader::FileChangedState change)

57 
{ 
58 
if (change != FileReader::UNCHANGED) {

59 
EventLogFacade::synchronize(change); 
60  
61 
setNonLinearFocus(calculateNonLinearFocus()); 
62  
63 
if (timelineCoordinateOriginEventNumber != 1) { 
64 
IEvent *event = eventLog>getEventForEventNumber(timelineCoordinateOriginEventNumber); 
65  
66 
if (event)

67 
relocateTimelineCoordinateSystem(event); 
68 
else

69 
undefineTimelineCoordinateSystem(); 
70 
} 
71 
} 
72 
} 
73  
74 
double SequenceChartFacade::calculateNonLinearFocus()

75 
{ 
76 
if (!eventLog>isEmpty()) {

77 
double lastEventSimulationTime = eventLog>getLastEvent()>getSimulationTime().dbl();

78 
double firstEventSimulationTime = eventLog>getFirstEvent()>getSimulationTime().dbl();

79 
double totalSimulationTimeDelta = lastEventSimulationTime  firstEventSimulationTime;

80  
81 
if (totalSimulationTimeDelta == 0) 
82 
totalSimulationTimeDelta = firstEventSimulationTime; 
83  
84 
if (totalSimulationTimeDelta == 0) 
85 
return 1; 
86 
else

87 
return totalSimulationTimeDelta / eventLog>getApproximateNumberOfEvents() / 10; 
88 
} 
89 
else

90 
return 1; 
91 
} 
92  
93 
void SequenceChartFacade::setNonLinearMinimumTimelineCoordinateDelta(double value) 
94 
{ 
95 
Assert(value >= 0);

96 
nonLinearMinimumTimelineCoordinateDelta = value; 
97 
} 
98  
99 
void SequenceChartFacade::setNonLinearFocus(double nonLinearFocus) 
100 
{ 
101 
Assert(nonLinearFocus >= 0);

102 
this>nonLinearFocus = nonLinearFocus;

103 
} 
104  
105 
void SequenceChartFacade::undefineTimelineCoordinateSystem()

106 
{ 
107 
timelineCoordinateSystemVersion++; 
108 
timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = 1;

109 
timelineCoordinateOriginSimulationTime = simtime_nil; 
110 
timelineCoordinateOriginRealTime = 0;

111 
} 
112  
113 
void SequenceChartFacade::relocateTimelineCoordinateSystem(IEvent *event)

114 
{ 
115 
Assert(event); 
116  
117 
timelineCoordinateSystemVersion++; 
118 
timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = event>getEventNumber(); 
119 
timelineCoordinateOriginSimulationTime = event>getSimulationTime(); 
120 
timelineCoordinateOriginRealTime = event>getEarliestStartTime() / 1000000.0; 
121 
event>cachedTimelineCoordinate = 0;

122 
event>cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion; 
123 
} 
124  
125 
void SequenceChartFacade::setTimelineMode(TimelineMode timelineMode)

126 
{ 
127 
this>timelineMode = timelineMode;

128  
129 
if (timelineCoordinateOriginEventNumber != 1) 
130 
relocateTimelineCoordinateSystem(eventLog>getEventForEventNumber(timelineCoordinateOriginEventNumber)); 
131 
} 
132  
133 
double SequenceChartFacade::IEvent_getTimelineCoordinate(ptr_t ptr)

134 
{ 
135 
IEVENT_PTR(ptr); 
136 
return getTimelineCoordinate((IEvent*)ptr);

137 
} 
138  
139 
double SequenceChartFacade::IEvent_getTimelineEventEndCoordinate(ptr_t ptr)

140 
{ 
141 
IEVENT_PTR(ptr); 
142 
return getTimelineEventEndCoordinate((IEvent*)ptr);

143 
} 
144  
145 
double SequenceChartFacade::getTimelineCoordinateDelta(double simulationTimeDelta) 
146 
{ 
147 
Assert(nonLinearFocus > 0);

148  
149 
if (timelineMode == STEP)

150 
return 1; 
151 
else

152 
return nonLinearMinimumTimelineCoordinateDelta + (1  nonLinearMinimumTimelineCoordinateDelta) * atan(fabs(simulationTimeDelta) / nonLinearFocus) / PI * 2; 
153 
} 
154  
155 
double SequenceChartFacade::getTimelineCoordinate(ptr_t ptr, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) 
156 
{ 
157 
IEVENT_PTR(ptr); 
158 
return getTimelineCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);

159 
} 
160  
161 
double SequenceChartFacade::getTimelineEventEndCoordinate(ptr_t ptr, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) 
162 
{ 
163 
IEVENT_PTR(ptr); 
164 
return getTimelineEventEndCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);

165 
} 
166  
167 
double SequenceChartFacade::getTimelineCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) 
168 
{ 
169 
Assert(event); 
170 
Assert(event>getEventLog() == eventLog); 
171 
Assert(timelineCoordinateSystemVersion != 1);

172 
Assert(timelineCoordinateOriginEventNumber != 1);

173  
174 
if (this>timelineCoordinateSystemVersion > event>cachedTimelineCoordinateSystemVersion) { 
175 
double timelineCoordinate;

176  
177 
switch (timelineMode) {

178 
case REAL_TIME:

179 
timelineCoordinate = ((event>getEarliestStartTime()/1000000.0  timelineCoordinateOriginRealTime)); 
180 
break;

181 
case SIMULATION_TIME:

182 
timelineCoordinate = (event>getSimulationTime()  timelineCoordinateOriginSimulationTime).dbl(); 
183 
break;

184 
case EVENT_NUMBER:

185 
timelineCoordinate = event>getEventNumber()  timelineCoordinateOriginEventNumber; 
186 
break;

187 
case STEP:

188 
case NONLINEAR:

189 
{ 
190 
IEvent *previousEvent = NULL;

191 
// do we go forward from end or backward from start of known range

192 
bool forward = event>getEventNumber() > timelineCoordinateRangeEndEventNumber;

193 
IEvent *currentEvent = eventLog>getEventForEventNumber(forward ? timelineCoordinateRangeEndEventNumber : timelineCoordinateRangeStartEventNumber); 
194  
195 
Assert(event>getEventNumber() < timelineCoordinateRangeStartEventNumber  timelineCoordinateRangeEndEventNumber < event>getEventNumber()); 
196  
197 
// TODO: LONG RUNNING OPERATION

198 
// does a linear search towards the event to calculate the non linear timeline coordinate

199 
do {

200 
eventLog>progress(); 
201  
202 
Assert(currentEvent); 
203 
previousEvent = currentEvent; 
204 
currentEvent = forward ? currentEvent>getNextEvent() : currentEvent>getPreviousEvent(); 
205 
Assert(currentEvent); 
206  
207 
simtime_t previousSimulationTime = previousEvent>getSimulationTime(); 
208 
double previousTimelineCoordinate = previousEvent>cachedTimelineCoordinate;

209 
simtime_t simulationTime = currentEvent>getSimulationTime(); 
210 
double timelineCoordinateDelta = getTimelineCoordinateDelta((simulationTime  previousSimulationTime).dbl());

211  
212 
if (forward) {

213 
timelineCoordinate = previousTimelineCoordinate + timelineCoordinateDelta; 
214  
215 
if (timelineCoordinate > upperTimelineCoordinateCalculationLimit)

216 
return NaN;

217 
} 
218 
else {

219 
timelineCoordinate = previousTimelineCoordinate  timelineCoordinateDelta; 
220  
221 
if (timelineCoordinate < lowerTimelineCoordinateCalculationLimit)

222 
return NaN;

223 
} 
224  
225 
currentEvent>cachedTimelineCoordinate = timelineCoordinate; 
226 
currentEvent>cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion; 
227 
} 
228 
while (currentEvent != event);

229  
230 
if (forward)

231 
timelineCoordinateRangeEndEventNumber = event>getEventNumber(); 
232 
else

233 
timelineCoordinateRangeStartEventNumber = event>getEventNumber(); 
234 
} 
235 
break;

236 
default:

237 
throw opp_runtime_error("Unknown timeline mode"); 
238 
} 
239  
240 
event>cachedTimelineCoordinate = timelineCoordinate; 
241 
event>cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion; 
242 
} 
243  
244 
return event>cachedTimelineCoordinate;

245 
} 
246  
247 
double SequenceChartFacade::getTimelineEventEndCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit) 
248 
{ 
249 
Assert(event); 
250 
Assert(event>getEventLog() == eventLog); 
251 
if(!eventLog>isLegacyTrace()) {

252 
return getTimelineCoordinate(event);

253 
} 
254 
double timelineEventEndCoordinate;

255 
switch (timelineMode) {

256 
case REAL_TIME:

257 
timelineEventEndCoordinate = (event>getEarliestProcessingTime()/ 1000000.0  timelineCoordinateOriginRealTime) ; 
258 
break;

259 
case SIMULATION_TIME:

260 
timelineEventEndCoordinate = (event>getSimulationTime()+event>getEventEntry()>duration  timelineCoordinateOriginSimulationTime).dbl(); 
261 
break;

262 
default:

263 
return getTimelineCoordinate(event);

264 
} 
265 
return timelineEventEndCoordinate;

266 
} 
267  
268 
double SequenceChartFacade::getCachedTimelineCoordinate(IEvent *event)

269 
{ 
270 
Assert(event); 
271 
Assert(timelineCoordinateSystemVersion != 1);

272 
Assert(timelineCoordinateOriginEventNumber != 1);

273  
274 
if (this>timelineCoordinateSystemVersion > event>cachedTimelineCoordinateSystemVersion) 
275 
return 1; 
276 
else

277 
return event>cachedTimelineCoordinate;

278 
} 
279  
280 
IEvent *SequenceChartFacade::getEventForNonLinearTimelineCoordinate(double timelineCoordinate, bool &forward) 
281 
{ 
282 
Assert(timelineCoordinateOriginEventNumber != 1);

283 
IEvent *timelineCoordinateRangeStartEvent = eventLog>getEventForEventNumber(timelineCoordinateRangeStartEventNumber); 
284 
IEvent *timelineCoordinateRangeEndEvent = eventLog>getEventForEventNumber(timelineCoordinateRangeEndEventNumber); 
285 
IEvent *currentEvent; 
286  
287 
Assert(timelineCoordinateRangeStartEvent && timelineCoordinateRangeEndEvent); 
288  
289 
if (timelineCoordinate <= getTimelineCoordinate(timelineCoordinateRangeStartEvent)) {

290 
forward = false;

291 
currentEvent = timelineCoordinateRangeStartEvent; 
292 
} 
293 
else if (getTimelineCoordinate(timelineCoordinateRangeEndEvent) <= timelineCoordinate) { 
294 
forward = true;

295 
currentEvent = timelineCoordinateRangeEndEvent; 
296 
} 
297 
else {

298 
forward = true;

299 
currentEvent = timelineCoordinateRangeStartEvent; 
300 
} 
301  
302 
// TODO: LONG RUNNING OPERATION

303 
// does a linear search towards requested non linear timeline coordinate

304 
while (currentEvent && (forward ? getTimelineCoordinate(currentEvent) < timelineCoordinate :

305 
timelineCoordinate <= getTimelineCoordinate(currentEvent))) 
306 
{ 
307 
eventLog>progress(); 
308 
currentEvent = forward ? currentEvent>getNextEvent() : currentEvent>getPreviousEvent(); 
309 
} 
310  
311 
return currentEvent;

312 
} 
313  
314 
IEvent *SequenceChartFacade::getLastEventNotAfterTimelineCoordinate(double timelineCoordinate)

315 
{ 
316 
if (eventLog>isEmpty())

317 
return NULL; 
318  
319 
switch (timelineMode) {

320 
case REAL_TIME:

321 
{ 
322 
//TODO MAKE THIS MORE EFFICIENT (i.e. sorted data structure)!

323 
IEvent* res = eventLog>getFirstEvent(); 
324 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

325 
if ((double) current>getEarliestStartTime() / 1000000.0 < timelineCoordinate) { 
326 
if (current>getEarliestStartTime() > res>getEarliestStartTime()) {

327 
res = current; 
328 
} 
329 
} 
330 
} 
331 
return res;

332 
} 
333 
case SIMULATION_TIME:

334 
return eventLog>getLastEventNotAfterSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));

335 
case EVENT_NUMBER:

336 
{ 
337 
eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber; 
338  
339 
if (eventNumber < 0) 
340 
return NULL; 
341 
else

342 
return eventLog>getLastEventNotAfterEventNumber(eventNumber);

343 
} 
344 
case STEP:

345 
case NONLINEAR:

346 
{ 
347 
bool forward;

348 
IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward); 
349 
currentEvent = forward ? (currentEvent ? currentEvent>getPreviousEvent() : eventLog>getLastEvent()) : currentEvent; 
350  
351 
Assert(!currentEvent  getTimelineCoordinate(currentEvent) <= timelineCoordinate); 
352 
return currentEvent;

353 
} 
354 
default:

355 
throw opp_runtime_error("Unknown timeline mode"); 
356 
} 
357 
} 
358  
359 
IEvent *SequenceChartFacade::getFirstEventNotBeforeTimelineCoordinate(double timelineCoordinate)

360 
{ 
361 
if (eventLog>isEmpty())

362 
return NULL; 
363  
364 
switch (timelineMode) {

365 
case REAL_TIME:

366 
{ 
367 
//TODO MAKE THIS MORE EFFICIENT (i.e. sorted data structure)!

368 
IEvent* res = eventLog>getLastEvent(); 
369 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

370 
if ((double) current>getEarliestStartTime() / 1000000.0 > timelineCoordinate) { 
371 
if (current>getEarliestStartTime() < res>getEarliestStartTime()) {

372 
res = current; 
373 
} 
374 
} 
375 
} 
376 
return res;

377 
} 
378 
case SIMULATION_TIME:

379 
return eventLog>getFirstEventNotBeforeSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));

380 
case EVENT_NUMBER:

381 
{ 
382 
eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber; 
383  
384 
if (eventNumber < 0) 
385 
return eventLog>getFirstEvent();

386 
else

387 
return eventLog>getFirstEventNotBeforeEventNumber(eventNumber);

388 
} 
389 
case STEP:

390 
case NONLINEAR:

391 
{ 
392 
bool forward;

393 
IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward); 
394 
currentEvent = forward ? currentEvent : (currentEvent ? currentEvent>getNextEvent() : eventLog>getFirstEvent()); 
395  
396 
Assert(!currentEvent  getTimelineCoordinate(currentEvent) >= timelineCoordinate); 
397 
return currentEvent;

398 
} 
399 
default:

400 
throw opp_runtime_error("Unknown timeline mode"); 
401 
} 
402 
} 
403  
404 
void SequenceChartFacade::extractSimulationTimesAndTimelineCoordinates(

405 
IEvent *event, IEvent *&nextEvent, 
406 
simtime_t &eventSimulationTime, double &eventTimelineCoordinate,

407 
simtime_t &nextEventSimulationTime, double &nextEventTimelineCoordinate,

408 
simtime_t &simulationTimeDelta, double &timelineCoordinateDelta)

409 
{ 
410 
// if before the first event

411 
if (event) {

412 
if (timelineMode==REAL_TIME) {

413 
eventSimulationTime = event>getEarliestStartTime() / 1000000.0; 
414 
} else {

415 
eventSimulationTime = event>getSimulationTime(); 
416 
} 
417 
eventTimelineCoordinate = getTimelineCoordinate(event); 
418 
} 
419 
else {

420 
eventSimulationTime = BigDecimal::Zero; 
421 
IEvent *firstEvent = eventLog>getFirstEvent(); 
422 
eventTimelineCoordinate = getTimelineCoordinate(firstEvent); 
423  
424 
if (timelineMode == EVENT_NUMBER)

425 
eventTimelineCoordinate = 1;

426 
else if (timelineMode == REAL_TIME) 
427 
eventTimelineCoordinate = getTimelineCoordinateDelta(0);

428 
else

429 
eventTimelineCoordinate = getTimelineCoordinateDelta(firstEvent>getSimulationTime().dbl()); 
430 
} 
431  
432 
// linear approximation between two enclosing events

433 
nextEvent = event ? event>getNextEvent() : eventLog>getFirstEvent(); 
434  
435 
if (nextEvent) {

436 
if(timelineMode==REAL_TIME) {

437 
nextEventSimulationTime = nextEvent>getEarliestStartTime() / 1000000.0; 
438 
} else {

439 
nextEventSimulationTime = nextEvent>getSimulationTime(); 
440 
} 
441  
442 
nextEventTimelineCoordinate = getTimelineCoordinate(nextEvent); 
443  
444 
simulationTimeDelta = nextEventSimulationTime  eventSimulationTime; 
445 
timelineCoordinateDelta = nextEventTimelineCoordinate  eventTimelineCoordinate; 
446 
} 
447 
} 
448  
449 
simtime_t SequenceChartFacade::getSimulationTimeForTimelineCoordinate(double timelineCoordinate, bool upperLimit) 
450 
{ 
451 
Assert(!isNaN(timelineCoordinate)); 
452  
453 
if (eventLog>isEmpty())

454 
return BigDecimal::Zero;

455  
456 
simtime_t simulationTime; 
457  
458 
switch (timelineMode)

459 
{ 
460 
case REAL_TIME:

461 
{ 
462 
simulationTime = max(BigDecimal::Zero, min(biggestEarliestProcessingTime, (timelineCoordinate + timelineCoordinateOriginRealTime))); 
463 
} 
464 
break;

465 
case SIMULATION_TIME:

466 
{ 
467 
IEvent* largestEvent = (IEvent*) getLargestEndtimeInEventRange((ptr_t)(eventLog>getFirstEvent()),(ptr_t)(eventLog>getLastEvent()), upperLimit); 
468 
simtime_t lastEventSimulationTime= largestEvent>getSimulationTime() + largestEvent>getEventEntry()>duration; 
469 
simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, timelineCoordinate + timelineCoordinateOriginSimulationTime)); 
470 
} 
471 
break;

472 
case EVENT_NUMBER:

473 
case STEP:

474 
case NONLINEAR:

475 
{ 
476 
IEvent *nextEvent; 
477 
simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta; 
478 
double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;

479  
480 
IEvent *event = getLastEventNotAfterTimelineCoordinate(timelineCoordinate); 
481 
extractSimulationTimesAndTimelineCoordinates(event, nextEvent, 
482 
eventSimulationTime, eventTimelineCoordinate, 
483 
nextEventSimulationTime, nextEventTimelineCoordinate, 
484 
simulationTimeDelta, timelineCoordinateDelta); 
485  
486 
if (nextEvent) {

487 
if (timelineCoordinateDelta == 0) { 
488 
// IMPORTANT NOTE: this is just an approximation

489 
if (upperLimit)

490 
simulationTime = nextEventSimulationTime; 
491 
else

492 
simulationTime = eventSimulationTime; 
493 
} 
494 
else {

495 
timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate)); 
496 
simulationTime = eventSimulationTime + simulationTimeDelta * (timelineCoordinate  eventTimelineCoordinate) / timelineCoordinateDelta; 
497 
simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime)); 
498 
} 
499 
} 
500 
else

501 
simulationTime = eventSimulationTime; 
502 
} 
503 
break;

504 
default:

505 
throw opp_runtime_error("Unknown timeline mode"); 
506 
} 
507  
508 
Assert(!simulationTime.isNaN()); 
509 
Assert(simulationTime >= BigDecimal::Zero); 
510 
/*if (timelineMode != REAL_TIME)

511 
Assert(simulationTime <= eventLog>getLastEvent()>getSimulationTime());

512 
*/

513 
return simulationTime;

514 
} 
515  
516 
double SequenceChartFacade::getTimelineCoordinateForSimulationTime(simtime_t simulationTime, bool upperLimit) 
517 
{ 
518 
Assert(!simulationTime.isNaN()); 
519  
520 
if (eventLog>isEmpty())

521 
return 0; 
522  
523 
Assert(simulationTime >= BigDecimal::Zero); 
524 
/*if (timelineMode != REAL_TIME)

525 
Assert(simulationTime <= eventLog>getLastEvent()>getSimulationTime());

526 
*/

527  
528 
double timelineCoordinate;

529  
530 
switch (timelineMode)

531 
{ 
532 
case REAL_TIME:

533 
//treat simulationTime as real time:

534 
timelineCoordinate = simulationTime.dbl()  timelineCoordinateOriginRealTime; 
535 
break;

536 
case SIMULATION_TIME:

537 
timelineCoordinate = (simulationTime  timelineCoordinateOriginSimulationTime).dbl(); 
538 
break;

539 
case EVENT_NUMBER:

540 
case STEP:

541 
case NONLINEAR:

542 
{ 
543 
IEvent *nextEvent; 
544 
simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta; 
545 
double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;

546  
547 
IEvent *event = eventLog>getLastEventNotAfterSimulationTime(simulationTime); 
548 
extractSimulationTimesAndTimelineCoordinates(event, nextEvent, 
549 
eventSimulationTime, eventTimelineCoordinate, 
550 
nextEventSimulationTime, nextEventTimelineCoordinate, 
551 
simulationTimeDelta, timelineCoordinateDelta); 
552  
553 
if (nextEvent) {

554 
if (simulationTimeDelta == BigDecimal::Zero) {

555 
// IMPORTANT NOTE: this is just an approximation

556 
if (upperLimit)

557 
timelineCoordinate = nextEventTimelineCoordinate; 
558 
else

559 
timelineCoordinate = eventTimelineCoordinate; 
560 
} 
561 
else {

562 
simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime)); 
563 
timelineCoordinate = eventTimelineCoordinate + timelineCoordinateDelta * (simulationTime  eventSimulationTime).dbl() / simulationTimeDelta.dbl(); 
564 
timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate)); 
565 
} 
566 
} 
567 
else

568 
timelineCoordinate = eventTimelineCoordinate; 
569 
} 
570 
break;

571 
default:

572 
throw opp_runtime_error("Unknown timeline mode"); 
573 
} 
574  
575 
Assert(!isNaN(timelineCoordinate)); 
576  
577 
return timelineCoordinate;

578 
} 
579  
580 
double SequenceChartFacade::getTimelineCoordinateForSimulationTimeAndEventInModule(simtime_t simulationTime, int moduleId) 
581 
{ 
582 
IEvent *event = eventLog>getLastEventNotAfterSimulationTime(simulationTime); 
583  
584 
while (event && event>getSimulationTime() == simulationTime) {

585 
if (event>getModuleId() == moduleId)

586 
return getTimelineCoordinate(event);

587  
588 
event = event>getNextEvent(); 
589 
} 
590  
591 
return getTimelineCoordinateForSimulationTime(simulationTime);

592 
} 
593  
594 
std::vector<ptr_t> *SequenceChartFacade::getModuleMethodBeginEntries(ptr_t startEventPtr, ptr_t endEventPtr) 
595 
{ 
596 
IEvent *startEvent = (IEvent *)startEventPtr; 
597 
IEvent *endEvent = (IEvent *)endEventPtr; 
598 
Assert(startEvent); 
599 
Assert(endEvent); 
600 
std::vector<ptr_t> *moduleMethodBeginEntries = new std::vector<ptr_t>();

601  
602 
for (IEvent *event = startEvent;; event = event>getNextEvent()) {

603 
eventLog>progress(); 
604  
605 
for (int i = 0; i < event>getNumEventLogEntries(); i++) { 
606 
EventLogEntry *eventLogEntry = event>getEventLogEntry(i); 
607  
608 
if (dynamic_cast<ModuleMethodBeginEntry *>(eventLogEntry)) 
609 
moduleMethodBeginEntries>push_back((ptr_t)eventLogEntry); 
610 
} 
611  
612 
if (event == endEvent)

613 
break;

614 
} 
615  
616 
return moduleMethodBeginEntries;

617 
} 
618  
619 
std::vector<ptr_t> *SequenceChartFacade::getIntersectingMessageDependencies(ptr_t startEventPtr, ptr_t endEventPtr) 
620 
{ 
621 
IEvent *startEvent = (IEvent *)startEventPtr; 
622 
IEvent *endEvent = (IEvent *)endEventPtr; 
623 
Assert(startEvent); 
624 
Assert(endEvent); 
625 
std::set<ptr_t> messageDependencies; 
626 
eventnumber_t startEventNumber = startEvent>getEventNumber(); 
627  
628 
// TODO: LONG RUNNING OPERATION

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

630 
// if not completed then some dependencies will not be included

631 
for (IEvent *event = startEvent;; event = event>getNextEvent()) {

632 
eventLog>progress(); 
633 
IMessageDependencyList *causes = event>getCauses(); 
634  
635 
for (IMessageDependencyList::iterator it = causes>begin(); it != causes>end(); it++) {

636 
IMessageDependency *messageDependency = *it; 
637  
638 
if (messageDependency>getCauseEventNumber() < startEventNumber)

639 
messageDependencies.insert((ptr_t)messageDependency); 
640 
} 
641  
642 
IMessageDependencyList *consequences = event>getConsequences(); 
643  
644 
for (IMessageDependencyList::iterator it = consequences>begin(); it != consequences>end(); it++)

645 
messageDependencies.insert((ptr_t)*it); 
646  
647 
if (event == endEvent)

648 
break;

649 
} 
650  
651 
std::vector<ptr_t> *result = new std::vector<ptr_t>;

652 
result>resize(messageDependencies.size()); 
653 
std::copy(messageDependencies.begin(), messageDependencies.end(), result>begin()); 
654  
655 
return result;

656 
} 
657  
658 
std::vector<int> SequenceChartFacade::getApproximateMessageDependencyCountAdjacencyMatrix(std::map<int, int> *moduleIdToAxisIndexMap, int numberOfSamples, int messageSendWeight, int messageReuseWeight) 
659 
{ 
660 
LCGRandom lcgRandom; 
661 
std::vector<int> adjacencyMatrix;

662 
std::set<int> axisIndexSet;

663 
std::map<eventnumber_t, IEvent *> eventNumberToEventMap; 
664  
665 
for (std::map<int, int>::iterator it = moduleIdToAxisIndexMap>begin(); it != moduleIdToAxisIndexMap>end(); it++) 
666 
axisIndexSet.insert(it>second); 
667  
668 
int numberOfAxes = axisIndexSet.size();

669 
adjacencyMatrix.resize(numberOfAxes * numberOfAxes); 
670  
671 
for (int i = 0; i < numberOfSamples; i++) 
672 
{ 
673 
// draw random

674 
double percentage = lcgRandom.next01();

675 
IEvent *event = eventLog>getApproximateEventAt(percentage); 
676 
eventNumberToEventMap[event>getEventNumber()] = event; 
677  
678 
// look before origin

679 
if (timelineCoordinateOriginEventNumber != 1) { 
680 
if (timelineCoordinateOriginEventNumber  i >= 0) { 
681 
event = eventLog>getEventForEventNumber(timelineCoordinateOriginEventNumber  i); 
682 
if (event)

683 
eventNumberToEventMap[event>getEventNumber()] = event; 
684 
} 
685  
686 
// look after origin

687 
event = eventLog>getEventForEventNumber(timelineCoordinateOriginEventNumber + i); 
688 
if (event)

689 
eventNumberToEventMap[event>getEventNumber()] = event; 
690 
} 
691 
} 
692  
693 
for (std::map<eventnumber_t, IEvent *>::iterator it = eventNumberToEventMap.begin(); it != eventNumberToEventMap.end(); it++) {

694 
IEvent *event = it>second; 
695 
IMessageDependencyList *causes = event>getCauses(); 
696  
697 
for (IMessageDependencyList::iterator it = causes>begin(); it != causes>end(); it++) {

698 
IMessageDependency *messageDependency = *it; 
699 
IEvent *causeEvent = messageDependency>getCauseEvent(); 
700 
IEvent *consequenceEvent = messageDependency>getConsequenceEvent(); 
701 
int weight = messageDependency>getIsReuse() ? messageReuseWeight : messageSendWeight;

702  
703 
if (causeEvent && consequenceEvent && weight != 0) { 
704 
int causeModuleId = causeEvent>getModuleId();

705 
int consequenceModuleId = consequenceEvent>getModuleId();

706  
707 
std::map<int, int>::iterator causeModuleIdIt = moduleIdToAxisIndexMap>find(causeModuleId); 
708 
std::map<int, int>::iterator consequenceModuleIdIt = moduleIdToAxisIndexMap>find(consequenceModuleId); 
709  
710 
if (causeModuleIdIt != moduleIdToAxisIndexMap>end() && consequenceModuleIdIt != moduleIdToAxisIndexMap>end())

711 
adjacencyMatrix.at(causeModuleIdIt>second * numberOfAxes + consequenceModuleIdIt>second) += weight; 
712 
} 
713 
} 
714 
} 
715  
716 
return adjacencyMatrix;

717 
} 
718  
719  
720 
long SequenceChartFacade::getSmallestEventComplexity() {

721 
long complexity = 0; 
722 
if (smallestComplexity < 0) { 
723 
for (IEvent *event = eventLog>getFirstEvent();event != eventLog>getLastEvent(); event = event>getNextEvent()) {

724 
if (event>getEventEndEntry()) {

725 
complexity = event>getEventEndEntry()>complexity; 
726 
} else {

727 
continue;

728 
} 
729 
if (complexity < smallestComplexity  smallestComplexity < 0) { 
730 
smallestComplexity = complexity; 
731 
} 
732 
if (complexity > largestComplexity  largestComplexity < 0) { 
733 
largestComplexity = complexity; 
734 
} 
735 
} 
736 
} 
737 
if (smallestComplexity < 0) { 
738 
smallestComplexity = 0;

739 
} 
740 
return smallestComplexity;

741 
} 
742  
743 
long SequenceChartFacade::getLargestEventComplexity() {

744 
if (largestComplexity < 0) { 
745 
getSmallestEventComplexity(); 
746 
} 
747 
if (largestComplexity < 0) { 
748 
largestComplexity = 0;

749 
} 
750 
return largestComplexity;

751 
} 
752  
753 
simtime_t SequenceChartFacade::getSmallestEventDuration() { 
754 
simtime_t duration = 0;

755 
if (smallestDuration < 0) { 
756 
for (IEvent *event = eventLog>getFirstEvent();event != eventLog>getLastEvent(); event = event>getNextEvent()) {

757 
if (event>getEventEntry()) {

758 
duration = event>getEventEntry()>duration; 
759 
} else {

760 
continue;

761 
} 
762 
if (duration < smallestDuration  smallestDuration < 0) { 
763 
smallestDuration = duration; 
764 
} 
765 
if (duration > largestDuration  largestDuration < 0) { 
766 
largestDuration = duration; 
767 
} 
768 
} 
769 
} 
770 
if (smallestDuration < 0) { 
771 
smallestDuration = 0;

772 
} 
773 
return smallestDuration;

774 
} 
775  
776 
simtime_t SequenceChartFacade::getLargestEventDuration() { 
777 
if (largestDuration < 0) { 
778 
getSmallestEventComplexity(); 
779 
} 
780 
if (largestDuration < 0) { 
781 
largestDuration = 0;

782 
} 
783 
return largestDuration;

784 
} 
785  
786  
787 
IEvent* SequenceChartFacade::getPreviousBottleneck(IEvent* e, double threshold) {

788 
IEvent* next = e>getPreviousEvent(); 
789 
while (next) {

790 
if (isBottleneck(next,threshold)) {

791 
return next;

792 
} 
793 
next = next>getPreviousEvent(); 
794 
} 
795 
return e;

796 
} 
797  
798 
IEvent* SequenceChartFacade::getNextBottleneck(IEvent* e, double threshold) {

799 
IEvent* next = e>getNextEvent(); 
800 
while (next) {

801 
if (isBottleneck(next,threshold)) {

802 
return next;

803 
} 
804 
next = next>getNextEvent(); 
805 
} 
806 
return e;

807 
} 
808  
809 
/*

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

811 
*/

812 
bool SequenceChartFacade::isBottleneck(IEvent* event, double threshold) 
813 
{ 
814 
if (isOnCriticalPath(event)) {

815 
return getOverlappingQuotient((ptr_t)event) <= threshold;

816 
} 
817 
return false; 
818 
} 
819 
/*

820 
* Returns whether event is in the largest parallel set of selected.

821 
*/

822 
bool SequenceChartFacade::isParallelWithEvent(IEvent* event, IEvent* selected) {

823  
824 
if (lastSelected != selected) {

825 
getLargestParallelSet(selected, &cachedParallelSet); 
826 
} 
827 
return cachedParallelSet.find((ptr_t)event) != cachedParallelSet.end();

828 
} 
829 
/*

830 
* Returns the size of the largest set that is parallel with event.

831 
*

832 
* Works by calculating the first parallel set which does not contain event by

833 
* successively going backwards through all events starting from event.

834 
*/

835 
unsigned int SequenceChartFacade::getLargestParallelSetSize(IEvent* event) 
836 
{ 
837 
IEvent* prev = event; 
838 
std::set<ptr_t> parallelSet; 
839 
parallelSet.clear(); 
840 
unsigned int previousSize = 0; 
841 
while (prev)

842 
{ 
843 
previousSize = parallelSet.size(); 
844  
845 
getParallelSet(prev, ¶llelSet); 
846  
847 
if (parallelSet.find((ptr_t) event) == parallelSet.end())

848 
{ 
849 
//The current set does not contain event.

850 
//Therefore the previous set was the largest Parallel Set.

851 
break;

852 
} 
853 
prev = prev>getPreviousEvent(); 
854 
} 
855 
return previousSize;

856 
} 
857 
/*

858 
* Returns the largest set that is parallel with event.

859 
*

860 
* Works by calculating the first parallel set which does not contain event by

861 
* successively going backwards through all events starting from event.

862 
*/

863 
std::set<ptr_t>* SequenceChartFacade::getLargestParallelSet(IEvent* event, std::set<ptr_t>* parallelSet) { 
864 
IEvent* prev = event; 
865 
parallelSet>clear(); 
866 
while (prev)

867 
{ 
868 
getParallelSet(prev, parallelSet); 
869 
if (parallelSet>find((ptr_t) event) == parallelSet>end())

870 
{ 
871 
//The current set does not contain event.

872 
//Therefore the previous set was the largest Parallel Set.

873 
break;

874 
} 
875 
prev = prev>getPreviousEvent(); 
876 
} 
877 
if (prev != event) {

878 
getParallelSet(prev>getNextEvent(), parallelSet); 
879 
} 
880 
return parallelSet;

881 
} 
882  
883 
/*

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

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

886 
*/

887 
void SequenceChartFacade::getParallelSet(IEvent* event,

888 
std::set<ptr_t>* parallelSet) 
889 
{ 
890 
IEvent* next = event>getNextEvent(); 
891 
simtime_t smallestParallelEndtime = getSmallestParallelEndtime(event); 
892 
parallelSet>clear(); 
893 
parallelSet>insert((ptr_t) event); 
894 
while (next)

895 
{ 
896 
if ((next>getSimulationTime() >= event>getSimulationTime())

897 
&& (smallestParallelEndtime >= next>getSimulationTime())) 
898 
{ 
899 
if(parallelSet>find((ptr_t)(next>getCauseEvent())) == parallelSet>end()) {

900 
parallelSet>insert((ptr_t) next); 
901 
} 
902 
} 
903 
else

904 
{ 
905 
break;

906 
} 
907 
next = next>getNextEvent(); 
908 
} 
909 
} 
910 
/*

911 
*

912 
*/

913 
simtime_t SequenceChartFacade::getSmallestParallelEndtime(IEvent* event) 
914 
{ 
915 
simtime_t minimum = event>getSimulationTime() 
916 
+ event>getEventEntry()>duration; 
917 
for (IEvent *current = eventLog>getFirstEvent(); current; current

918 
= current>getNextEvent()) 
919 
{ 
920 
if (current>getSimulationTime() >= event>getSimulationTime())

921 
{ 
922 
if ((current>getSimulationTime()

923 
+ current>getEventEntry()>duration) 
924 
> event>getSimulationTime()) 
925 
{ 
926 
if (minimum > (current>getSimulationTime()

927 
+ current>getEventEntry()>duration)) 
928 
{ 
929 
minimum = current>getSimulationTime() 
930 
+ current>getEventEntry()>duration; 
931 
} 
932 
} 
933 
if (current>getSimulationTime() > minimum)

934 
{ // After this, no overlapping can follow

935 
break;

936 
} 
937 
} 
938 
} 
939 
return minimum;

940 
} 
941  
942 
/*

943 
* Determines whether the event lies on the critical path

944 
*/

945 
bool SequenceChartFacade::isOnCriticalPath(IEvent* event) {

946 
if (cachedCriticalPath.empty()) {

947 
calculateCriticalPath(); 
948 
} 
949 
return (cachedCriticalPath.find((ptr_t)event) != cachedCriticalPath.end());

950 
} 
951  
952 
/*

953 
* Calculates the critical path of the run and stores it in the set cachedCriticalPath

954 
* Caches the earliestStartTimes of all events

955 
*/

956 
void SequenceChartFacade::calculateCriticalPath() {

957 
long maxEarliestProcessingTime = 0; 
958 
IEvent* maxEarliestProcessingTimeEvent; 
959  
960 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

961 
simtime_t startTime = current>getSimulationTime(); 
962 
int moduleId = current>getModuleId();

963 
if(current>getEventEndEntry()) {

964 
current>_earliestProcessingTime = current>getComplexity(); 
965 
} 
966  
967 
current>setCriticalPredecessor(eventLog>getFirstEvent()); 
968  
969 
for (IEvent *antecessor = eventLog>getFirstEvent(); antecessor; antecessor = antecessor>getNextEvent()) {

970 
if(antecessor==current) {

971 
break; //We have to consider earlier events only 
972 
} 
973 
if(antecessor>getModuleId() != moduleId && current>getCauseEvent() != antecessor) {

974 
continue; // Check if this is an antecessor 
975 
} 
976 
if(antecessor>_earliestProcessingTime+current>getComplexity() > current>_earliestProcessingTime) {

977 
current>_earliestProcessingTime = antecessor>_earliestProcessingTime+current>getComplexity(); 
978 
current>setCriticalPredecessor(antecessor); 
979 
} 
980 
} 
981 
// Memorize max event

982 
if (maxEarliestProcessingTime < current>_earliestProcessingTime) {

983 
maxEarliestProcessingTime = current>_earliestProcessingTime; 
984 
maxEarliestProcessingTimeEvent = current; 
985 
} 
986 
} 
987 
//Cache an additional event ordering sorted by their earliestStartingTimes

988 
cacheRealTimeEventOrder(); 
989  
990 
//Now produce the convex hull of critical antecessors/predecessors:

991 
cachedCriticalPath.clear(); 
992 
//Cache largest processing time:

993 
biggestEarliestProcessingTime = maxEarliestProcessingTime / 1000000.0; 
994 
biggestEarliestProcessingTimeEvent = maxEarliestProcessingTimeEvent; 
995 
for (IEvent *predecessor = maxEarliestProcessingTimeEvent; predecessor ; predecessor = predecessor>getCriticalPredecessor()) {

996 
cachedCriticalPath.insert((ptr_t)predecessor); 
997 
if(predecessor>getEventNumber() == 0) { 
998 
break;

999 
} 
1000 
} 
1001 
} 
1002 
/*

1003 
* Returns the event with the largest calculated earliest Processing time in REAL_TIME mode

1004 
* or the largest endtime in other modes within the given event range.

1005 
*/

1006 
ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr, 
1007 
ptr_t endEventPtr, bool duration)

1008 
{ 
1009 
IEvent *startEvent = (IEvent *) startEventPtr; 
1010 
IEvent *endEvent = (IEvent *) endEventPtr; 
1011 
switch (timelineMode)

1012 
{ 
1013 
case REAL_TIME:

1014 
{ 
1015 
//Use cached result when range contains all events

1016 
if (startEvent == eventLog>getFirstEvent() && endEvent

1017 
== eventLog>getLastEvent()) 
1018 
{ 
1019 
return (ptr_t) biggestEarliestProcessingTimeEvent;

1020 
} 
1021  
1022 
long largest = 0; 
1023 
IEvent* largestEvent = startEvent; 
1024  
1025 
for (IEvent* current = startEvent; current; current

1026 
= current>getNextEvent()) 
1027 
{ 
1028 
long temp = current>getEarliestProcessingTime();

1029 
if (temp > largest)

1030 
{ 
1031 
largest = temp; 
1032 
largestEvent = current; 
1033 
} 
1034 
if (current == endEvent)

1035 
{ 
1036 
break;

1037 
} 
1038 
} 
1039 
return (ptr_t) largestEvent;

1040 
} 
1041 
case SIMULATION_TIME:

1042 
case EVENT_NUMBER:

1043 
case STEP:

1044 
case NONLINEAR:

1045 
default:

1046 
{ 
1047 
if (!duration) {

1048 
return endEventPtr;

1049 
} 
1050 
//Use cached result when range contains all events

1051 
if (startEvent == eventLog>getFirstEvent() && endEvent

1052 
== eventLog>getLastEvent() && biggestEndTimeEvent != NULL)

1053 
{ 
1054 
return (ptr_t) biggestEndTimeEvent;

1055 
} 
1056 
simtime_t largest = 0;

1057 
IEvent* largestEvent = endEvent; 
1058  
1059 
for (IEvent* current = endEvent; current; current

1060 
= current>getPreviousEvent()) 
1061 
{ 
1062 
simtime_t temp = current>getSimulationTime() 
1063 
+ current>getEventEntry()>duration; 
1064 
if (temp > largest)

1065 
{ 
1066 
largest = temp; 
1067 
largestEvent = current; 
1068 
} 
1069 
if (current == startEvent)

1070 
{ 
1071 
break;

1072 
} 
1073 
} 
1074 
if (startEvent == eventLog>getFirstEvent() && endEvent

1075 
== eventLog>getLastEvent()) 
1076 
{ 
1077 
biggestEndTimeEvent = largestEvent; 
1078 
} 
1079  
1080 
return (ptr_t) largestEvent;

1081 
} 
1082 
} 
1083  
1084 
} 
1085  
1086 
double SequenceChartFacade::getOverlapping(ptr_t eventPtr) {

1087 
long overlapping = 0; 
1088 
IEvent* event = (IEvent*) eventPtr; 
1089  
1090 
long eventProcessingTime = event>getEarliestProcessingTime();

1091 
long eventStartTime = event>getEarliestStartTime();

1092  
1093 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

1094  
1095 
if(current>getComplexity() == 0) { 
1096 
continue;

1097 
} 
1098  
1099 
long currentStartTime = current>getEarliestStartTime();

1100 
long currentProcessingTime = current>getEarliestProcessingTime();

1101  
1102 
if(eventStartTime <= currentStartTime && eventProcessingTime >= currentStartTime) {

1103 
overlapping += eventProcessingTime  currentStartTime; 
1104 
} else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventStartTime) { 
1105 
overlapping += currentProcessingTime  eventStartTime; 
1106 
} else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventProcessingTime) { 
1107 
overlapping += event>getComplexity(); 
1108 
} 
1109 
} 
1110 
return overlapping / (event>getComplexity() * 1.0); 
1111 
} 
1112  
1113 
double SequenceChartFacade::getMaximumOverlapping() {

1114 
double maxOverlapping = 0; 
1115 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

1116 
if(!isOnCriticalPath(current)  current>getComplexity() == 0) { 
1117 
continue;

1118 
} 
1119 
double overlapping = getOverlapping((ptr_t) current);

1120 
if (overlapping > maxOverlapping){

1121 
maxOverlapping = overlapping; 
1122 
} 
1123 
} 
1124 
return maxOverlapping;

1125 
} 
1126  
1127 
/*

1128 
* returns the quotient of

1129 
* relative overlapping cputime with the event / maximum relative overlapping

1130 
* cputime with any event of the critical path

1131 
*/

1132 
double SequenceChartFacade::getOverlappingQuotient(ptr_t eventPtr) {

1133  
1134 
if (((IEvent*)eventPtr)>getComplexity() == 0) { 
1135 
return 0; 
1136 
} 
1137 
double overlapping = getOverlapping(eventPtr);

1138  
1139 
if (maximumOverlapping == 1) { 
1140 
maximumOverlapping = getMaximumOverlapping(); 
1141 
} 
1142  
1143 
return overlapping / maximumOverlapping;

1144 
} 
1145  
1146 
bool SequenceChartFacade::isOverlappingInRealTimeDomain(ptr_t eventPtr1, ptr_t eventPtr2) {

1147 
long eventProcessingTime1 = ((IEvent*)eventPtr1)>getEarliestProcessingTime();

1148 
long eventStartTime1 = ((IEvent*)eventPtr1)>getEarliestStartTime();

1149 
long eventProcessingTime2 = ((IEvent*)eventPtr2)>getEarliestProcessingTime();

1150 
long eventStartTime2 = ((IEvent*)eventPtr2)>getEarliestStartTime();

1151  
1152 
return !(eventProcessingTime1 < eventStartTime2  eventProcessingTime2 < eventStartTime1);

1153 
} 
1154  
1155  
1156 
bool compare_events_realtime (IEvent* a, IEvent* b)

1157 
{ 
1158 
return a>getEarliestStartTime() <= b>getEarliestStartTime();

1159 
} 
1160  
1161  
1162 
void SequenceChartFacade::cacheRealTimeEventOrder() {

1163 
//First Event is the same in both domains

1164 
eventLog>setFirstEventRealTime((Event*)eventLog>getFirstEvent()); 
1165 
int i = 0; 
1166 
std::list<IEvent*> eventMap; 
1167 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

1168 
i++; 
1169 
eventMap.push_back(current); 
1170 
} 
1171 
eventMap.sort(compare_events_realtime); 
1172  
1173 
IEvent* current = NULL;

1174 
IEvent* prev = NULL;

1175 
for (std::list<IEvent*>::iterator it = eventMap.begin(); it != eventMap.end(); it++) {

1176 
current = *it; 
1177 
if (prev != NULL) { 
1178 
prev>setNextEventRealTime(current); 
1179 
current>setPreviousEventRealTime(prev); 
1180 
} 
1181 
prev = current; 
1182 
} 
1183 
//Set last event in eventlog

1184 
eventLog>setLastEventRealTime((Event*)prev); 
1185 
//Test:

1186 
for (IEvent *current = eventLog>getFirstEventRealTime(); current; current = current>getNextEventRealTime()) {

1187 
printf("event %i, simtime %f, time %i \n",current>getEventNumber(), current>getSimulationTime().dbl(), current>getEarliestStartTime());

1188 
} 
1189  
1190  
1191 
} 