Statistics
| Branch: | Revision:

root / src / eventlog / eventlog.cc @ master

History | View | Annotate | Download (14.3 KB)

1 01873262 Georg Kunz
//=========================================================================
2
//  EVENTLOG.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 "filereader.h"
19
#include "stringpool.h"
20
#include "eventlog.h"
21
22
NAMESPACE_BEGIN
23
24
CommonStringPool eventLogStringPool;
25
26
EventLog::EventLog(FileReader *reader) : EventLogIndex(reader)
27
{
28
    reader->setSynchronizeWhenAppended(false);
29
30
    clearInternalState();
31
    parseInitializationLogEntries();
32
}
33
34
EventLog::~EventLog()
35
{
36
    deleteAllocatedObjects();
37
}
38
39
void EventLog::deleteAllocatedObjects()
40
{
41
    for (EventLogEntryList::iterator it = initializationLogEntries.begin(); it != initializationLogEntries.end(); it++)
42
        delete *it;
43
44
    for (EventNumberToEventMap::iterator it = eventNumberToEventMap.begin(); it != eventNumberToEventMap.end(); it++)
45
        delete it->second;
46
47
    clearInternalState();
48
}
49
50
void EventLog::clearInternalState(FileReader::FileChangedState change)
51
{
52
    Assert(change != FileReader::UNCHANGED);
53
    approximateNumberOfEvents = -1;
54
55
    // lastEvent should be set to null if the last event becomes a different one
56
    if (change == FileReader::OVERWRITTEN) {
57
        numParsedEvents = 0;
58
59
        progressCallInterval = CLOCKS_PER_SEC;
60
        lastProgressCall = -1;
61
62
        firstEvent = NULL;
63
        lastEvent = NULL;
64
65 81ad8b66 Georg Kunz
        legacyTrace = true;
66
67 01873262 Georg Kunz
        messageNames.clear();
68
        messageClassNames.clear();
69
70
        initializationLogEntries.clear();
71
//        moduleIdToModuleCreatedEntryMap.clear();
72
        moduleIdAndGateIdToGateCreatedEntryMap.clear();
73
74
        simulationBeginEntry = NULL;
75
76
        eventNumberToEventMap.clear();
77
        beginOffsetToEventMap.clear();
78
        endOffsetToEventMap.clear();
79
    }
80
    else if (lastEvent && lastEvent->getBeginOffset() != getLastEventOffset())
81
        lastEvent = NULL;
82
}
83
84
void EventLog::synchronize(FileReader::FileChangedState change)
85
{
86
    if (change != FileReader::UNCHANGED) {
87
        if (change == FileReader::OVERWRITTEN)
88
            deleteAllocatedObjects();
89
90
        Event *lastEvent = this->lastEvent;
91
92
        IEventLog::synchronize(change);
93
        EventLogIndex::synchronize(change);
94
95
        if (change == FileReader::APPENDED) {
96
            clearInternalState(change);
97
98
            // always update the old last event because it might have been incomplete
99
            if (lastEvent)
100
                parseEvent(lastEvent, lastEvent->getBeginOffset());
101
102
            for (EventNumberToEventMap::iterator it = eventNumberToEventMap.begin(); it != eventNumberToEventMap.end(); it++)
103
                it->second->synchronize();
104
        }
105
        else
106
            parseInitializationLogEntries();
107
    }
108
}
109
110
ProgressMonitor EventLog::setProgressMonitor(ProgressMonitor newProgressMonitor)
111
{
112
    ProgressMonitor oldProgressMonitor = progressMonitor;
113
    progressMonitor = newProgressMonitor;
114
    return oldProgressMonitor;
115
}
116
117
void EventLog::progress()
118
{
119
    if (lastProgressCall + progressCallInterval < clock()) {
120
        progressMonitor.progress(this);
121
        lastProgressCall = clock();
122
    }
123
}
124
125
eventnumber_t EventLog::getApproximateNumberOfEvents()
126
{
127
    if (approximateNumberOfEvents == -1)
128
    {
129
        Event *firstEvent = getFirstEvent();
130
        Event *lastEvent = getLastEvent();
131
132
        if (firstEvent == NULL)
133
            approximateNumberOfEvents = 0;
134
        else
135
        {
136
            file_offset_t beginOffset = firstEvent->getBeginOffset();
137
            file_offset_t endOffset = lastEvent->getEndOffset();
138
            long sum = 0;
139
            long count = 0;
140
            int eventCount = 100;
141
142
            for (int i = 0; i < eventCount; i++)
143
            {
144
                if (firstEvent) {
145
                    sum += firstEvent->getEndOffset() - firstEvent->getBeginOffset();
146
                    count++;
147
                    firstEvent = firstEvent->getNextEvent();
148
                }
149
150
                if (lastEvent) {
151
                    sum += lastEvent->getEndOffset() - lastEvent->getBeginOffset();
152
                    count++;
153
                    lastEvent = lastEvent->getPreviousEvent();
154
                }
155
            }
156
157
            double average = (double)sum / count;
158
            approximateNumberOfEvents = (long)((endOffset - beginOffset) / average);
159
        }
160
    }
161
162
    return approximateNumberOfEvents;
163
}
164
165
Event *EventLog::getApproximateEventAt(double percentage)
166
{
167
    Event *firstEvent = getFirstEvent();
168
    Event *lastEvent = getLastEvent();
169
170
    if (firstEvent == NULL)
171
        return NULL;
172
    else {
173
        file_offset_t beginOffset = firstEvent->getBeginOffset();
174
        file_offset_t endOffset = lastEvent->getEndOffset();
175
        file_offset_t offset = beginOffset + (file_offset_t)((endOffset - beginOffset) * percentage);
176
177
        eventnumber_t eventNumber;
178
        file_offset_t lineStartOffset = -1, lineEndOffset;
179
        simtime_t simulationTime;
180
        readToEventLine(false, offset, eventNumber, simulationTime, lineStartOffset, lineEndOffset);
181
182
        Event *event = NULL;
183
184
        if (lineStartOffset == -1)
185
            event = getFirstEvent();
186
        else
187
            event = getEventForBeginOffset(lineStartOffset);
188
189
        Assert(event);
190
191
        return event;
192
    }
193
}
194
195
void EventLog::parseInitializationLogEntries()
196
{
197
    int index = 0;
198
    reader->seekTo(0);
199
200
    if (PRINT_DEBUG_MESSAGES) printf("Parsing initialization log entries at: 0\n");
201
202
    while (true)
203
    {
204
        char *line = reader->getNextLineBufferPointer();
205
206
        if (!line)
207
            break;
208
209
        EventLogEntry *eventLogEntry = EventLogEntry::parseEntry(NULL, index, line, reader->getCurrentLineLength());
210
211
        if (!eventLogEntry)
212
            continue;
213
        else
214
            index++;
215
216
        if (dynamic_cast<EventEntry *>(eventLogEntry)) {
217
            delete eventLogEntry;
218
            break;
219
        }
220
221
        initializationLogEntries.push_back(eventLogEntry);
222
        cacheEventLogEntry(eventLogEntry);
223
    }
224
}
225
226
void EventLog::printInitializationLogEntries(FILE *file)
227
{
228
    for (EventLogEntryList::iterator it = initializationLogEntries.begin(); it != initializationLogEntries.end(); it++)
229
        (*it)->print(file);
230
}
231
232
std::vector<ModuleCreatedEntry *> EventLog::getModuleCreatedEntries()
233
{
234
    std::vector<ModuleCreatedEntry *> moduleCreatedEntries;
235
236
    for (ModuleIdToModuleCreatedEntryMap::iterator it = moduleIdToModuleCreatedEntryMap.begin(); it != moduleIdToModuleCreatedEntryMap.end(); it++) {
237
        Assert(it->second);
238
        moduleCreatedEntries.push_back(it->second);
239
    }
240
241
    return moduleCreatedEntries;
242
}
243
244
ModuleCreatedEntry *EventLog::getModuleCreatedEntry(int moduleId)
245
{
246
    ModuleIdToModuleCreatedEntryMap::iterator it = moduleIdToModuleCreatedEntryMap.find(moduleId);
247
248
    if (it == moduleIdToModuleCreatedEntryMap.end())
249
        return NULL;
250
    else
251
        return it->second;
252
}
253
254
GateCreatedEntry *EventLog::getGateCreatedEntry(int moduleId, int gateId)
255
{
256
    std::pair<int, int> key(moduleId, gateId);
257
    ModuleIdAndGateIdToGateCreatedEntryMap::iterator it = moduleIdAndGateIdToGateCreatedEntryMap.find(key);
258
259
    if (it == moduleIdAndGateIdToGateCreatedEntryMap.end())
260
        return NULL;
261
    else
262
        return it->second;
263
}
264
265
Event *EventLog::getFirstEvent()
266
{
267
    if (!firstEvent) {
268
        file_offset_t offset = getFirstEventOffset();
269
270
        if (offset != -1)
271
            firstEvent = getEventForBeginOffset(offset);
272
    }
273
274
    return firstEvent;
275
}
276
277
Event *EventLog::getLastEvent()
278
{
279
    if (!lastEvent) {
280
        file_offset_t offset = getLastEventOffset();
281
282
        if (offset != -1)
283
            lastEvent = getEventForBeginOffset(offset);
284
    }
285
286
    return lastEvent;
287
}
288
289 12288d0e Simon Tenbusch
Event *EventLog::getFirstEventRealTime()
290
{
291
    Assert(firstEventRealTime != NULL);
292
    return firstEventRealTime;
293
}
294
295
Event *EventLog::getLastEventRealTime()
296
{
297
    Assert(lastEventRealTime != NULL);
298
    return lastEventRealTime;
299
}
300
301 01873262 Georg Kunz
Event *EventLog::getEventForEventNumber(eventnumber_t eventNumber, MatchKind matchKind)
302
{
303
    Assert(eventNumber >= 0);
304
305
    if (matchKind == EXACT) {
306
        EventNumberToEventMap::iterator it = eventNumberToEventMap.find(eventNumber);
307
        if (it != eventNumberToEventMap.end())
308
            return it->second;
309
310
        // the following two are still faster than binary searching
311
        it = eventNumberToEventMap.find(eventNumber - 1);
312
        if (it != eventNumberToEventMap.end())
313
            return it->second->getNextEvent();
314
315
        it = eventNumberToEventMap.find(eventNumber + 1);
316
        if (it != eventNumberToEventMap.end())
317
            return it->second->getPreviousEvent();
318
    }
319
320
    // TODO: maybe cache result
321
    file_offset_t offset = getOffsetForEventNumber(eventNumber, matchKind);
322
323
    if (offset == -1)
324
        return NULL;
325
    else
326
        return getEventForBeginOffset(offset);
327
}
328
329
Event *EventLog::getNeighbourEvent(IEvent *event, eventnumber_t distance)
330
{
331
    Assert(event);
332
    return (Event *)IEventLog::getNeighbourEvent(event, distance);
333
}
334
335
Event *EventLog::getEventForSimulationTime(simtime_t simulationTime, MatchKind matchKind)
336
{
337
    Assert(simulationTime >= 0);
338
339
    file_offset_t offset = getOffsetForSimulationTime(simulationTime, matchKind);
340
341
    if (offset == -1)
342
        return NULL;
343
    else
344
        return getEventForBeginOffset(offset);
345
}
346
347
EventLogEntry *EventLog::findEventLogEntry(EventLogEntry *start, const char *search, bool forward, bool caseSensitive)
348
{
349
    char *line;
350
    reader->seekTo(start->getEvent()->getBeginOffset());
351
    int index = start->getEntryIndex();
352
353
    for (int i = 0; i < index + forward ? 1 : 0; i++)
354
        reader->getNextLineBufferPointer();
355
356
    if (forward)
357
        line = reader->findNextLineBufferPointer(search, caseSensitive);
358
    else
359
        line = reader->findPreviousLineBufferPointer(search, caseSensitive);
360
361
    if (line) {
362
        if (forward)
363
            line = reader->getPreviousLineBufferPointer();
364
365
        index = 0;
366
367
        do {
368
            if (line[0] == 'E' && line[1] == ' ')
369
                return getEventForBeginOffset(reader->getCurrentLineStartOffset())->getEventLogEntry(index);
370
            else if (line[0] != '\r' && line[0] != '\n')
371
                index++;
372
        }
373
        while ((line = reader->getPreviousLineBufferPointer()));
374
    }
375
376
    return NULL;
377
}
378
379
Event *EventLog::getEventForBeginOffset(file_offset_t beginOffset)
380
{
381
    Assert(beginOffset >= 0);
382
    OffsetToEventMap::iterator it = beginOffsetToEventMap.find(beginOffset);
383
384
    if (it != beginOffsetToEventMap.end())
385
        return it->second;
386
    else if (reader->getFileSize() != beginOffset)
387
    {
388
        Event *event = new Event(this);
389
        parseEvent(event, beginOffset);
390
        cacheEvent(event);
391
        return event;
392
    }
393
    else {
394
        beginOffsetToEventMap[beginOffset] = NULL;
395
        return NULL;
396
    }
397
}
398
399
Event *EventLog::getEventForEndOffset(file_offset_t endOffset)
400
{
401
    Assert(endOffset >= 0);
402
    OffsetToEventMap::iterator it = endOffsetToEventMap.find(endOffset);
403
404
    if (it != endOffsetToEventMap.end())
405
        return it->second;
406
    else {
407
        file_offset_t beginOffset = getBeginOffsetForEndOffset(endOffset);
408
409
        if (beginOffset == -1) {
410
            endOffsetToEventMap[endOffset] = NULL;
411
            return NULL;
412
        }
413
        else
414
            return getEventForBeginOffset(beginOffset);
415
    }
416
}
417
418
void EventLog::parseEvent(Event *event, file_offset_t beginOffset)
419
{
420
    event->parse(reader, beginOffset);
421 81ad8b66 Georg Kunz
    if(event->getEventEndEntry() != NULL)
422
        legacyTrace = false;
423
424 01873262 Georg Kunz
    cacheEntry(event->getEventNumber(), event->getSimulationTime(), event->getBeginOffset(), event->getEndOffset());
425
    cacheEventLogEntries(event);
426
    numParsedEvents++;
427
}
428
429
void EventLog::cacheEventLogEntries(Event *event)
430
{
431
    for (int i = 0; i < event->getNumEventLogEntries(); i++)
432
        cacheEventLogEntry(event->getEventLogEntry(i));
433
}
434
435
void EventLog::uncacheEventLogEntries(Event *event)
436
{
437
    for (int i = 0; i < event->getNumEventLogEntries(); i++)
438
        uncacheEventLogEntry(event->getEventLogEntry(i));
439
}
440
441
void EventLog::cacheEventLogEntry(EventLogEntry *eventLogEntry)
442
{
443
    // simulation begin entry
444
    SimulationBeginEntry *simulationBeginEntry = dynamic_cast<SimulationBeginEntry *>(eventLogEntry);
445
446
    if (simulationBeginEntry)
447
        this->simulationBeginEntry = simulationBeginEntry;
448
449
    // collect module created entries
450
    ModuleCreatedEntry *moduleCreatedEntry = dynamic_cast<ModuleCreatedEntry *>(eventLogEntry);
451
452
    if (moduleCreatedEntry) {
453
        moduleIdToModuleCreatedEntryMap[moduleCreatedEntry->moduleId] = moduleCreatedEntry;
454
        getModuleCreatedEntries();
455
    }
456
457
    // collect gate created entries
458
    GateCreatedEntry *gateCreatedEntry = dynamic_cast<GateCreatedEntry *>(eventLogEntry);
459
460
    if (gateCreatedEntry) {
461
        std::pair<int, int> key(gateCreatedEntry->moduleId, gateCreatedEntry->gateId);
462
        moduleIdAndGateIdToGateCreatedEntryMap[key] = gateCreatedEntry;
463
    }
464
465
    // colllect begin send entry
466
    BeginSendEntry *beginSendEntry = dynamic_cast<BeginSendEntry *>(eventLogEntry);
467
    if (beginSendEntry) {
468
        messageNames.insert(beginSendEntry->messageFullName);
469
        messageClassNames.insert(beginSendEntry->messageClassName);
470
    }
471
}
472
473
void EventLog::uncacheEventLogEntry(EventLogEntry *eventLogEntry)
474
{
475
    // collect module created entries
476
//    ModuleCreatedEntry *moduleCreatedEntry = dynamic_cast<ModuleCreatedEntry *>(eventLogEntry);
477
//    if (moduleCreatedEntry)
478
//        moduleIdToModuleCreatedEntryMap.erase(moduleCreatedEntry->moduleId);
479
480
    // collect gate created entries
481
    GateCreatedEntry *gateCreatedEntry = dynamic_cast<GateCreatedEntry *>(eventLogEntry);
482
483
    if (gateCreatedEntry) {
484
        std::pair<int, int> key(gateCreatedEntry->moduleId, gateCreatedEntry->gateId);
485
        moduleIdAndGateIdToGateCreatedEntryMap.erase(key);
486
    }
487
}
488
489
void EventLog::cacheEvent(Event *event)
490
{
491
    int eventNumber = event->getEventNumber();
492
    Assert(!lastEvent || eventNumber <= lastEvent->getEventNumber());
493
    Assert(eventNumberToEventMap.find(eventNumber) == eventNumberToEventMap.end());
494
495
    eventNumberToEventMap[eventNumber] = event;
496
    beginOffsetToEventMap[event->getBeginOffset()] = event;
497
    endOffsetToEventMap[event->getEndOffset()] = event;
498
}
499
500
NAMESPACE_END