Project

General

Profile

Statistics
| Branch: | Revision:

root / src / eventlog / messagedependency.cc @ 3e29b8a0

History | View | Annotate | Download (11 KB)

1
//=========================================================================
2
//  MESSAGEDEPENDENCY.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 "eventlogdefs.h"
19
#include "ievent.h"
20
#include "ieventlog.h"
21
#include "event.h"
22
#include "eventlogentry.h"
23
#include "messagedependency.h"
24

    
25
USING_NAMESPACE
26

    
27
/**************************************************/
28

    
29
IMessageDependency::IMessageDependency(IEventLog *eventLog, bool isReuse)
30
{
31
    this->eventLog = eventLog;
32
    this->isReuse = isReuse;
33
}
34

    
35

    
36
bool IMessageDependency::corresponds(IMessageDependency *dependency1, IMessageDependency *dependency2)
37
{
38
    if (!dependency1 || !dependency2)
39
        return false;
40

    
41
    BeginSendEntry *entry1 = dependency1->getBeginSendEntry();
42
    BeginSendEntry *entry2 = dependency2->getBeginSendEntry();
43

    
44
    if (!entry1 || !entry2)
45
        return false;
46

    
47
    return
48
        (entry1->messageId != -1 && entry1->messageId == entry2->messageId) ||
49
        (entry1->messageTreeId != -1 && entry1->messageTreeId == entry2->messageTreeId) ||
50
        (entry1->messageEncapsulationId != -1 && entry1->messageEncapsulationId == entry2->messageEncapsulationId) ||
51
        (entry1->messageEncapsulationTreeId != -1 && entry1->messageEncapsulationTreeId == entry2->messageEncapsulationTreeId);
52
}
53

    
54
bool IMessageDependency::equals(IMessageDependency *other)
55
{
56
    Assert(eventLog == other->eventLog);
57

    
58
    return other->isReuse == isReuse;
59
}
60

    
61
/**************************************************/
62

    
63
MessageDependency::MessageDependency(IEventLog *eventLog, bool isReuse, eventnumber_t eventNumber, int beginSendEntryNumber)
64
    : IMessageDependency(eventLog, isReuse)
