Revision 842775ab src/eventlog/sequencechartfacade.cc

View differences:

src/eventlog/sequencechartfacade.cc
17 17
#include <stdio.h>
18 18
#include <algorithm>
19 19
#include <set>
20
#include <list>
21 20
#include <math.h>
22 21
#include "lcgrandom.h"
23 22
#include "ievent.h"
......
35 34
    timelineMode = NONLINEAR;
36 35
    timelineCoordinateSystemVersion = -1;
37 36
    undefineTimelineCoordinateSystem();
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 37
}
54 38

  
55 39
void SequenceChartFacade::synchronize(FileReader::FileChangedState change)
......
117 101
    timelineCoordinateSystemVersion++;
118 102
    timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = -1;
119 103
    timelineCoordinateOriginSimulationTime = simtime_nil;
120
    timelineCoordinateOriginRealTime = 0;
121 104
}
122 105

  
123 106
void SequenceChartFacade::relocateTimelineCoordinateSystem(IEvent *event)
......
126 109
    timelineCoordinateSystemVersion++;
127 110
    timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = event->getEventNumber();
128 111
    timelineCoordinateOriginSimulationTime = event->getSimulationTime();
129
    timelineCoordinateOriginRealTime = event->getEarliestStartTime() / 1000000.0;
130 112
    event->cachedTimelineCoordinate = 0;
131 113
    event->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion;
132 114
}
......
145 127
    return getTimelineCoordinate((IEvent*)ptr);
146 128
}
147 129

  
148
double SequenceChartFacade::IEvent_getTimelineEventEndCoordinate(ptr_t ptr)
149
{
150
    IEVENT_PTR(ptr);
151
    return getTimelineEventEndCoordinate((IEvent*)ptr);
152
}
153

  
154 130
double SequenceChartFacade::getTimelineCoordinateDelta(double simulationTimeDelta)
155 131
{
156 132
    Assert(getNonLinearFocus() > 0);
......
167 143
    return getTimelineCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);
168 144
}
169 145

  
170
double SequenceChartFacade::getTimelineEventEndCoordinate(ptr_t ptr, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit)
171
{
172
    IEVENT_PTR(ptr);
173
    return getTimelineEventEndCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);
