Statistics
| Branch: | Revision:

root / src / eventlog / sequencechartfacade.cc @ 842775ab

History | View | Annotate | Download (25 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 <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
    nonLinearFocus = -1;
33
    nonLinearMinimumTimelineCoordinateDelta = 0.1;
34
    timelineMode = NONLINEAR;
35
    timelineCoordinateSystemVersion = -1;
36
    undefineTimelineCoordinateSystem();
37
}
38

    
39
void SequenceChartFacade::synchronize(FileReader::FileChangedState change)
40
{
41
        if (change != FileReader::UNCHANGED) {
42
                EventLogFacade::synchronize(change);
43
                nonLinearFocus = -1;
44
        switch (change) {
45
            case FileReader::UNCHANGED:   // cannot be reached. just to avoid warnings of unhandled enum value
46
                break;
47
            case FileReader::OVERWRITTEN:
48
                            undefineTimelineCoordinateSystem();
49
                break;
50
            case FileReader::APPENDED:
51
                IEvent *event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber, EXACT, true);
52
                if (event)
53
                    relocateTimelineCoordinateSystem(event);
54
                else
55
                                undefineTimelineCoordinateSystem();
56
                break;
57
        }
58
        }
59
}
60

    
61
double SequenceChartFacade::calculateNonLinearFocus()
62
{
63
    if (!eventLog->isEmpty()) {
64
        double lastEventSimulationTime = eventLog->getLastEvent()->getSimulationTime().dbl();
65
        double firstEventSimulationTime = eventLog->getFirstEvent()->getSimulationTime().dbl();
66
        double totalSimulationTimeDelta = lastEventSimulationTime - firstEventSimulationTime;
67

    
68
        if (totalSimulationTimeDelta == 0)
69
            totalSimulationTimeDelta = firstEventSimulationTime;
70

    
71
        if (totalSimulationTimeDelta == 0)
72
            return 1;
73
        else
74
            return totalSimulationTimeDelta / eventLog->getApproximateNumberOfEvents() / 10;
75
    }
76
    else
77
        return 1;
78
}
79

    
80
void SequenceChartFacade::setNonLinearMinimumTimelineCoordinateDelta(double value)
81
{
82
    Assert(value >= 0);
83
    nonLinearMinimumTimelineCoordinateDelta = value;
84
}
85

    
86
void SequenceChartFacade::setNonLinearFocus(double nonLinearFocus)
87
{
88
        Assert(nonLinearFocus >= 0);
89
        this->nonLinearFocus = nonLinearFocus;
90
}
91

    
92
double SequenceChartFacade::getNonLinearFocus()
93
{
94
        if (nonLinearFocus == -1)
95
                nonLinearFocus = calculateNonLinearFocus();
96
        return nonLinearFocus;
97
}
98

    
99
void SequenceChartFacade::undefineTimelineCoordinateSystem()
100
{
101
    timelineCoordinateSystemVersion++;
102
    timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = -1;
103
    timelineCoordinateOriginSimulationTime = simtime_nil;
104
}
105

    
106
void SequenceChartFacade::relocateTimelineCoordinateSystem(IEvent *event)
107
{
108
    Assert(event);
109
    timelineCoordinateSystemVersion++;
110
    timelineCoordinateOriginEventNumber = timelineCoordinateRangeStartEventNumber = timelineCoordinateRangeEndEventNumber = event->getEventNumber();
111
    timelineCoordinateOriginSimulationTime = event->getSimulationTime();
112
    event->cachedTimelineCoordinate = 0;
113
    event->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion;
114
}
115

    
116
void SequenceChartFacade::setTimelineMode(TimelineMode timelineMode)
117
{
118
    this->timelineMode = timelineMode;
119

    
120
    if (timelineCoordinateOriginEventNumber != -1)
121
        relocateTimelineCoordinateSystem(eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber));