65
{
66
    Assert(eventNumber >= 0 && beginSendEntryNumber >= 0);
67

    
68
    if (isReuse) {
69
        this->causeEventNumber = EVENT_NOT_YET_CALCULATED;
70
        this->causeBeginSendEntryNumber = -1;
71
        this->consequenceEventNumber = eventNumber;
72
        this->consequenceBeginSendEntryNumber = beginSendEntryNumber;
73
    }
74
    else {
75
        this->causeEventNumber = eventNumber;
76
        this->causeBeginSendEntryNumber = beginSendEntryNumber;
77
        this->consequenceEventNumber = EVENT_NOT_YET_CALCULATED;
78
        this->consequenceBeginSendEntryNumber = -1;
79
    }
80
}
81

    
82
MessageDependency *MessageDependency::duplicate(IEventLog *eventLog)
83
{
84
    MessageDependency *messageDependency = new MessageDependency(*this);
85
    messageDependency->eventLog = eventLog;
86
    return messageDependency;
87
}
88

    
89
BeginSendEntry *MessageDependency::getCauseBeginSendEntry()
90
{
91
    Assert(causeBeginSendEntryNumber != -1);
92
    IEvent *event = getCauseEvent();
93
    Assert(event);
94
    return (BeginSendEntry *)event->getEventLogEntry(causeBeginSendEntryNumber);
95
}
96

    
97
eventnumber_t MessageDependency::getCauseEventNumber()
98
{
99
    if (causeEventNumber == EVENT_NOT_YET_CALCULATED)
100
    {
101
        // only consequence is present, calculate cause from it
102
        IEvent *consequenceEvent = getConsequenceEvent();
103
        Assert(consequenceEvent);
104
        BeginSendEntry *beginSendEntry = (BeginSendEntry *)consequenceEvent->getEventLogEntry(consequenceBeginSendEntryNumber);
105
        causeEventNumber = beginSendEntry->previousEventNumber;
106
    }
107

    
108
    return causeEventNumber;
109
}
110

    
111
IEvent *MessageDependency::getCauseEvent()
112
{
113
    eventnumber_t causeEventNumber = getCauseEventNumber();
114

    
115
    if (causeEventNumber < 0)
116
        return NULL;
117
    else
118
        return eventLog->getEventForEventNumber(causeEventNumber);
119
}
120

    
121
simtime_t MessageDependency::getCauseSimulationTime()
122
{
123
    return getCauseEvent()->getSimulationTime();
124
}
125

    
126
BeginSendEntry *MessageDependency::getConsequenceBeginSendEntry()
127
{
128
    Assert(consequenceBeginSendEntryNumber != -1);
129
    IEvent *event = getConsequenceEvent();
130
    Assert(event);
131
    return (BeginSendEntry *)event->getEventLogEntry(consequenceBeginSendEntryNumber);
132
}
133

    
134
eventnumber_t MessageDependency::getConsequenceEventNumber()
135
{
136
    if (consequenceEventNumber == EVENT_NOT_YET_CALCULATED || consequenceEventNumber == EVENT_NOT_YET_REACHED)
137
    {
138
        // only cause is present, calculate consequence from it.
139
        //
140
        // when a message is scheduled/sent, we don't know the arrival event number
141
        // yet, only the simulation time is recorded in the event log file.
142
        // So here we have to look through all events at the arrival time,
143
        // and find the one "caused by" our message.
144
        simtime_t consequenceTime = getConsequenceSimulationTime();
145

    
146
        if (consequenceTime == simtime_nil)
147
            consequenceEventNumber = NO_SUCH_EVENT;
148
        else {
149
            IEvent *event = eventLog->getEventForSimulationTime(consequenceTime, FIRST_OR_PREVIOUS);
150

    
151
            // TODO: LONG RUNNING OPERATION
152
            while (event)
153
            {
154
                eventLog->progress();
155

    
156
                if (event->getCauseEventNumber() == getCauseEventNumber() &&
157
                    event->getMessageId() == getCauseMessageId())
158
                {
159
                    consequenceEventNumber = event->getEventNumber();
160
                    break;
161
                }
162

    
163
                if (event->getSimulationTime() > consequenceTime)
164
                {
165
                    // no more event at that simulation time, and consequence event
166
                    // still not found. It must have been cancelled (self message),
167
                    // or it is not in the file (filtered out by the user, etc).
168
                    consequenceEventNumber = NO_SUCH_EVENT;
169
                    break;
170
                }
171

    
172
                event = event->getNextEvent();
173
            }
174

    
175
            // end of file
176
            if (!event)
177
                consequenceEventNumber = EVENT_NOT_YET_REACHED;
178
        }
179
    }
180

    
181
    return consequenceEventNumber;
182
}
183

    
184
IEvent *MessageDependency::getConsequenceEvent()
185
{
186
    eventnumber_t consequenceEventNumber = getConsequenceEventNumber();
187

    
188
    if (consequenceEventNumber < 0)
189
        return NULL;
190
    else
191
        return eventLog->getEventForEventNumber(consequenceEventNumber);
192
}
193

    
194
simtime_t MessageDependency::getConsequenceSimulationTime()
195
{
196
    if (consequenceEventNumber >= 0)
197
        return getConsequenceEvent()->getSimulationTime();
198
    else
199
    {
200
        // find the arrival time of the message
201
        IEvent *event = getCauseEvent();
202
        BeginSendEntry *beginSendEntry = (BeginSendEntry *)(event->getEventLogEntry(causeBeginSendEntryNumber));
203
        EndSendEntry *endSendEntry = event->getEndSendEntry(beginSendEntry);
204

    
205
        if (endSendEntry)
206
            return endSendEntry->arrivalTime;
207
        else
208
            return simtime_nil;
209
    }
210
}
211

    
212
bool MessageDependency::isSelfMessageReuse()
213
{
214
    if (!isReuse)
215
        return false;
216
    else {
217
        IEvent *causeEvent = getCauseEvent();
218
        IEvent *consequenceEvent = getConsequenceEvent();
219
        BeginSendEntry *beginSendEntry = getConsequenceBeginSendEntry();
220

    
221
        return causeEvent && consequenceEvent && beginSendEntry &&
222
            causeEvent->getModuleId() == consequenceEvent->getModuleId() &&
223
            consequenceEvent->isSelfMessage(beginSendEntry);
224
    }
225

    
226
}
227

    
228
bool MessageDependency::isStoredMessageReuse()
229
{
230
    if (!isReuse)
231
        return false;
232
    else {
233
        IEvent *causeEvent = getCauseEvent();
234
        IEvent *consequenceEvent = getConsequenceEvent();
235
        BeginSendEntry *beginSendEntry = getConsequenceBeginSendEntry();
236

    
237
        return causeEvent && consequenceEvent && beginSendEntry &&
238
            causeEvent->getModuleId() == consequenceEvent->getModuleId() &&
239
            !consequenceEvent->isSelfMessage(beginSendEntry);
240
    }
241
}
242

    
243
bool MessageDependency::equals(IMessageDependency *other)
244
{
245
    MessageDependency *otherMessageDependency = dynamic_cast<MessageDependency *>(other);
246
    return IMessageDependency::equals(other) && otherMessageDependency &&
247
        getCauseEventNumber() == otherMessageDependency->getCauseEventNumber() &&
248
        getCauseBeginSendEntryNumber() == otherMessageDependency->getCauseBeginSendEntryNumber() &&
249
        getConsequenceEventNumber() == otherMessageDependency->getConsequenceEventNumber() &&
250
        getConsequenceBeginSendEntryNumber() == otherMessageDependency->getConsequenceBeginSendEntryNumber();
251
}
252

    
253
void MessageDependency::print(FILE *file)
254
{
255
    printCause(file);
256
    printConsequence(file);
257
}
258

    
259
void MessageDependency::printCause(FILE *file)
260
{
261
    if (getCauseEventNumber() >= 0)
262
        getCauseEvent()->getEventEntry()->print(file);
263

    
264
    if (getCauseBeginSendEntryNumber() != -1)
265
        getCauseBeginSendEntry()->print(file);
266
}
267

    
268
void MessageDependency::printConsequence(FILE *file)
269
{
270
    if (getConsequenceEventNumber() >= 0)
271
       getConsequenceEvent()->getEventEntry()->print(file);
272

    
273
    if (getConsequenceBeginSendEntryNumber() != -1)
274
       getConsequenceBeginSendEntry()->print(file);
275
}
276

    
277
/**************************************************/
278

    
279
FilteredMessageDependency::FilteredMessageDependency(IEventLog *eventLog, bool isReuse, IMessageDependency *beginMessageDependency, IMessageDependency *endMessageDependency)
280
    : IMessageDependency(eventLog, isReuse)
