Statistics
| Branch: | Revision:

root / src / eventlog / sequencechartfacade.cc @ 7c7d95e5

History | View | Annotate | Download (44.7 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) 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 <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
            IEvent* res = eventLog->getFirstEventRealTime();
323
            for (IEvent *current = eventLog->getFirstEventRealTime(); current; current = current->getNextEventRealTime()) {
324
                if ((double) current->getEarliestProcessingTime() / 1000000.0 < timelineCoordinate + timelineCoordinateOriginRealTime) {
325
                    if (current->getEarliestProcessingTime() > res->getEarliestProcessingTime()) {
326
                        res = current;
327
                    }
328
                } else {
329
                    break;
330
                }
331
            }
332
            return res;
333
        }
334
        case SIMULATION_TIME:
335
            return eventLog->getLastEventNotAfterSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
336
        case EVENT_NUMBER:
337
            {
338
                eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber;
339

    
340
                if (eventNumber < 0)
341
                    return NULL;
342
                else
343
                    return eventLog->getLastEventNotAfterEventNumber(eventNumber);
344
            }
345
        case STEP:
346
        case NONLINEAR:
347
            {
348
                bool forward;
349
                IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward);
350
                currentEvent = forward ? (currentEvent ? currentEvent->getPreviousEvent() : eventLog->getLastEvent()) : currentEvent;
351

    
352
                Assert(!currentEvent || getTimelineCoordinate(currentEvent) <= timelineCoordinate);
353
                return currentEvent;
354
            }
355
        default:
356
            throw opp_runtime_error("Unknown timeline mode");
357
    }
358
}
359

    
360
IEvent *SequenceChartFacade::getFirstEventNotBeforeTimelineCoordinate(double timelineCoordinate)
361
{
362
    if (eventLog->isEmpty())
363
        return NULL;
364

    
365
    switch (timelineMode) {
366
        case REAL_TIME:
367
        {
368
            IEvent* res = eventLog->getLastEventRealTime();
369
            for (IEvent *current = eventLog->getLastEventRealTime(); current; current = current->getPreviousEventRealTime()) {
370
                if ((double) current->getEarliestStartTime() / 1000000.0 > timelineCoordinate + timelineCoordinateOriginRealTime) {
371
                    if (current->getEarliestStartTime() < res->getEarliestStartTime()) {
372
                        res = current;
373
                    }
374
                } else {
375
                    break;
376
                }
377
            }
378
            return res;
379
        }
380
        case SIMULATION_TIME:
381
            return eventLog->getFirstEventNotBeforeSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
382
        case EVENT_NUMBER:
383
            {
384
                eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber;
385

    
386
                if (eventNumber < 0)
387
                    return eventLog->getFirstEvent();
388
                else
389
                    return eventLog->getFirstEventNotBeforeEventNumber(eventNumber);
390
            }
391
        case STEP:
392
        case NONLINEAR:
393
            {
394
                bool forward;
395
                IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward);
396
                currentEvent = forward ? currentEvent : (currentEvent ? currentEvent->getNextEvent() : eventLog->getFirstEvent());
397

    
398
                Assert(!currentEvent || getTimelineCoordinate(currentEvent) >= timelineCoordinate);
399
                return currentEvent;
400
            }
401
        default:
402
            throw opp_runtime_error("Unknown timeline mode");
403
    }
404
}
405

    
406
void SequenceChartFacade::extractSimulationTimesAndTimelineCoordinates(
407
    IEvent *event, IEvent *&nextEvent,
408
    simtime_t &eventSimulationTime, double &eventTimelineCoordinate,
409
    simtime_t &nextEventSimulationTime, double &nextEventTimelineCoordinate,
410
    simtime_t &simulationTimeDelta, double &timelineCoordinateDelta)