122
}
123

    
124
double SequenceChartFacade::IEvent_getTimelineCoordinate(ptr_t ptr)
125
{
126
    IEVENT_PTR(ptr);
127
    return getTimelineCoordinate((IEvent*)ptr);
128
}
129

    
130
double SequenceChartFacade::getTimelineCoordinateDelta(double simulationTimeDelta)
131
{
132
    Assert(getNonLinearFocus() > 0);
133

    
134
    if (timelineMode == STEP)
135
        return 1;
136
    else
137
        return nonLinearMinimumTimelineCoordinateDelta + (1 - nonLinearMinimumTimelineCoordinateDelta) * atan(fabs(simulationTimeDelta) / getNonLinearFocus()) / PI * 2;
138
}
139

    
140
double SequenceChartFacade::getTimelineCoordinate(ptr_t ptr, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit)
141
{
142
    IEVENT_PTR(ptr);
143
    return getTimelineCoordinate((IEvent *)ptr, lowerTimelineCoordinateCalculationLimit, upperTimelineCoordinateCalculationLimit);
144
}
145

    
146
double SequenceChartFacade::getTimelineCoordinate(IEvent *event, double lowerTimelineCoordinateCalculationLimit, double upperTimelineCoordinateCalculationLimit)
147
{
148
    Assert(event);
149
    Assert(event->getEventLog() == eventLog);
150
    Assert(timelineCoordinateSystemVersion != -1);
151
    Assert(timelineCoordinateOriginEventNumber != -1);
152

    
153
    if (this->timelineCoordinateSystemVersion > event->cachedTimelineCoordinateSystemVersion) {
154
        double timelineCoordinate;
155

    
156
        switch (timelineMode) {
157
            case SIMULATION_TIME:
158
                timelineCoordinate = (event->getSimulationTime() - timelineCoordinateOriginSimulationTime).dbl();
159
                break;
160
            case EVENT_NUMBER:
161
                timelineCoordinate = event->getEventNumber() - timelineCoordinateOriginEventNumber;
162
                break;
163
            case STEP:
164
            case NONLINEAR:
165
                {
166
                    IEvent *previousEvent = NULL;
167
                    // do we go forward from end or backward from start of known range
168
                    bool forward = event->getEventNumber() > timelineCoordinateRangeEndEventNumber;
169
                    IEvent *currentEvent = eventLog->getEventForEventNumber(forward ? timelineCoordinateRangeEndEventNumber : timelineCoordinateRangeStartEventNumber);
170

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

    
173
                    // TODO: LONG RUNNING OPERATION
174
                    // does a linear search towards the event to calculate the non linear timeline coordinate
175
                    do {
176
                        eventLog->progress();
177

    
178
                        Assert(currentEvent);
179
                        previousEvent = currentEvent;
180
                        currentEvent = forward ? currentEvent->getNextEvent() : currentEvent->getPreviousEvent();
181
                        Assert(currentEvent);
182

    
183
                        simtime_t previousSimulationTime = previousEvent->getSimulationTime();
184
                        double previousTimelineCoordinate = previousEvent->cachedTimelineCoordinate;
185
                        simtime_t simulationTime = currentEvent->getSimulationTime();
186
                        double timelineCoordinateDelta = getTimelineCoordinateDelta((simulationTime - previousSimulationTime).dbl());
187

    
188
                        if (forward) {
189
                            timelineCoordinate = previousTimelineCoordinate + timelineCoordinateDelta;
190

    
191
                            if (timelineCoordinate > upperTimelineCoordinateCalculationLimit)
192
                                return NaN;
193
                        }
194
                        else {
195
                            timelineCoordinate = previousTimelineCoordinate - timelineCoordinateDelta;
196

    
197
                            if (timelineCoordinate < lowerTimelineCoordinateCalculationLimit)
198
                                return NaN;
199
                        }
200

    
201
                        currentEvent->cachedTimelineCoordinate = timelineCoordinate;
202
                        currentEvent->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion;
203
                    }
204
                    while (currentEvent != event);
205

    
206
                    if (forward)
207
                        timelineCoordinateRangeEndEventNumber = event->getEventNumber();
208
                    else
209
                        timelineCoordinateRangeStartEventNumber = event->getEventNumber();
210
                }
211
                break;
212
            default:
213
                throw opp_runtime_error("Unknown timeline mode");
214
        }
215

    
216
        event->cachedTimelineCoordinate = timelineCoordinate;
217
        event->cachedTimelineCoordinateSystemVersion = timelineCoordinateSystemVersion;
218
    }
219

    
220
    return event->cachedTimelineCoordinate;
221
}
222

    
223
double SequenceChartFacade::getCachedTimelineCoordinate(IEvent *event)
224
{
225
    Assert(event);
226
    Assert(timelineCoordinateSystemVersion != -1);
227
    Assert(timelineCoordinateOriginEventNumber != -1);
228

    
229
    if (this->timelineCoordinateSystemVersion > event->cachedTimelineCoordinateSystemVersion)
230
        return -1;
231
    else
232
        return event->cachedTimelineCoordinate;
233
}
234

    
235
IEvent *SequenceChartFacade::getEventForNonLinearTimelineCoordinate(double timelineCoordinate, bool &forward)
236
{
237
    Assert(timelineCoordinateOriginEventNumber != -1);
238
    IEvent *timelineCoordinateRangeStartEvent = eventLog->getEventForEventNumber(timelineCoordinateRangeStartEventNumber);
239
    IEvent *timelineCoordinateRangeEndEvent = eventLog->getEventForEventNumber(timelineCoordinateRangeEndEventNumber);
240
    IEvent *currentEvent;
241

    
242
    Assert(timelineCoordinateRangeStartEvent && timelineCoordinateRangeEndEvent);
243

    
244
    if (timelineCoordinate <= getTimelineCoordinate(timelineCoordinateRangeStartEvent)) {
245
        forward = false;
246
        currentEvent = timelineCoordinateRangeStartEvent;
247
    }
248
    else if (getTimelineCoordinate(timelineCoordinateRangeEndEvent) <= timelineCoordinate) {
249
        forward = true;
250
        currentEvent = timelineCoordinateRangeEndEvent;
251
    }
252
    else {
253
        forward = true;
254
        currentEvent = timelineCoordinateRangeStartEvent;
255
    }
256

    
257
    // TODO: LONG RUNNING OPERATION
258
    // does a linear search towards requested non linear timeline coordinate
259
    while (currentEvent && (forward ? getTimelineCoordinate(currentEvent) < timelineCoordinate :
260
                                      timelineCoordinate <= getTimelineCoordinate(currentEvent)))
261
    {
262
        eventLog->progress();
263
        currentEvent = forward ? currentEvent->getNextEvent() : currentEvent->getPreviousEvent();
264
    }
265

    
266
    return currentEvent;
267
}
268

    
269
IEvent *SequenceChartFacade::getLastEventNotAfterTimelineCoordinate(double timelineCoordinate)
270
{
271
    if (eventLog->isEmpty())
272
        return NULL;
273

    
274
    switch (timelineMode) {
275
        case SIMULATION_TIME:
276
            return eventLog->getLastEventNotAfterSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
277
        case EVENT_NUMBER:
278
            {
279
                eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber;
280

    
281
                if (eventNumber < 0)
282
                    return NULL;
283
                else
284
                    return eventLog->getLastEventNotAfterEventNumber(eventNumber);
285
            }
286
        case STEP:
287
        case NONLINEAR:
288
            {
289
                bool forward;
290
                IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward);
291
                currentEvent = forward ? (currentEvent ? currentEvent->getPreviousEvent() : eventLog->getLastEvent()) : currentEvent;
292

    
293
                Assert(!currentEvent || getTimelineCoordinate(currentEvent) <= timelineCoordinate);
294
                return currentEvent;
295
            }
296
        default:
297
            throw opp_runtime_error("Unknown timeline mode");
298
    }