281
{
282
    this->beginMessageDependency = beginMessageDependency;
283
    this->endMessageDependency = endMessageDependency;
284
}
285

    
286
FilteredMessageDependency::~FilteredMessageDependency()
287
{
288
    delete beginMessageDependency;
289
    delete endMessageDependency;
290
}
291

    
292
FilteredMessageDependency *FilteredMessageDependency::duplicate(IEventLog *eventLog)
293
{
294
    return new FilteredMessageDependency(eventLog, isReuse, beginMessageDependency->duplicate(eventLog), endMessageDependency->duplicate(eventLog));
295
}
296

    
297
IEvent *FilteredMessageDependency::getCauseEvent()
298
{
299
    eventnumber_t causeEventNumber = beginMessageDependency->getCauseEventNumber();
300

    
301
    if (causeEventNumber < 0)
302
        return NULL;
303
    else
304
        return eventLog->getEventForEventNumber(causeEventNumber);
305
}
306

    
307
IEvent *FilteredMessageDependency::getConsequenceEvent()
308
{
309
    eventnumber_t consequenceEventNumber = endMessageDependency->getConsequenceEventNumber();
310

    
311
    if (consequenceEventNumber < 0)
312
        return NULL;
313
    else
314
        return eventLog->getEventForEventNumber(consequenceEventNumber);
315
}
316

    
317
BeginSendEntry *FilteredMessageDependency::getCauseBeginSendEntry()
318
{
319
    return beginMessageDependency->getBeginSendEntry();
320
}
321

    
322
BeginSendEntry *FilteredMessageDependency::getConsequenceBeginSendEntry()
323
{
324
    return endMessageDependency->getBeginSendEntry();
325
}
326

    
327
bool FilteredMessageDependency::equals(IMessageDependency *other)
328
{
329
    FilteredMessageDependency *otherFiltered = dynamic_cast<FilteredMessageDependency *>(other);
330
    return IMessageDependency::equals(other) && otherFiltered &&
331
        beginMessageDependency->equals(otherFiltered->beginMessageDependency) &&
332
        endMessageDependency->equals(otherFiltered->endMessageDependency);
333
}
334

    
335
void FilteredMessageDependency::print(FILE *file)
336
{
337
    beginMessageDependency->print(file);
338
    endMessageDependency->print(file);
339
}