411
{
412
    // if before the first event
413
    if (event) {
414
        if (timelineMode==REAL_TIME) {
415
            eventSimulationTime = event->getEarliestStartTime() / 1000000.0;
416
        } else {
417
            eventSimulationTime = event->getSimulationTime();
418
        }
419
        eventTimelineCoordinate = getTimelineCoordinate(event);
420
    }
421
    else {
422
        eventSimulationTime = BigDecimal::Zero;
423
        IEvent *firstEvent = eventLog->getFirstEvent();
424
        eventTimelineCoordinate = getTimelineCoordinate(firstEvent);
425

    
426
        if (timelineMode == EVENT_NUMBER)
427
            eventTimelineCoordinate -= 1;
428
        else if (timelineMode == REAL_TIME)
429
            eventTimelineCoordinate -= getTimelineCoordinateDelta(0);
430
        else
431
            eventTimelineCoordinate -= getTimelineCoordinateDelta(firstEvent->getSimulationTime().dbl());
432
    }
433

    
434
    // linear approximation between two enclosing events
435
    if(timelineMode==REAL_TIME) {
436
        nextEvent = event ? event->getNextEventRealTime() : eventLog->getFirstEventRealTime();
437
    } else {
438
        nextEvent = event ? event->getNextEvent() : eventLog->getFirstEvent();
439
    }
440

    
441
    if (nextEvent) {
442
        if(timelineMode==REAL_TIME) {
443
            nextEventSimulationTime = nextEvent->getEarliestStartTime() / 1000000.0;
444
        } else {
445
            nextEventSimulationTime = nextEvent->getSimulationTime();
446
        }
447

    
448
        nextEventTimelineCoordinate = getTimelineCoordinate(nextEvent);
449

    
450
        simulationTimeDelta = nextEventSimulationTime - eventSimulationTime;
451
        timelineCoordinateDelta = nextEventTimelineCoordinate - eventTimelineCoordinate;
452
    }
453
}
454

    
455
simtime_t SequenceChartFacade::getSimulationTimeForTimelineCoordinate(double timelineCoordinate, bool upperLimit)
456
{
457
    Assert(!isNaN(timelineCoordinate));
458

    
459
    if (eventLog->isEmpty())
460
        return BigDecimal::Zero;
461

    
462
    simtime_t simulationTime;
463

    
464
    switch (timelineMode)
465
    {
466
        case REAL_TIME:
467
        {
468
            simulationTime = max(BigDecimal::Zero, min(biggestEarliestProcessingTime, (timelineCoordinate + timelineCoordinateOriginRealTime)));
469
        }
470
        break;
471
        case SIMULATION_TIME:
472
            {
473
                IEvent* largestEvent = (IEvent*) getLargestEndtimeInEventRange((ptr_t)(eventLog->getFirstEvent()),(ptr_t)(eventLog->getLastEvent()), upperLimit);
474
                simtime_t lastEventSimulationTime= largestEvent->getSimulationTime() + largestEvent->getEventEntry()->duration;
475
                simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, timelineCoordinate + timelineCoordinateOriginSimulationTime));
476
            }
477
            break;
478
        case EVENT_NUMBER:
479
        case STEP:
480
        case NONLINEAR:
481
            {
482
                IEvent *nextEvent;
483
                simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta;
484
                double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;
485

    
486
                IEvent *event = getLastEventNotAfterTimelineCoordinate(timelineCoordinate);
487
                extractSimulationTimesAndTimelineCoordinates(event, nextEvent,
488
                                                             eventSimulationTime, eventTimelineCoordinate,
489
                                                             nextEventSimulationTime, nextEventTimelineCoordinate,
490
                                                             simulationTimeDelta, timelineCoordinateDelta);
491

    
492
                if (nextEvent) {
493
                    if (timelineCoordinateDelta == 0) {
494
                        // IMPORTANT NOTE: this is just an approximation
495
                        if (upperLimit)
496
                            simulationTime = nextEventSimulationTime;
497
                        else
498
                            simulationTime = eventSimulationTime;
499
                    }
500
                    else {
501
                        timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate));
502
                        simulationTime = eventSimulationTime + simulationTimeDelta * (timelineCoordinate - eventTimelineCoordinate) / timelineCoordinateDelta;
503
                        simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime));