299
}
300

    
301
IEvent *SequenceChartFacade::getFirstEventNotBeforeTimelineCoordinate(double timelineCoordinate)
302
{
303
    if (eventLog->isEmpty())
304
        return NULL;
305

    
306
    switch (timelineMode) {
307
        case SIMULATION_TIME:
308
            return eventLog->getFirstEventNotBeforeSimulationTime(getSimulationTimeForTimelineCoordinate(timelineCoordinate));
309
        case EVENT_NUMBER:
310
            {
311
                eventnumber_t eventNumber = (eventnumber_t)floor(timelineCoordinate) + timelineCoordinateOriginEventNumber;
312

    
313
                if (eventNumber < 0)
314
                    return eventLog->getFirstEvent();
315
                else
316
                    return eventLog->getFirstEventNotBeforeEventNumber(eventNumber);
317
            }
318
        case STEP:
319
        case NONLINEAR:
320
            {
321
                bool forward;
322
                IEvent *currentEvent = getEventForNonLinearTimelineCoordinate(timelineCoordinate, forward);
323
                currentEvent = forward ? currentEvent : (currentEvent ? currentEvent->getNextEvent() : eventLog->getFirstEvent());
324

    
325
                Assert(!currentEvent || getTimelineCoordinate(currentEvent) >= timelineCoordinate);
326
                return currentEvent;
327
            }
328
        default:
329
            throw opp_runtime_error("Unknown timeline mode");
330
    }
331
}
332

    
333
void SequenceChartFacade::extractSimulationTimesAndTimelineCoordinates(
334
    IEvent *event, IEvent *&nextEvent,
335
    simtime_t &eventSimulationTime, double &eventTimelineCoordinate,
336
    simtime_t &nextEventSimulationTime, double &nextEventTimelineCoordinate,
337
    simtime_t &simulationTimeDelta, double &timelineCoordinateDelta)
