root / src / eventlog / sequencechartfacade.cc @ 943aa6e2
History  View  Annotate  Download (42.3 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 <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  
39 
smallestComplexity = 1;

40 
largestComplexity = 1;

41  
42 
smallestDuration = 1;

43 
largestDuration = 1;

44  
45 
maximumOverlapping = 1;

46  
47 
biggestEarliestProcessingTime = 0;

48  
49 
biggestEndTimeEvent = NULL;

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

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

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

66 
relocateTimelineCoordinateSystem(event); 
67 
else

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

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

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

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

78 
double totalSimulationTimeDelta = lastEventSimulationTime  firstEventSimulationTime;

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

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

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

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

101 
this>nonLinearFocus = nonLinearFocus;

102 
} 
103  
104 
void SequenceChartFacade::undefineTimelineCoordinateSystem()

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

108 
timelineCoordinateOriginSimulationTime = simtime_nil; 
109 
timelineCoordinateOriginRealTime = 0;

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

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

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

125 
{ 
126 
this>timelineMode = timelineMode;

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

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

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

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

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

147  
148 
if (timelineMode == STEP)

149 
return 1; 
150 
else

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

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

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

171 
Assert(timelineCoordinateOriginEventNumber != 1);

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

175  
176 
switch (timelineMode) {

177 
case REAL_TIME:

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

180 
case SIMULATION_TIME:

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

183 
case EVENT_NUMBER:

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

186 
case STEP:

187 
case NONLINEAR:

188 
{ 
189 
IEvent *previousEvent = NULL;

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

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

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

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

198 
do {

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

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

210  
211 
if (forward) {

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

215 
return NaN;

216 
} 
217 
else {

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

221 
return NaN;

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

228  
229 
if (forward)

230 
timelineCoordinateRangeEndEventNumber = event>getEventNumber(); 
231 
else

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

235 
default:

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

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

251 
return getTimelineCoordinate(event);

252 
} 
253 
double timelineEventEndCoordinate;

254 
switch (timelineMode) {

255 
case REAL_TIME:

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

258 
case SIMULATION_TIME:

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

261 
default:

262 
return getTimelineCoordinate(event);

263 
} 
264 
return timelineEventEndCoordinate;

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

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

271 
Assert(timelineCoordinateOriginEventNumber != 1);

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

276 
return event>cachedTimelineCoordinate;

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

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

289 
forward = false;

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

294 
currentEvent = timelineCoordinateRangeEndEvent; 
295 
} 
296 
else {

297 
forward = true;

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

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

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

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

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

314 
{ 
315 
if (eventLog>isEmpty())

316 
return NULL; 
317  
318 
switch (timelineMode) {

319 
case REAL_TIME:

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

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

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

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

331 
} 
332 
case SIMULATION_TIME:

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

334 
case EVENT_NUMBER:

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

341 
return eventLog>getLastEventNotAfterEventNumber(eventNumber);

342 
} 
343 
case STEP:

344 
case NONLINEAR:

345 
{ 
346 
bool forward;

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

352 
} 
353 
default:

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

359 
{ 
360 
if (eventLog>isEmpty())

361 
return NULL; 
362  
363 
switch (timelineMode) {

364 
case REAL_TIME:

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

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

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

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

376 
} 
377 
case SIMULATION_TIME:

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

379 
case EVENT_NUMBER:

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

385 
else

386 
return eventLog>getFirstEventNotBeforeEventNumber(eventNumber);

387 
} 
388 
case STEP:

389 
case NONLINEAR:

390 
{ 
391 
bool forward;

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

397 
} 
398 
default:

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

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

406 
simtime_t &nextEventSimulationTime, double &nextEventTimelineCoordinate,

407 
simtime_t &simulationTimeDelta, double &timelineCoordinateDelta)

408 
{ 
409 
// if before the first event

410 
if (event) {

411 
if (timelineMode==REAL_TIME) {

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

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

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

424 
eventTimelineCoordinate = 1;

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

427 
else

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

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

435 
if(timelineMode==REAL_TIME) {

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

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

453 
return BigDecimal::Zero;

454  
455 
simtime_t simulationTime; 
456  
457 
switch (timelineMode)

458 
{ 
459 
case REAL_TIME:

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

464 
case SIMULATION_TIME:

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

471 
case EVENT_NUMBER:

472 
case STEP:

473 
case NONLINEAR:

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

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

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

488 
if (upperLimit)

489 
simulationTime = nextEventSimulationTime; 
490 
else

491 
simulationTime = eventSimulationTime; 
492 
} 
493 
else {

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

500 
simulationTime = eventSimulationTime; 
501 
} 
502 
break;

503 
default:

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

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

511 
*/

512 
return simulationTime;

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

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

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

525 
*/

526  
527 
double timelineCoordinate;

528  
529 
switch (timelineMode)

530 
{ 
531 
case REAL_TIME:

532 
//treat simulationTime as real time:

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

535 
case SIMULATION_TIME:

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

538 
case EVENT_NUMBER:

539 
case STEP:

540 
case NONLINEAR:

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

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

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

554 
// IMPORTANT NOTE: this is just an approximation

555 
if (upperLimit)

556 
timelineCoordinate = nextEventTimelineCoordinate; 
557 
else

558 
timelineCoordinate = eventTimelineCoordinate; 
559 
} 
560 
else {

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

567 
timelineCoordinate = eventTimelineCoordinate; 
568 
} 
569 
break;

570 
default:

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

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

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

585 
return getTimelineCoordinate(event);

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

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

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

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

612 
break;

613 
} 
614  
615 
return moduleMethodBeginEntries;

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

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

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

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

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

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

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

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

647 
break;

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

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

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

661 
std::set<int> axisIndexSet;

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

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

673 
double percentage = lcgRandom.next01();

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

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

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

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

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

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

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

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

704 
int consequenceModuleId = consequenceEvent>getModuleId();

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

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

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

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

723 
if (event>getEventEndEntry()) {

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

726 
continue;

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

738 
} 
739 
return smallestComplexity;

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

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

748 
} 
749 
return largestComplexity;

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

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

756 
if (event>getEventEntry()) {

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

759 
continue;

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

771 
} 
772 
return smallestDuration;

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

781 
} 
782 
return largestDuration;

783 
} 
784  
785  
786 
IEvent* SequenceChartFacade::getPreviousBottleneck(IEvent* e, unsigned int threshold) { 
787 
IEvent* next = e>getPreviousEvent(); 
788 
while (next) {

789 
if (isBottleneck(next,threshold)) {

790 
return next;

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

795 
} 
796  
797 
IEvent* SequenceChartFacade::getNextBottleneck(IEvent* e, unsigned int threshold) { 
798 
IEvent* next = e>getNextEvent(); 
799 
while (next) {

800 
if (isBottleneck(next,threshold)) {

801 
return next;

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

806 
} 
807  
808 
/*

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

810 
*/

811 
bool SequenceChartFacade::isBottleneck(IEvent* event, unsigned int threshold) 
812 
{ 
813 
return getLargestParallelSetSize(event) <= threshold;

814 
} 
815 
/*

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

817 
*/

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

819  
820 
if (lastSelected != selected) {

821 
getLargestParallelSet(selected, &cachedParallelSet); 
822 
} 
823 
return cachedParallelSet.find((ptr_t)event) != cachedParallelSet.end();

824 
} 
825 
/*

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

827 
*

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

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

830 
*/

831 
unsigned int SequenceChartFacade::getLargestParallelSetSize(IEvent* event) 
832 
{ 
833 
IEvent* prev = event; 
834 
std::set<ptr_t> parallelSet; 
835 
parallelSet.clear(); 
836 
unsigned int previousSize = 0; 
837 
while (prev)

838 
{ 
839 
previousSize = parallelSet.size(); 
840  
841 
getParallelSet(prev, ¶llelSet); 
842  
843 
if (parallelSet.find((ptr_t) event) == parallelSet.end())

844 
{ 
845 
//The current set does not contain event.

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

847 
break;

848 
} 
849 
prev = prev>getPreviousEvent(); 
850 
} 
851 
return previousSize;

852 
} 
853 
/*

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

855 
*

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

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

858 
*/

859 
std::set<ptr_t>* SequenceChartFacade::getLargestParallelSet(IEvent* event, std::set<ptr_t>* parallelSet) { 
860 
IEvent* prev = event; 
861 
parallelSet>clear(); 
862 
while (prev)

863 
{ 
864 
getParallelSet(prev, parallelSet); 
865 
if (parallelSet>find((ptr_t) event) == parallelSet>end())

866 
{ 
867 
//The current set does not contain event.

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

869 
break;

870 
} 
871 
prev = prev>getPreviousEvent(); 
872 
} 
873 
if (prev != event) {

874 
getParallelSet(prev>getNextEvent(), parallelSet); 
875 
} 
876 
return parallelSet;

877 
} 
878  
879 
/*

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

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

882 
*/

883 
void SequenceChartFacade::getParallelSet(IEvent* event,

884 
std::set<ptr_t>* parallelSet) 
885 
{ 
886 
IEvent* next = event>getNextEvent(); 
887 
simtime_t smallestParallelEndtime = getSmallestParallelEndtime(event); 
888 
parallelSet>clear(); 
889 
parallelSet>insert((ptr_t) event); 
890 
while (next)

891 
{ 
892 
if ((next>getSimulationTime() >= event>getSimulationTime())

893 
&& (smallestParallelEndtime >= next>getSimulationTime())) 
894 
{ 
895 
if(parallelSet>find((ptr_t)(next>getCauseEvent())) == parallelSet>end()) {

896 
parallelSet>insert((ptr_t) next); 
897 
} 
898 
} 
899 
else

900 
{ 
901 
break;

902 
} 
903 
next = next>getNextEvent(); 
904 
} 
905 
} 
906 
/*

907 
*

908 
*/

909 
simtime_t SequenceChartFacade::getSmallestParallelEndtime(IEvent* event) 
910 
{ 
911 
simtime_t minimum = event>getSimulationTime() 
912 
+ event>getEventEntry()>duration; 
913 
for (IEvent *current = eventLog>getFirstEvent(); current; current

914 
= current>getNextEvent()) 
915 
{ 
916 
if (current>getSimulationTime() >= event>getSimulationTime())

917 
{ 
918 
if ((current>getSimulationTime()

919 
+ current>getEventEntry()>duration) 
920 
> event>getSimulationTime()) 
921 
{ 
922 
if (minimum > (current>getSimulationTime()

923 
+ current>getEventEntry()>duration)) 
924 
{ 
925 
minimum = current>getSimulationTime() 
926 
+ current>getEventEntry()>duration; 
927 
} 
928 
} 
929 
if (current>getSimulationTime() > minimum)

930 
{ // After this, no overlapping can follow

931 
break;

932 
} 
933 
} 
934 
} 
935 
return minimum;

936 
} 
937  
938 
/*

939 
* Determines whether the event lies on the critical path

940 
*/

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

942 
if (cachedCriticalPath.empty()) {

943 
calculateCriticalPath(); 
944 
} 
945 
return (cachedCriticalPath.find((ptr_t)event) != cachedCriticalPath.end());

946 
} 
947  
948 
/*

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

950 
*/

951 
void SequenceChartFacade::calculateCriticalPath() {

952 
long maxEarliestProcessingTime = 0; 
953 
IEvent* maxEarliestProcessingTimeEvent; 
954  
955 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

956 
simtime_t startTime = current>getSimulationTime(); 
957 
int moduleId = current>getModuleId();

958 
if(current>getEventEndEntry()) {

959 
current>_earliestProcessingTime = current>getComplexity(); 
960 
} 
961  
962 
current>setCriticalPredecessor(eventLog>getFirstEvent()); 
963  
964 
for (IEvent *antecessor = eventLog>getFirstEvent(); antecessor; antecessor = antecessor>getNextEvent()) {

965 
if(antecessor==current) {

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

969 
continue; // Check if this is an antecesor 
970 
} 
971 
if(antecessor>_earliestProcessingTime+current>getComplexity() > current>_earliestProcessingTime) {

972 
current>_earliestProcessingTime = antecessor>_earliestProcessingTime+current>getComplexity(); 
973 
current>setCriticalPredecessor(antecessor); 
974 
} 
975 
} 
976 
// Memorize max event

977 
if (maxEarliestProcessingTime < current>_earliestProcessingTime) {

978 
maxEarliestProcessingTime = current>_earliestProcessingTime; 
979 
maxEarliestProcessingTimeEvent = current; 
980 
} 
981 
} 
982 
//Now produce the convex hull of critical antecessors/predecessors:

983 
cachedCriticalPath.clear(); 
984 
//Cache largest processing time:

985 
biggestEarliestProcessingTime = maxEarliestProcessingTime / 1000000.0; 
986 
biggestEarliestProcessingTimeEvent = maxEarliestProcessingTimeEvent; 
987 
for (IEvent *predecessor = maxEarliestProcessingTimeEvent; predecessor ; predecessor = predecessor>getCriticalPredecessor()) {

988 
cachedCriticalPath.insert((ptr_t)predecessor); 
989 
if(predecessor>getEventNumber() == 0) { 
990 
break;

991 
} 
992 
} 
993 
} 
994 
/*

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

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

997 
*/

998 
ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr, 
999 
ptr_t endEventPtr, bool duration)

1000 
{ 
1001 
IEvent *startEvent = (IEvent *) startEventPtr; 
1002 
IEvent *endEvent = (IEvent *) endEventPtr; 
1003 
switch (timelineMode)

1004 
{ 
1005 
case REAL_TIME:

1006 
{ 
1007 
//Use cached result when range contains all events

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

1009 
== eventLog>getLastEvent()) 
1010 
{ 
1011 
return (ptr_t) biggestEarliestProcessingTimeEvent;

1012 
} 
1013  
1014 
long largest = 0; 
1015 
IEvent* largestEvent = startEvent; 
1016  
1017 
for (IEvent* current = startEvent; current; current

1018 
= current>getNextEvent()) 
1019 
{ 
1020 
long temp = current>getEarliestProcessingTime();

1021 
if (temp > largest)

1022 
{ 
1023 
largest = temp; 
1024 
largestEvent = current; 
1025 
} 
1026 
if (current == endEvent)

1027 
{ 
1028 
break;

1029 
} 
1030 
} 
1031 
return (ptr_t) largestEvent;

1032 
} 
1033 
case SIMULATION_TIME:

1034 
case EVENT_NUMBER:

1035 
case STEP:

1036 
case NONLINEAR:

1037 
default:

1038 
{ 
1039 
if (!duration) {

1040 
return endEventPtr;

1041 
} 
1042 
//Use cached result when range contains all events

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

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

1045 
{ 
1046 
return (ptr_t) biggestEndTimeEvent;

1047 
} 
1048 
simtime_t largest = 0;

1049 
IEvent* largestEvent = endEvent; 
1050  
1051 
for (IEvent* current = endEvent; current; current

1052 
= current>getPreviousEvent()) 
1053 
{ 
1054 
simtime_t temp = current>getSimulationTime() 
1055 
+ current>getEventEntry()>duration; 
1056 
if (temp > largest)

1057 
{ 
1058 
largest = temp; 
1059 
largestEvent = current; 
1060 
} 
1061 
if (current == startEvent)

1062 
{ 
1063 
break;

1064 
} 
1065 
} 
1066 
if (startEvent == eventLog>getFirstEvent() && endEvent

1067 
== eventLog>getLastEvent()) 
1068 
{ 
1069 
biggestEndTimeEvent = largestEvent; 
1070 
} 
1071  
1072 
return (ptr_t) largestEvent;

1073 
} 
1074 
} 
1075  
1076 
} 
1077  
1078 
double SequenceChartFacade::getOverlapping(ptr_t eventPtr) {

1079 
long overlapping = 0; 
1080 
IEvent* event = (IEvent*) eventPtr; 
1081  
1082 
long eventProcessingTime = event>getEarliestProcessingTime();

1083 
long eventStartTime = event>getEarliestStartTime();

1084  
1085 
for (IEvent *current = eventLog>getFirstEvent(); current; current = current>getNextEvent()) {

1086  
1087 
if(current>getComplexity() == 0) { 
1088 
continue;

1089 
} 
1090  
1091 
long currentStartTime = current>getEarliestStartTime();

1092 
long currentProcessingTime = current>getEarliestProcessingTime();

1093  
1094 
if(eventStartTime <= currentStartTime && eventProcessingTime >= currentStartTime) {

1095 
overlapping += eventProcessingTime  currentStartTime; 
1096 
} else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventStartTime) { 
1097 
overlapping += currentProcessingTime  eventStartTime; 
1098 
} else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventProcessingTime) { 
1099 
overlapping += event>getComplexity(); 
1100 
} 
1101 
} 
1102 
printf("overlapping %i %f %i %i\n", overlapping, overlapping / (event>getComplexity() * 1.0), event>getComplexity(), event>getEventNumber()); 
1103 
return overlapping / (event>getComplexity() * 1.0); 
1104 
} 
1105  
1106 
double SequenceChartFacade::getMaximumOverlapping() {

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

1109 
if(!isOnCriticalPath(current)  current>getComplexity() == 0) { 
1110 
continue;

1111 
} 
1112 
double overlapping = getOverlapping((ptr_t) current);

1113 
if (overlapping > maxOverlapping){

1114 
maxOverlapping = overlapping; 
1115 
} 
1116 
} 
1117 
printf("maxoverlapping %i \n", maxOverlapping);

1118 
return maxOverlapping;

1119 
} 
1120  
1121 
/*

1122 
* returns the quotient of

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

1124 
* cputime with any event of the critical path

1125 
*/

1126 
double SequenceChartFacade::getOverlappingQuotient(ptr_t eventPtr) {

1127  
1128 
if (((IEvent*)eventPtr)>getComplexity() == 0) { 
1129 
return 0; 
1130 
} 
1131 
double overlapping = getOverlapping(eventPtr);

1132  
1133 
if (maximumOverlapping == 1) { 
1134 
maximumOverlapping = getMaximumOverlapping(); 
1135 
} 
1136  
1137 
return overlapping / maximumOverlapping;

1138 
} 
1139 