504
                    }
505
                }
506
                else
507
                    simulationTime = eventSimulationTime;
508
            }
509
            break;
510
        default:
511
            throw opp_runtime_error("Unknown timeline mode");
512
    }
513

    
514
    Assert(!simulationTime.isNaN());
515
    Assert(simulationTime >= BigDecimal::Zero);
516
    /*if (timelineMode != REAL_TIME)
517
        Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
518
    */
519
    return simulationTime;
520
}
521

    
522
double SequenceChartFacade::getTimelineCoordinateForSimulationTime(simtime_t simulationTime, bool upperLimit)
523
{
524
    Assert(!simulationTime.isNaN());
525

    
526
    if (eventLog->isEmpty())
527
        return 0;
528

    
529
    Assert(simulationTime >= BigDecimal::Zero);
530
    /*if (timelineMode != REAL_TIME)
531
        Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
532
    */
533

    
534
    double timelineCoordinate;
535

    
536
    switch (timelineMode)
537
    {
538
        case REAL_TIME:
539
            //treat simulationTime as real time:
540
            timelineCoordinate = simulationTime.dbl() - timelineCoordinateOriginRealTime;
541
            break;
542
        case SIMULATION_TIME:
543
            timelineCoordinate = (simulationTime - timelineCoordinateOriginSimulationTime).dbl();
544
            break;
545
        case EVENT_NUMBER:
546
        case STEP:
547
        case NONLINEAR:
548
            {
549
                IEvent *nextEvent;
550
                simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta;
551
                double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;
552

    
553
                IEvent *event = eventLog->getLastEventNotAfterSimulationTime(simulationTime);
554
                extractSimulationTimesAndTimelineCoordinates(event, nextEvent,
555
                                                             eventSimulationTime, eventTimelineCoordinate,
556
                                                             nextEventSimulationTime, nextEventTimelineCoordinate,
557
                                                             simulationTimeDelta, timelineCoordinateDelta);
558

    
559
                if (nextEvent) {
560
                    if (simulationTimeDelta == BigDecimal::Zero) {
561
                        // IMPORTANT NOTE: this is just an approximation
562
                        if (upperLimit)
563
                            timelineCoordinate = nextEventTimelineCoordinate;
564
                        else
565
                            timelineCoordinate = eventTimelineCoordinate;
566
                    }
567
                    else {
568
                        simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime));
569
                        timelineCoordinate = eventTimelineCoordinate + timelineCoordinateDelta * (simulationTime - eventSimulationTime).dbl() / simulationTimeDelta.dbl();
570
                        timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate));
571
                    }
572
                }
573
                else
574
                    timelineCoordinate = eventTimelineCoordinate;
575
            }
576
            break;
577
        default:
578
            throw opp_runtime_error("Unknown timeline mode");
579
    }
580

    
581
    Assert(!isNaN(timelineCoordinate));
582

    
583
    return timelineCoordinate;