338
{
339
    // if before the first event
340
    if (event) {
341
        eventSimulationTime = event->getSimulationTime();
342
        eventTimelineCoordinate = getTimelineCoordinate(event);
343
    }
344
    else {
345
        eventSimulationTime = BigDecimal::Zero;
346
        IEvent *firstEvent = eventLog->getFirstEvent();
347
        eventTimelineCoordinate = getTimelineCoordinate(firstEvent);
348

    
349
        if (timelineMode == EVENT_NUMBER)
350
            eventTimelineCoordinate -= 1;
351
        else
352
            eventTimelineCoordinate -= getTimelineCoordinateDelta(firstEvent->getSimulationTime().dbl());
353
    }
354

    
355
    // linear approximation between two enclosing events
356
    nextEvent = event ? event->getNextEvent() : eventLog->getFirstEvent();
357

    
358
    if (nextEvent) {
359
        nextEventSimulationTime = nextEvent->getSimulationTime();
360
        nextEventTimelineCoordinate = getTimelineCoordinate(nextEvent);
361

    
362
        simulationTimeDelta = nextEventSimulationTime - eventSimulationTime;
363
        timelineCoordinateDelta = nextEventTimelineCoordinate - eventTimelineCoordinate;
364
    }
365
}
366

    
367
simtime_t SequenceChartFacade::getSimulationTimeForTimelineCoordinate(double timelineCoordinate, bool upperLimit)
368
{
369
    Assert(!isNaN(timelineCoordinate));
370

    
371
    if (eventLog->isEmpty())
372
        return BigDecimal::Zero;
373

    
374
    simtime_t simulationTime;
375

    
376
    switch (timelineMode)
377
    {
378
        case SIMULATION_TIME:
379
            {
380
                simtime_t lastEventSimulationTime = eventLog->getLastEvent()->getSimulationTime();
381
                simulationTime = max(BigDecimal::Zero, min(lastEventSimulationTime, timelineCoordinate + timelineCoordinateOriginSimulationTime));
382
            }
383
            break;
384
        case EVENT_NUMBER:
385
        case STEP:
386
        case NONLINEAR:
387
            {
388
                IEvent *nextEvent;
389
                simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta;
390
                double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;
391

    
392
                IEvent *event = getLastEventNotAfterTimelineCoordinate(timelineCoordinate);
393
                extractSimulationTimesAndTimelineCoordinates(event, nextEvent,
394
                                                             eventSimulationTime, eventTimelineCoordinate,
395
                                                             nextEventSimulationTime, nextEventTimelineCoordinate,
396
                                                             simulationTimeDelta, timelineCoordinateDelta);
397

    
398
                if (nextEvent) {
399
                    if (timelineCoordinateDelta == 0) {
400
                        // IMPORTANT NOTE: this is just an approximation
401
                        if (upperLimit)
402
                            simulationTime = nextEventSimulationTime;
403
                        else
404
                            simulationTime = eventSimulationTime;
405
                    }
406
                    else {
407
                        timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate));
408
                        simulationTime = eventSimulationTime + simulationTimeDelta * (timelineCoordinate - eventTimelineCoordinate) / timelineCoordinateDelta;
409
                        simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime));
410
                    }
411
                }
412
                else
413
                    simulationTime = eventSimulationTime;