174
}
175

  
176 146
double SequenceChartFacade::getTimelineCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit)
177 147
{
178 148
    Assert(event);
......
184 154
        double timelineCoordinate;
185 155

  
186 156
        switch (timelineMode) {
187
            case REAL_TIME:
188
                timelineCoordinate = ((event->getEarliestStartTime()/1000000.0 - timelineCoordinateOriginRealTime));
189
                break;
190 157
            case SIMULATION_TIME:
191 158
                timelineCoordinate = (event->getSimulationTime() - timelineCoordinateOriginSimulationTime).dbl();
192 159
                break;
......
253 220
    return event->cachedTimelineCoordinate;
254 221
}
255 222

  
256
double SequenceChartFacade::getTimelineEventEndCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit)
257
{
258
    Assert(event);
259
    Assert(event->getEventLog() == eventLog);
260
    if(!eventLog->isLegacyTrace()) {
261
        return getTimelineCoordinate(event);
262
    }
263
        double timelineEventEndCoordinate;
264
        switch (timelineMode) {
265
            case REAL_TIME:
266
                timelineEventEndCoordinate = (event->getEarliestProcessingTime()/ 1000000.0 - timelineCoordinateOriginRealTime) ;
267
                break;
268
            case SIMULATION_TIME:
269
                timelineEventEndCoordinate = (event->getSimulationTime()+event->getEventEntry()->duration - timelineCoordinateOriginSimulationTime).dbl();
270
                break;
271
            default:
272
                return getTimelineCoordinate(event);
273
        }
274
    return timelineEventEndCoordinate;
275
}
276

  
277 223
double SequenceChartFacade::getCachedTimelineCoordinate(IEvent *event)
278 224
{
279 225
    Assert(event);
......
326 272
        return NULL;
327 273

  
328 274
    switch (timelineMode) {
329
        case REAL_TIME:
330
        {
331
            IEvent* res = eventLog->getFirstEventRealTime();
332
            for (IEvent *current = eventLog->getFirstEventRealTime(); current; current = current->getNextEventRealTime()) {
333
                if ((double) current->getEarliestProcessingTime() / 1000000.0 < timelineCoordinate + timelineCoordinateOriginRealTime) {
334
                    if (current->getEarliestProcessingTime() > res->getEarliestProcessingTime()) {
335
                        res = current;
336
                    }
337
                } else {
338
                    break;
339
                }
340
            }
341
            return res;
342
        }
343 275
        case SIMULATION_TIME:
344 276
            return eventLog->getLastEventNotAfterSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
345 277
        case EVENT_NUMBER:
......
372 304
        return NULL;
373 305

  
374 306
    switch (timelineMode) {
375
        case REAL_TIME:
376
        {
377
            IEvent* res = eventLog->getLastEventRealTime();
378
            for (IEvent *current = eventLog->getLastEventRealTime(); current; current = current->getPreviousEventRealTime()) {
379
                if ((double) current->getEarliestStartTime() / 1000000.0 > timelineCoordinate + timelineCoordinateOriginRealTime) {
380
                    if (current->getEarliestStartTime() < res->getEarliestStartTime()) {
381
                        res = current;
382
                    }
383
                } else {
384
                    break;
385
                }
386
            }
387
            return res;
388
        }
389 307
        case SIMULATION_TIME:
390 308
            return eventLog->getFirstEventNotBeforeSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
391 309
        case EVENT_NUMBER:
......
420 338
{
421 339
    // if before the first event
422 340
    if (event) {
423
        if (timelineMode==REAL_TIME) {
424
            eventSimulationTime = event->getEarliestStartTime() / 1000000.0;
425
        } else {
426
            eventSimulationTime = event->getSimulationTime();
427
        }
341
        eventSimulationTime = event->getSimulationTime();
428 342
        eventTimelineCoordinate = getTimelineCoordinate(event);
429 343
    }
430 344
    else {
......
434 348

  
435 349
        if (timelineMode == EVENT_NUMBER)
436 350
            eventTimelineCoordinate -= 1;
437
        else if (timelineMode == REAL_TIME)
438
            eventTimelineCoordinate -= getTimelineCoordinateDelta(0);
439 351
        else
440 352
            eventTimelineCoordinate -= getTimelineCoordinateDelta(firstEvent->getSimulationTime().dbl());
441 353
    }
442 354

  
443 355
    // linear approximation between two enclosing events
444
    if(timelineMode==REAL_TIME) {
445
        nextEvent = event ? event->getNextEventRealTime() : eventLog->getFirstEventRealTime();
446
    } else {
447
        nextEvent = event ? event->getNextEvent() : eventLog->getFirstEvent();
448
    }
356
    nextEvent = event ? event->getNextEvent() : eventLog->getFirstEvent();
449 357

  
450 358
    if (nextEvent) {
451
        if(timelineMode==REAL_TIME) {
452
            nextEventSimulationTime = nextEvent->getEarliestStartTime() / 1000000.0;
453
        } else {
454
            nextEventSimulationTime = nextEvent->getSimulationTime();
455
        }
456

  
359
        nextEventSimulationTime = nextEvent->getSimulationTime();
457 360
        nextEventTimelineCoordinate = getTimelineCoordinate(nextEvent);
458 361

  
459 362
        simulationTimeDelta = nextEventSimulationTime - eventSimulationTime;
......
472 375

  
473 376
    switch (timelineMode)
474 377
    {
475
        case REAL_TIME:
476
        {
477
            simulationTime = max(BigDecimal::Zero, min(biggestEarliestProcessingTime, (timelineCoordinate + timelineCoordinateOriginRealTime)));
478
        }
479
        break;
480 378
        case SIMULATION_TIME:
481 379
            {
482
                IEvent* largestEvent = (IEvent*) getLargestEndtimeInEventRange((ptr_t)(eventLog->getFirstEvent()),(ptr_t)(eventLog->getLastEvent()), upperLimit);
483
                simtime_t lastEventSimulationTime= largestEvent->getSimulationTime() + largestEvent->getEventEntry()->duration;
380
                simtime_t lastEventSimulationTime = eventLog->getLastEvent()->getSimulationTime();
484 381
                simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, timelineCoordinate + timelineCoordinateOriginSimulationTime));
485 382
            }
486 383
            break;
......
522 419

  
523 420
    Assert(!simulationTime.isNaN());
524 421
    Assert(simulationTime >= BigDecimal::Zero);
525
    /*if (timelineMode != REAL_TIME)
526
        Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
527
    */
422
    Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
423

  
528 424
    return simulationTime;
529 425
}
530 426

  
......
536 432
        return 0;
537 433

  
538 434
    Assert(simulationTime >= BigDecimal::Zero);
539
    /*if (timelineMode != REAL_TIME)
540
        Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
541
    */
435
    Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
542 436

  
543 437
    double timelineCoordinate;
544 438

  
545 439
    switch (timelineMode)
546 440
    {
547
        case REAL_TIME:
548
            //treat simulationTime as real time:
549
            timelineCoordinate = simulationTime.dbl() - timelineCoordinateOriginRealTime;
550
            break;
551 441
        case SIMULATION_TIME:
552 442
            timelineCoordinate = (simulationTime - timelineCoordinateOriginSimulationTime).dbl();
553 443
            break;
......
614 504
    Assert(endEvent);
615 505
    std::vector<ptr_t> *moduleMethodBeginEntries = new std::vector<ptr_t>();
616 506

  
617
    for (IEvent *event = startEvent; event; event = timelineMode==REAL_TIME ? event->getNextEventRealTime() : event->getNextEvent()) {
507
    for (IEvent *event = startEvent;; event = event->getNextEvent()) {
618 508
        eventLog->progress();
619 509

  
620 510
        for (int i = 0; i < event->getNumEventLogEntries(); i++) {
......
639 529
    Assert(endEvent);
640 530
    std::set<ptr_t> messageDependencies;
641 531
    eventnumber_t startEventNumber = startEvent->getEventNumber();
532

  
642 533
    // TODO: LONG RUNNING OPERATION
643 534
    // this might take a while if start and end events are far away from each other
644 535
    // if not completed then some dependencies will not be included
645
    for (IEvent *event = startEvent; event; event = timelineMode==REAL_TIME ? event->getNextEventRealTime() : event->getNextEvent()) {
536
    for (IEvent *event = startEvent;; event = event->getNextEvent()) {
646 537
        eventLog->progress();
647 538
        IMessageDependencyList *causes = event->getCauses();
539

  
648 540
        for (IMessageDependencyList::iterator it = causes->begin(); it != causes->end(); it++) {
649 541
            IMessageDependency *messageDependency = *it;
542

  
650 543
            if (messageDependency->getCauseEventNumber() < startEventNumber)
651 544
                messageDependencies.insert((ptr_t)messageDependency);
652 545
        }
546

  
653 547
        IMessageDependencyList *consequences = event->getConsequences();
548

  
654 549
        for (IMessageDependencyList::iterator it = consequences->begin(); it != consequences->end(); it++)
655 550
            messageDependencies.insert((ptr_t)*it);
551

  
656 552
        if (event == endEvent)
657 553
            break;
658 554
    }
555

  
659 556
    std::vector<ptr_t> *result = new std::vector<ptr_t>;
660 557
    result->resize(messageDependencies.size());
661 558
    std::copy(messageDependencies.begin(), messageDependencies.end(), result->begin());
559

  
662 560
    return result;
663 561
}
664 562

  
......
726 624

  
727 625
    return adjacencyMatrix;
728 626
}
729

  
730

  
731
long SequenceChartFacade::getSmallestEventComplexity() {
732
    long complexity = 0;
733
    if (smallestComplexity < 0) {
734
        for (IEvent *event = eventLog->getFirstEvent();event != eventLog->getLastEvent(); event = event->getNextEvent()) {
735
             if (event->getEventEndEntry()) {
736
                 complexity = event->getEventEndEntry()->complexity;
737
             } else {
738
                 continue;
739
             }
740
             if (complexity < smallestComplexity || smallestComplexity < 0) {
741
                 smallestComplexity = complexity;
742
             }
743
             if (complexity > largestComplexity || largestComplexity < 0) {
744
                 largestComplexity = complexity;
745
             }
746
        }
747
    }
748
    if (smallestComplexity < 0) {
749
        smallestComplexity = 0;
750
    }
751
    return smallestComplexity;
752
}
753

  
754
long SequenceChartFacade::getLargestEventComplexity() {
755
    if (largestComplexity < 0) {
756
        getSmallestEventComplexity();
757
    }
758
    if (largestComplexity < 0) {
759
        largestComplexity = 0;
760
    }
761
    return largestComplexity;
762
}
763

  
764
simtime_t SequenceChartFacade::getSmallestEventDuration() {
765
    simtime_t duration = 0;
766
    if (smallestDuration < 0) {
767
        for (IEvent *event = eventLog->getFirstEvent();event != eventLog->getLastEvent(); event = event->getNextEvent()) {
768
             if (event->getEventEntry()) {
769
                 duration = event->getEventEntry()->duration;
770
             } else {
771
                 continue;
772
             }
773
             if (duration < smallestDuration || smallestDuration < 0) {
774
                 smallestDuration = duration;
775
             }
776
             if (duration > largestDuration || largestDuration < 0) {
777
                 largestDuration = duration;
778
             }
779
        }
780
    }
781
    if (smallestDuration < 0) {
782
        smallestDuration = 0;
783
    }
784
    return smallestDuration;
785
}
786

  
787
simtime_t SequenceChartFacade::getLargestEventDuration() {
788
    if (largestDuration < 0) {
789
        getSmallestEventComplexity();
790
    }
791
    if (largestDuration < 0) {
792
        largestDuration = 0;
793
    }
794
    return largestDuration;
795
}
796

  
797

  
798
IEvent* SequenceChartFacade::getPreviousBottleneck(IEvent* e, double threshold) {
799
    IEvent* next = e->getPreviousEventRealTime();
800
    while (next) {
801
        if (isBottleneck(next,threshold)) {
802
            return next;
803
        }
804
        next = next->getPreviousEventRealTime();
805
    }
806
    return e;
807
}
808

  
809
IEvent* SequenceChartFacade::getNextBottleneck(IEvent* e, double threshold) {
810
    IEvent* next = e->getNextEventRealTime();
811
    while (next) {
812
        if (isBottleneck(next,threshold)) {
813
            return next;
814
        }
815
        next = next->getNextEventRealTime();
816
    }
817
    return e;
818
}
819

  
820
/*
821
 * Returns whether an event not part of a set of parallel events with more than treshold elements.
822
 */
823
bool SequenceChartFacade::isBottleneck(IEvent* event, double threshold)
824
{
825
    if (isOnCriticalPath(event)) {
826
        return getOverlappingQuotient((ptr_t)event) <= threshold;
827
    }
828
    return false;
829
}
830
/*
831
 * Returns whether event is in the largest parallel set of selected.
832
 */
833
bool SequenceChartFacade::isParallelWithEvent(IEvent* event, IEvent* selected) {
834

  
835
    if (lastSelected != selected) {
836
        getLargestParallelSet(selected, &cachedParallelSet);
837
    }
838
    return cachedParallelSet.find((ptr_t)event) != cachedParallelSet.end();
839
}
840
/*
841
 * Returns the size of the largest set that is parallel with event.
842
 *
843
 * Works by calculating the first parallel set which does not contain event by
844
 * successively going backwards through all events starting from event.
845
 */
846
unsigned int SequenceChartFacade::getLargestParallelSetSize(IEvent* event)
847
{
848
    IEvent* prev = event;
849
    std::set<ptr_t> parallelSet;
850
    parallelSet.clear();
851
    unsigned int previousSize = 0;
852
    while (prev)
853
    {
854
        previousSize = parallelSet.size();
855

  
856
        getParallelSet(prev, &parallelSet);
857

  
858
        if (parallelSet.find((ptr_t) event) == parallelSet.end())
859
        {
860
            //The current set does not contain event.
861
            //Therefore the previous set was the largest Parallel Set.
862
            break;
863
        }
864
        prev = prev->getPreviousEvent();
865
    }
866
    return previousSize;
867
}
868
/*
869
 * Returns the largest set that is parallel with event.
870
 *
871
 * Works by calculating the first parallel set which does not contain event by
872
 * successively going backwards through all events starting from event.
873
 */
874
std::set<ptr_t>* SequenceChartFacade::getLargestParallelSet(IEvent* event, std::set<ptr_t>* parallelSet) {
875
    IEvent* prev = event;
876
    parallelSet->clear();
877
    while (prev)
878
    {
879
        getParallelSet(prev, parallelSet);
880
        if (parallelSet->find((ptr_t) event) == parallelSet->end())
881
        {
882
            //The current set does not contain event.
883
            //Therefore the previous set was the largest Parallel Set.
884
            break;
885
        }
886
        prev = prev->getPreviousEvent();
887
    }
888
    if (prev != event) {
889
        getParallelSet(prev->getNextEvent(), parallelSet);
890
    }
891
    return parallelSet;
892
}
893

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

  
953
/*
954
 * Determines whether the event lies on the critical path
955
 */
956
bool SequenceChartFacade::isOnCriticalPath(IEvent* event) {
957
    if (cachedCriticalPath.empty()) {
958
        calculateCriticalPath();
959
    }
960
    return (cachedCriticalPath.find((ptr_t)event) != cachedCriticalPath.end());
961
}
962

  
963
/*
964
 * Calculates the critical path of the run and stores it in the set cachedCriticalPath
965
 * Caches the earliestStartTimes of all events
966
 */
967
void SequenceChartFacade::calculateCriticalPath() {
968
    long maxEarliestProcessingTime = 0;
969
    IEvent* maxEarliestProcessingTimeEvent;
970
    for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
971
        simtime_t startTime = current->getSimulationTime();
972
        int moduleId = current->getModuleId();
973
        if(current->getEventEndEntry()) {
974
            current->_earliestProcessingTime = current->getComplexity();
975
        }
976
        current->setCriticalPredecessor(eventLog->getFirstEvent());
977
        for (IEvent *antecessor = eventLog->getFirstEvent(); antecessor; antecessor = antecessor->getNextEvent()) {
978
            if(antecessor==current) {
979
                break; //We have to consider earlier events only
980
            }
981
            if(antecessor->getModuleId() != moduleId && current->getCauseEvent() != antecessor) {
982
                continue; // Check if this is an antecessor
983
            }
984
            if(antecessor->_earliestProcessingTime+current->getComplexity() > current->_earliestProcessingTime) {
985
                current->_earliestProcessingTime = antecessor->_earliestProcessingTime+current->getComplexity();
986
                current->setCriticalPredecessor(antecessor);
987
            }
988
        }
989
        // Memorize max event
990
        if (maxEarliestProcessingTime < current->_earliestProcessingTime) {
991
            maxEarliestProcessingTime = current->_earliestProcessingTime;
992
            maxEarliestProcessingTimeEvent = current;
993
        }
994
    }
995
    //Cache an additional event ordering sorted by their earliestStartingTimes
996
    cacheRealTimeEventOrder();
997

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

  
1030
        long largest = 0;
1031
        IEvent* largestEvent = startEvent;
1032

  
1033
        for (IEvent* current = startEvent; current; current
1034
                = current->getNextEventRealTime())
1035
        {
1036
            long temp = current->getEarliestProcessingTime();
1037
            if (temp > largest)
1038
            {
1039
                largest = temp;
1040
                largestEvent = current;
1041
            }
1042
            if (current == endEvent)
1043
            {
1044
                break;
1045
            }
1046
        }
1047
        return (ptr_t) largestEvent;
1048
    }
1049
    case SIMULATION_TIME:
1050
    case EVENT_NUMBER:
1051
    case STEP:
1052
    case NONLINEAR:
1053
    default:
1054
    {
1055
        if (!duration) {
1056
            return endEventPtr;
1057
        }
1058
        //Use cached result when range contains all events
1059
        if (startEvent == eventLog->getFirstEvent() && endEvent
1060
                == eventLog->getLastEvent() && biggestEndTimeEvent != NULL)
1061
        {
1062
            return (ptr_t) biggestEndTimeEvent;
1063
        }
1064
        simtime_t largest = 0;
1065
        IEvent* largestEvent = endEvent;
1066

  
1067
        for (IEvent* current = endEvent; current; current
1068
                = current->getPreviousEvent())
1069
        {
1070
            simtime_t temp = current->getSimulationTime()
1071
                    + current->getEventEntry()->duration;
1072
            if (temp > largest)
1073
            {
1074
                largest = temp;
1075
                largestEvent = current;
1076
            }
1077
            if (current == startEvent)
1078
            {
1079
                break;
1080
            }
1081
        }
1082
        if (startEvent == eventLog->getFirstEvent() && endEvent
1083
                == eventLog->getLastEvent())
1084
        {
1085
            biggestEndTimeEvent = largestEvent;
1086
        }
1087

  
1088
        return (ptr_t) largestEvent;
1089
    }
1090
    }
1091

  
1092
}
1093

  
1094
double SequenceChartFacade::getOverlapping(ptr_t eventPtr) {
1095
    long overlapping = 0;
1096
    IEvent* event = (IEvent*) eventPtr;
1097

  
1098
    long eventProcessingTime = event->getEarliestProcessingTime();
1099
    long eventStartTime = event->getEarliestStartTime();
1100

  
1101
    for (IEvent *current = eventLog->getFirstEventRealTime(); current; current = current->getNextEventRealTime()) {
1102

  
1103
        if(current->getComplexity() == 0) {
1104
            continue;
1105
        }
1106

  
1107
        long currentStartTime = current->getEarliestStartTime();
1108
        long currentProcessingTime = current->getEarliestProcessingTime();
1109

  
1110
        if(eventStartTime <= currentStartTime && eventProcessingTime >= currentStartTime) {
1111
            overlapping += eventProcessingTime - currentStartTime;
1112
        } else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventStartTime) {
1113
            overlapping += currentProcessingTime - eventStartTime;
1114
        } else if (currentStartTime <= eventStartTime && currentProcessingTime >= eventProcessingTime) {
1115
            overlapping += event->getComplexity();
1116
        }
1117

  
1118
        if (current->getEarliestStartTime() > eventProcessingTime) {
1119
            break;
1120
        }
1121
    }
1122
    return overlapping / (event->getComplexity() * 1.0);
1123
}
1124

  
1125
double SequenceChartFacade::getMaximumOverlapping() {
1126
    double maxOverlapping = 0;
1127
    for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
1128
        if(!isOnCriticalPath(current) || current->getComplexity() == 0) {
1129
            continue;
1130
        }
1131
        double overlapping = getOverlapping((ptr_t) current);
1132
        if (overlapping > maxOverlapping){
1133
            maxOverlapping = overlapping;
1134
        }
1135
    }
1136
    return maxOverlapping;
1137
}
1138

  
1139
/*
1140
 * returns the quotient of
1141
 * relative overlapping cputime with the event / maximum relative overlapping
1142
 * cputime with any event of the critical path
1143
 */
1144
double SequenceChartFacade::getOverlappingQuotient(ptr_t eventPtr) {
1145

  
1146
    if (((IEvent*)eventPtr)->getComplexity() == 0) {
1147
        return 0;
1148
    }
1149
    double overlapping = getOverlapping(eventPtr);
1150

  
1151
    if (maximumOverlapping == -1) {
1152
        maximumOverlapping = getMaximumOverlapping();
1153
    }
1154

  
1155
    return overlapping / maximumOverlapping;
1156
}
1157

  
1158
bool SequenceChartFacade::isOverlappingInRealTimeDomain(ptr_t eventPtr1, ptr_t eventPtr2) {
1159
    long eventProcessingTime1 = ((IEvent*)eventPtr1)->getEarliestProcessingTime();
1160
    long eventStartTime1 = ((IEvent*)eventPtr1)->getEarliestStartTime();
1161
    long eventProcessingTime2 = ((IEvent*)eventPtr2)->getEarliestProcessingTime();
1162
    long eventStartTime2 = ((IEvent*)eventPtr2)->getEarliestStartTime();
1163

  
1164
    return !(eventProcessingTime1 < eventStartTime2 || eventProcessingTime2 < eventStartTime1);
1165
}
1166

  
1167

  
1168
bool compare_events_realtime (IEvent* a, IEvent* b)
1169
{
1170
  return (a->getEarliestStartTime() < b->getEarliestStartTime() || (a->getEarliestStartTime() == b->getEarliestStartTime() && a->getEventNumber() < b->getEventNumber()));
1171
}
1172

  
1173

  
1174
void SequenceChartFacade::cacheRealTimeEventOrder() {
1175
    //First Event is the same in both domains
1176
    eventLog->setFirstEventRealTime((Event*)eventLog->getFirstEvent());
1177
    int i = 0;
1178
    std::list<IEvent*> eventMap;
1179
    for (IEvent *current = eventLog->getFirstEvent(); current; current = current->getNextEvent()) {
1180
        i++;
1181
        eventMap.push_back(current);
1182
    }
1183
    eventMap.sort(compare_events_realtime);
1184

  
1185
    IEvent* current = NULL;
1186
    IEvent* prev = NULL;
1187
    for (std::list<IEvent*>::iterator it = eventMap.begin(); it != eventMap.end(); it++) {
1188
        current = *it;
1189
        if (prev != NULL) {
1190
            prev->setNextEventRealTime(current);
1191
            current->setPreviousEventRealTime(prev);
1192
        }
1193
        prev = current;
1194
    }
1195
    //Set last event in eventlog
1196
    eventLog->setLastEventRealTime((Event*)prev);
1197
    //Test:
1198
    /*
1199
    for (IEvent *current = eventLog->getFirstEventRealTime(); current; current = current->getNextEventRealTime()) {
1200
        printf("event %i, simtime %f, time %i \n",current->getEventNumber(), current->getSimulationTime().dbl(), current->getEarliestStartTime());
1201
    }*/
1202

  
1203

  
1204
}

Also available in: Unified diff