584
}
585

    
586
double SequenceChartFacade::getTimelineCoordinateForSimulationTimeAndEventInModule(simtime_t simulationTime, int moduleId)
587
{
588
    IEvent *event = eventLog->getLastEventNotAfterSimulationTime(simulationTime);
589

    
590
    while (event && event->getSimulationTime() == simulationTime) {
591
        if (event->getModuleId() == moduleId)
592
            return getTimelineCoordinate(event);
593

    
594
        event = event->getNextEvent();
595
    }
596

    
597
    return getTimelineCoordinateForSimulationTime(simulationTime);
598
}
599

    
600
std::vector<ptr_t> *SequenceChartFacade::getModuleMethodBeginEntries(ptr_t startEventPtr, ptr_t endEventPtr)
601
{
602
    IEvent *startEvent = (IEvent *)startEventPtr;
603
    IEvent *endEvent = (IEvent *)endEventPtr;
604
    Assert(startEvent);
605
    Assert(endEvent);
606
    std::vector<ptr_t> *moduleMethodBeginEntries = new std::vector<ptr_t>();
607

    
608
    for (IEvent *event = startEvent; event; event = timelineMode==REAL_TIME ? event->getNextEventRealTime() : event->getNextEvent()) {
609
        eventLog->progress();
610

    
611
        for (int i = 0; i < event->getNumEventLogEntries(); i++) {
612
            EventLogEntry *eventLogEntry = event->getEventLogEntry(i);
613

    
614
            if (dynamic_cast<ModuleMethodBeginEntry *>(eventLogEntry))
615
                moduleMethodBeginEntries->push_back((ptr_t)eventLogEntry);
616
        }
617

    
618
        if (event == endEvent)
619
            break;
620
    }
621

    
622
    return moduleMethodBeginEntries;
623
}
624

    
625
std::vector<ptr_t> *SequenceChartFacade::getIntersectingMessageDependencies(ptr_t startEventPtr, ptr_t endEventPtr)
626
{
627
    IEvent *startEvent = (IEvent *)startEventPtr;
628
    IEvent *endEvent = (IEvent *)endEventPtr;
629
    Assert(startEvent);
630
    Assert(endEvent);
631
    std::set<ptr_t> messageDependencies;
632
    eventnumber_t startEventNumber = startEvent->getEventNumber();
633
    // TODO: LONG RUNNING OPERATION
634
    // this might take a while if start and end events are far away from each other
635
    // if not completed then some dependencies will not be included
636
    for (IEvent *event = startEvent; event; event = timelineMode==REAL_TIME ? event->getNextEventRealTime() : event->getNextEvent()) {
637
        eventLog->progress();
638
        IMessageDependencyList *causes = event->getCauses();
639
        for (IMessageDependencyList::iterator it = causes->begin(); it != causes->end(); it++) {
640
            IMessageDependency *messageDependency = *it;
641
            if (messageDependency->getCauseEventNumber() < startEventNumber)
642
                messageDependencies.insert((ptr_t)messageDependency);
643
        }
644
        IMessageDependencyList *consequences = event->getConsequences();
645
        for (IMessageDependencyList::iterator it = consequences->begin(); it != consequences->end(); it++)
646
            messageDependencies.insert((ptr_t)*it);
647
        if (event == endEvent)
648
            break;
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
    return result;
654
}
655

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

    
663
    for (std::map<int, int>::iterator it = moduleIdToAxisIndexMap->begin(); it != moduleIdToAxisIndexMap->end(); it++)
664
        axisIndexSet.insert(it->second);
665

    
666
    int numberOfAxes = axisIndexSet.size();
667
    adjacencyMatrix.resize(numberOfAxes * numberOfAxes);
668

    
669
    for (int i = 0; i < numberOfSamples; i++)
670
    {
671
        // draw random
672
        double percentage = lcgRandom.next01();
673
        IEvent *event = eventLog->getApproximateEventAt(percentage);
674
        eventNumberToEventMap[event->getEventNumber()] = event;
675

    
676
        // look before origin
677
        if (timelineCoordinateOriginEventNumber != -1) {
678
            if (timelineCoordinateOriginEventNumber - i >= 0) {
679
                event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber - i);
680
                if (event)
681
                    eventNumberToEventMap[event->getEventNumber()] = event;
682
            }
683

    
684
            // look after origin
685
            event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber + i);
686
            if (event)
687
                eventNumberToEventMap[event->getEventNumber()] = event;
688
        }
689
    }