414
            }
415
            break;
416
        default:
417
            throw opp_runtime_error("Unknown timeline mode");
418
    }
419

    
420
    Assert(!simulationTime.isNaN());
421
    Assert(simulationTime >= BigDecimal::Zero);
422
    Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
423

    
424
    return simulationTime;
425
}
426

    
427
double SequenceChartFacade::getTimelineCoordinateForSimulationTime(simtime_t simulationTime, bool upperLimit)
428
{
429
    Assert(!simulationTime.isNaN());
430

    
431
    if (eventLog->isEmpty())
432
        return 0;
433

    
434
    Assert(simulationTime >= BigDecimal::Zero);
435
    Assert(simulationTime <= eventLog->getLastEvent()->getSimulationTime());
436

    
437
    double timelineCoordinate;
438

    
439
    switch (timelineMode)
440
    {
441
        case SIMULATION_TIME:
442
            timelineCoordinate = (simulationTime - timelineCoordinateOriginSimulationTime).dbl();
443
            break;
444
        case EVENT_NUMBER:
445
        case STEP:
446
        case NONLINEAR:
447
            {
448
                IEvent *nextEvent;
449
                simtime_t eventSimulationTime, nextEventSimulationTime, simulationTimeDelta;
450
                double eventTimelineCoordinate, nextEventTimelineCoordinate, timelineCoordinateDelta;
451

    
452
                IEvent *event = eventLog->getLastEventNotAfterSimulationTime(simulationTime);
453
                extractSimulationTimesAndTimelineCoordinates(event, nextEvent,
454
                                                             eventSimulationTime, eventTimelineCoordinate,
455
                                                             nextEventSimulationTime, nextEventTimelineCoordinate,
456
                                                             simulationTimeDelta, timelineCoordinateDelta);
457

    
458
                if (nextEvent) {
459
                    if (simulationTimeDelta == BigDecimal::Zero) {
460
                        // IMPORTANT NOTE: this is just an approximation
461
                        if (upperLimit)
462
                            timelineCoordinate = nextEventTimelineCoordinate;
463
                        else
464
                            timelineCoordinate = eventTimelineCoordinate;
465
                    }
466
                    else {
467
                        simulationTime = max(eventSimulationTime, min(nextEventSimulationTime, simulationTime));
468
                        timelineCoordinate = eventTimelineCoordinate + timelineCoordinateDelta * (simulationTime - eventSimulationTime).dbl() / simulationTimeDelta.dbl();
469
                        timelineCoordinate = std::max(eventTimelineCoordinate, std::min(nextEventTimelineCoordinate, timelineCoordinate));
470
                    }
471
                }
472
                else
473
                    timelineCoordinate = eventTimelineCoordinate;
474
            }
475
            break;
476
        default:
477
            throw opp_runtime_error("Unknown timeline mode");
478
    }
479

    
480
    Assert(!isNaN(timelineCoordinate));
481

    
482
    return timelineCoordinate;
483
}
484

    
485
double SequenceChartFacade::getTimelineCoordinateForSimulationTimeAndEventInModule(simtime_t simulationTime, int moduleId)
486
{
487
    IEvent *event = eventLog->getLastEventNotAfterSimulationTime(simulationTime);
488

    
489
    while (event && event->getSimulationTime() == simulationTime) {
490
        if (event->getModuleId() == moduleId)
491
            return getTimelineCoordinate(event);
492

    
493
        event = event->getNextEvent();
494
    }
495

    
496
    return getTimelineCoordinateForSimulationTime(simulationTime);
497
}
498

    
499
std::vector<ptr_t> *SequenceChartFacade::getModuleMethodBeginEntries(ptr_t startEventPtr, ptr_t endEventPtr)
500
{
501
    IEvent *startEvent = (IEvent *)startEventPtr;
502
    IEvent *endEvent = (IEvent *)endEventPtr;
503
    Assert(startEvent);
504
    Assert(endEvent);
505
    std::vector<ptr_t> *moduleMethodBeginEntries = new std::vector<ptr_t>();
506

    
507
    for (IEvent *event = startEvent;; event = event->getNextEvent()) {
508
        eventLog->progress();
509

    
510
        for (int i = 0; i < event->getNumEventLogEntries(); i++) {
511
            EventLogEntry *eventLogEntry = event->getEventLogEntry(i);
512

    
513
            if (dynamic_cast<ModuleMethodBeginEntry *>(eventLogEntry))
514
                moduleMethodBeginEntries->push_back((ptr_t)eventLogEntry);
515
        }
516

    
517
        if (event == endEvent)
518
            break;
519
    }
520

    
521
    return moduleMethodBeginEntries;
522
}
523

    
524
std::vector<ptr_t> *SequenceChartFacade::getIntersectingMessageDependencies(ptr_t startEventPtr, ptr_t endEventPtr)
525
{
526
    IEvent *startEvent = (IEvent *)startEventPtr;
527
    IEvent *endEvent = (IEvent *)endEventPtr;
528
    Assert(startEvent);
529
    Assert(endEvent);
530
    std::set<ptr_t> messageDependencies;
531
    eventnumber_t startEventNumber = startEvent->getEventNumber();
532

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

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

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

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

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

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

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

    
560
    return result;
561
}
562

    
563
std::vector<int> SequenceChartFacade::getApproximateMessageDependencyCountAdjacencyMatrix(std::map<int, int> *moduleIdToAxisIndexMap, int numberOfSamples, int messageSendWeight, int messageReuseWeight)
564
{
565
    LCGRandom lcgRandom;
566
    std::vector<int> adjacencyMatrix;
567
    std::set<int> axisIndexSet;
568
    std::map<eventnumber_t, IEvent *> eventNumberToEventMap;
569

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

    
573
    int numberOfAxes = axisIndexSet.size();
574
    adjacencyMatrix.resize(numberOfAxes * numberOfAxes);
575

    
576
    for (int i = 0; i < numberOfSamples; i++)
577
    {
578
        // draw random
579
        double percentage = lcgRandom.next01();
580
        IEvent *event = eventLog->getApproximateEventAt(percentage);
581
        eventNumberToEventMap[event->getEventNumber()] = event;
582

    
583
        // look before origin
584
        if (timelineCoordinateOriginEventNumber != -1) {
585
            if (timelineCoordinateOriginEventNumber - i >= 0) {
586
                event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber - i);
587
                if (event)
588
                    eventNumberToEventMap[event->getEventNumber()] = event;
589
            }
590

    
591
            // look after origin
592
            event = eventLog->getEventForEventNumber(timelineCoordinateOriginEventNumber + i);
593
            if (event)
594
                eventNumberToEventMap[event->getEventNumber()] = event;
595
        }
596
    }