690

    
691
    for (std::map<eventnumber_t, IEvent *>::iterator it = eventNumberToEventMap.begin(); it != eventNumberToEventMap.end(); it++) {
692
        IEvent *event = it->second;
693
        IMessageDependencyList *causes = event->getCauses();
694

    
695
        for (IMessageDependencyList::iterator it = causes->begin(); it != causes->end(); it++) {
696
            IMessageDependency *messageDependency = *it;
697
            IEvent *causeEvent = messageDependency->getCauseEvent();
698
            IEvent *consequenceEvent = messageDependency->getConsequenceEvent();
699
            int weight = messageDependency->getIsReuse() ? messageReuseWeight : messageSendWeight;
700

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

    
705
                std::map<int, int>::iterator causeModuleIdIt = moduleIdToAxisIndexMap->find(causeModuleId);
706
                std::map<int, int>::iterator consequenceModuleIdIt = moduleIdToAxisIndexMap->find(consequenceModuleId);
707

    
708
                if (causeModuleIdIt !=  moduleIdToAxisIndexMap->end() && consequenceModuleIdIt != moduleIdToAxisIndexMap->end())
709
                    adjacencyMatrix.at(causeModuleIdIt->second * numberOfAxes + consequenceModuleIdIt->second) += weight;
710
            }
711
        }
712
    }
713

    
714
    return adjacencyMatrix;
715
}
716

    
717

    
718
long SequenceChartFacade::getSmallestEventComplexity() {
719
    long complexity = 0;
720
    if (smallestComplexity < 0) {
721
        for (IEvent *event = eventLog->getFirstEvent();event != eventLog->getLastEvent(); event = event->getNextEvent()) {
722
             if (event->getEventEndEntry()) {
723
                 complexity = event->getEventEndEntry()->complexity;
724
             } else {
725
                 continue;
726
             }
727
             if (complexity < smallestComplexity || smallestComplexity < 0) {
728
                 smallestComplexity = complexity;
729
             }
730
             if (complexity > largestComplexity || largestComplexity < 0) {
731
                 largestComplexity = complexity;
732
             }
733
        }
734
    }
735
    if (smallestComplexity < 0) {
736
        smallestComplexity = 0;
737
    }
738
    return smallestComplexity;
739
}
740

    
741
long SequenceChartFacade::getLargestEventComplexity() {
742
    if (largestComplexity < 0) {
743
        getSmallestEventComplexity();
744
    }
745
    if (largestComplexity < 0) {
746
        largestComplexity = 0;
747
    }
748
    return largestComplexity;
749
}
750

    
751
simtime_t SequenceChartFacade::getSmallestEventDuration() {
752
    simtime_t duration = 0;
753
    if (smallestDuration < 0) {
754
        for (IEvent *event = eventLog->getFirstEvent();event != eventLog->getLastEvent(); event = event->getNextEvent()) {
755
             if (event->getEventEntry()) {
756
                 duration = event->getEventEntry()->duration;
757
             } else {
758
                 continue;
759
             }
760
             if (duration < smallestDuration || smallestDuration < 0) {
761
                 smallestDuration = duration;
762
             }
763
             if (duration > largestDuration || largestDuration < 0) {
764
                 largestDuration = duration;
765
             }
766
        }
767
    }
768
    if (smallestDuration < 0) {
769
        smallestDuration = 0;
770
    }
771
    return smallestDuration;
772
}
773

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

    
784

    
785
IEvent* SequenceChartFacade::getPreviousBottleneck(IEvent* e, double threshold) {
786
    IEvent* next = e->getPreviousEventRealTime();
787
    while (next) {
788
        if (isBottleneck(next,threshold)) {
789
            return next;
790
        }
791
        next = next->getPreviousEventRealTime();
792
    }
793
    return e;
794
}
795

    
796
IEvent* SequenceChartFacade::getNextBottleneck(IEvent* e, double threshold) {
797
    IEvent* next = e->getNextEventRealTime();
798
    while (next) {
799
        if (isBottleneck(next,threshold)) {
800
            return next;
801
        }
802
        next = next->getNextEventRealTime();
803
    }
804
    return e;
805
}
806

    
807
/*
808
 * Returns whether an event not part of a set of parallel events with more than treshold elements.
809
 */
810
bool SequenceChartFacade::isBottleneck(IEvent* event, double threshold)
811
{
812
    if (isOnCriticalPath(event)) {
813
        return getOverlappingQuotient((ptr_t)event) <= threshold;
814
    }
815
    return false;
816
}
817
/*
818
 * Returns whether event is in the largest parallel set of selected.
819
 */
820
bool SequenceChartFacade::isParallelWithEvent(IEvent* event, IEvent* selected) {
821

    
822
    if (lastSelected != selected) {
823
        getLargestParallelSet(selected, &cachedParallelSet);
824
    }
825
    return cachedParallelSet.find((ptr_t)event) != cachedParallelSet.end();
826
}
827
/*
828
 * Returns the size of the largest set that is parallel with event.
829
 *
830
 * Works by calculating the first parallel set which does not contain event by
831
 * successively going backwards through all events starting from event.
832
 */
833
unsigned int SequenceChartFacade::getLargestParallelSetSize(IEvent* event)
834
{
835
    IEvent* prev = event;
836
    std::set<ptr_t> parallelSet;
837
    parallelSet.clear();
838
    unsigned int previousSize = 0;
839
    while (prev)
840
    {
841
        previousSize = parallelSet.size();
842

    
843
        getParallelSet(prev, &parallelSet);
844

    
845
        if (parallelSet.find((ptr_t) event) == parallelSet.end())
846
        {
847
            //The current set does not contain event.
848
            //Therefore the previous set was the largest Parallel Set.
849
            break;
850
        }
851
        prev = prev->getPreviousEvent();
852
    }
853
    return previousSize;
854
}
855
/*
856
 * Returns the largest set that is parallel with event.
857
 *
858
 * Works by calculating the first parallel set which does not contain event by
859
 * successively going backwards through all events starting from event.
860
 */
861
std::set<ptr_t>* SequenceChartFacade::getLargestParallelSet(IEvent* event, std::set<ptr_t>* parallelSet) {
862
    IEvent* prev = event;
863
    parallelSet->clear();
864
    while (prev)
865
    {
866
        getParallelSet(prev, parallelSet);
867
        if (parallelSet->find((ptr_t) event) == parallelSet->end())
868
        {
869
            //The current set does not contain event.
870
            //Therefore the previous set was the largest Parallel Set.
871
            break;
872
        }
873
        prev = prev->getPreviousEvent();
874
    }
875
    if (prev != event) {
876
        getParallelSet(prev->getNextEvent(), parallelSet);
877
    }
878
    return parallelSet;
879
}
880

    
881
/*
882
 * Calculates a set of those events that start after event but are still in parallel to event.
883
 * This means that no other event must end before the latest start time in this set.
884
 */
885
void SequenceChartFacade::getParallelSet(IEvent* event,
886
        std::set<ptr_t>* parallelSet)
887
{
888
    IEvent* next = event->getNextEvent();
889
    simtime_t smallestParallelEndtime = getSmallestParallelEndtime(event);
890
    parallelSet->clear();
891
    parallelSet->insert((ptr_t) event);
892
    while (next)
893
    {
894
        if ((next->getSimulationTime() >= event->getSimulationTime())
895
                && (smallestParallelEndtime >= next->getSimulationTime()))
896
        {
897
            if(parallelSet->find((ptr_t)(next->getCauseEvent())) == parallelSet->end()) {
898
                parallelSet->insert((ptr_t) next);
899
            }
900
        }
901
        else
902
        {
903
            break;
904
        }
905
        next = next->getNextEvent();
906
    }
907
}
908
/*
909
 *
910
 */