597

    
598
    for (std::map<eventnumber_t, IEvent *>::iterator it = eventNumberToEventMap.begin(); it != eventNumberToEventMap.end(); it++) {
599
        IEvent *event = it->second;
600
        IMessageDependencyList *causes = event->getCauses();
601

    
602
        for (IMessageDependencyList::iterator it = causes->begin(); it != causes->end(); it++) {
603
            IMessageDependency *messageDependency = *it;
604
            IEvent *causeEvent = messageDependency->getCauseEvent();
605
            IEvent *consequenceEvent = messageDependency->getConsequenceEvent();
606
            int weight = 0;
607
            if (dynamic_cast<MessageSendDependency *>(messageDependency))
608
                weight = messageSendWeight;
609
            else if (dynamic_cast<MessageReuseDependency *>(messageDependency))
610
                weight = messageReuseWeight;
611

    
612
            if (causeEvent && consequenceEvent && weight != 0) {
613
                int causeModuleId = causeEvent->getModuleId();
614
                int consequenceModuleId = consequenceEvent->getModuleId();
615

    
616
                std::map<int, int>::iterator causeModuleIdIt = moduleIdToAxisIndexMap->find(causeModuleId);
617
                std::map<int, int>::iterator consequenceModuleIdIt = moduleIdToAxisIndexMap->find(consequenceModuleId);
618

    
619
                if (causeModuleIdIt !=  moduleIdToAxisIndexMap->end() && consequenceModuleIdIt != moduleIdToAxisIndexMap->end())
620
                    adjacencyMatrix.at(causeModuleIdIt->second * numberOfAxes + consequenceModuleIdIt->second) += weight;
621
            }
622
        }
623
    }
624

    
625
    return adjacencyMatrix;
626
}