911
simtime_t SequenceChartFacade::getSmallestParallelEndtime(IEvent* event)
912
{
913
    simtime_t minimum = event->getSimulationTime()
914
            + event->getEventEntry()->duration;
915
    for (IEvent *current = eventLog->getFirstEvent(); current; current
916
            = current->getNextEvent())
917
    {
918
        if (current->getSimulationTime() >= event->getSimulationTime())
919
        {
920
            if ((current->getSimulationTime()
921
                    + current->getEventEntry()->duration)
922
                    > event->getSimulationTime())
923
            {
924
                if (minimum > (current->getSimulationTime()
925
                        + current->getEventEntry()->duration))
926
                {
927
                    minimum = current->getSimulationTime()
928
                            + current->getEventEntry()->duration;
929
                }
930
            }
931
            if (current->getSimulationTime() > minimum)
932
            { // After this, no overlapping can follow
933
                break;
934
            }
935
        }
936
    }
937
    return minimum;
938
}
939

    
940
/*
941
 * Determines whether the event lies on the critical path
942
 */
943
bool SequenceChartFacade::isOnCriticalPath(IEvent* event) {
944
    if (cachedCriticalPath.empty()) {
945
        calculateCriticalPath();
946
    }
947
    return (cachedCriticalPath.find((ptr_t)event) != cachedCriticalPath.end());
948
}
949

    
950
/*
951
 * Calculates the critical path of the run and stores it in the set cachedCriticalPath
952
 * Caches the earliestStartTimes of all events
953
 */
954
void SequenceChartFacade::calculateCriticalPath() {
955
    long maxEarliestProcessingTime = 0;
956
    IEvent* maxEarliestProcessingTimeEvent;
957
    printf("bla1");
958
    for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
959
        simtime_t startTime = current->getSimulationTime();
960
        int moduleId = current->getModuleId();
961
        if(current->getEventEndEntry()) {
962
            current->_earliestProcessingTime = current->getComplexity();
963
        }
964
        current->setCriticalPredecessor(eventLog->getFirstEvent());
965
        for (IEvent *antecessor = eventLog->getFirstEvent(); antecessor; antecessor = antecessor->getNextEvent()) {
966
            if(antecessor==current) {
967
                break; //We have to consider earlier events only
968
            }
969
            if(antecessor->getModuleId() != moduleId && current->getCauseEvent() != antecessor) {
970
                continue; // Check if this is an antecessor
971
            }
972
            if(antecessor->_earliestProcessingTime+current->getComplexity() > current->_earliestProcessingTime) {
973
                current->_earliestProcessingTime = antecessor->_earliestProcessingTime+current->getComplexity();
974
                current->setCriticalPredecessor(antecessor);
975
            }
976
        }
977
        // Memorize max event
978
        if (maxEarliestProcessingTime < current->_earliestProcessingTime) {
979
            maxEarliestProcessingTime = current->_earliestProcessingTime;
980
            maxEarliestProcessingTimeEvent = current;
981
        }
982
    }
983
    //Cache an additional event ordering sorted by their earliestStartingTimes
984
    cacheRealTimeEventOrder();
985

    
986
    //Now produce the convex hull of critical antecessors/predecessors:
987
    cachedCriticalPath.clear();
988
    //Cache largest processing time:
989
    biggestEarliestProcessingTime = maxEarliestProcessingTime / 1000000.0;
990
    biggestEarliestProcessingTimeEvent = maxEarliestProcessingTimeEvent;
991
    for (IEvent *predecessor = maxEarliestProcessingTimeEvent; predecessor ; predecessor = predecessor->getCriticalPredecessor()) {
992
        cachedCriticalPath.insert((ptr_t)predecessor);
993
        if(predecessor->getEventNumber() == 0) {
994
            break;
995
        }
996
    }
997
}
998
/*
999
 * Returns the event with the largest calculated earliest Processing time in REAL_TIME mode
1000
 * or the largest endtime in other modes within the given event range.
1001
 */
1002
ptr_t SequenceChartFacade::getLargestEndtimeInEventRange(ptr_t startEventPtr,
1003
        ptr_t endEventPtr, bool duration)
1004
{
1005
    IEvent *startEvent = (IEvent *) startEventPtr;
1006
    IEvent *endEvent = (IEvent *) endEventPtr;
1007
    switch (timelineMode)
1008
    {
1009
    case REAL_TIME:
1010
    {
1011
        //Use cached result when range contains all events
1012
        if (startEvent == eventLog->getFirstEventRealTime() && endEvent
1013
                == eventLog->getLastEventRealTime())
1014
        {
1015
            return (ptr_t) biggestEarliestProcessingTimeEvent;
1016
        }
1017

    
1018
        long largest = 0;
1019
        IEvent* largestEvent = startEvent;
1020

    
1021
        for (IEvent* current = startEvent; current; current
1022
                = current->getNextEventRealTime())
1023
        {
1024
            long temp = current->getEarliestProcessingTime();
1025
            if (temp > largest)
1026
            {
1027
                largest = temp;
1028
                largestEvent = current;
1029
            }
1030
            if (current == endEvent)
1031
            {
1032
                break;
1033
            }
1034
        }
1035
        return (ptr_t) largestEvent;
1036
    }
1037
    case SIMULATION_TIME:
1038
    case EVENT_NUMBER:
1039
    case STEP:
1040
    case NONLINEAR:
1041
    default:
1042
    {
1043
        if (!duration) {
1044
            return endEventPtr;
1045
        }
1046
        //Use cached result when range contains all events
1047
        if (startEvent == eventLog->getFirstEvent() && endEvent
1048
                == eventLog->getLastEvent() && biggestEndTimeEvent != NULL)
1049
        {
1050
            return (ptr_t) biggestEndTimeEvent;
1051
        }
1052
        simtime_t largest = 0;
1053
        IEvent* largestEvent = endEvent;
1054

    
1055
        for (IEvent* current = endEvent; current; current
1056
                = current->getPreviousEvent())
1057
        {
1058
            simtime_t temp = current->getSimulationTime()
1059
                    + current->getEventEntry()->duration;
1060
            if (temp > largest)
1061
            {
1062
                largest = temp;
1063
                largestEvent = current;
1064
            }
1065
            if (current == startEvent)
1066
            {
1067
                break;
1068
            }
1069
        }
1070
        if (startEvent == eventLog->getFirstEvent() && endEvent
1071
                == eventLog->getLastEvent())
1072
        {
1073
            biggestEndTimeEvent = largestEvent;
1074
        }
1075

    
1076
        return (ptr_t) largestEvent;
1077
    }
1078
    }
1079

    
1080
}
1081

    
1082
double SequenceChartFacade::getOverlapping(ptr_t eventPtr) {
1083
    long overlapping = 0;
1084
    IEvent* event = (IEvent*) eventPtr;
1085

    
1086
    long eventProcessingTime = event->getEarliestProcessingTime();
1087
    long eventStartTime = event->getEarliestStartTime();
1088

    
1089
    for (IEvent *current = eventLog->getFirstEventRealTime(); current; current = current->getNextEventRealTime()) {
1090

    
1091
        if(current->getComplexity() == 0) {
1092
            continue;
1093
        }
1094

    
1095
        long currentStartTime = current->getEarliestStartTime();
1096
        long currentProcessingTime = current->getEarliestProcessingTime();
1097

    
1098
        if(eventStartTime <= currentStartTime && eventProcessingTime >= currentStartTime) {
1099
            overlapping += eventProcessingTime - currentStartTime;
1100
        } else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventStartTime) {
1101
            overlapping += currentProcessingTime - eventStartTime;
1102
        } else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventProcessingTime) {
1103
            overlapping += event->getComplexity();
1104
        }
1105

    
1106
        if (current->getEarliestStartTime() > eventProcessingTime) {
1107
            break;
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() || (a->getEarliestStartTime() == b->getEarliestStartTime() && a->getEventNumber() < b->getEventNumber()));
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
    /*
1187
    for (IEvent *current = eventLog->getFirstEventRealTime(); current; current = current->getNextEventRealTime()) {
1188
        printf("event %i, simtime %f, time %i \n",current->getEventNumber(), current->getSimulationTime().dbl(), current->getEarliestStartTime());
1189
    }*/
1190

    
1191

    
1192
}