Statistics
| Branch: | Revision:

root / src / eventlog / eventlogindex.h @ e1750c09

History | View | Annotate | Download (7.68 KB)

1 01873262 Georg Kunz
//=========================================================================
2
//  EVENTLOGINDEX.H - 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
#ifndef __EVENTLOGINDEX_H_
18
#define __EVENTLOGINDEX_H_
19
20
#include <sstream>
21
#include <list>
22
#include <vector>
23
#include <map>
24
#include "eventlogdefs.h"
25
#include "exception.h"
26
#include "eventlogdefs.h"
27
#include "filereader.h"
28
#include "linetokenizer.h"
29
30
NAMESPACE_BEGIN
31
32
/**
33
 * Allows random access of an event log file, i.e. positioning on arbitrary event numbers and simulation times.
34
 * TODO: throw out entries from cache to free memory. This is not that urgent because the cache will be quite
35
 * small unless the file is linearly read through which is not supposed to happen.
36
 */
37
class EVENTLOG_API EventLogIndex
38
{
39
    protected:
40
        FileReader *reader;
41
        LineTokenizer tokenizer;
42
43
        file_offset_t firstEventOffset;
44
        file_offset_t lastEventOffset;
45
        eventnumber_t firstEventNumber;
46
        eventnumber_t lastEventNumber;
47
        simtime_t firstSimulationTime;
48
        simtime_t lastSimulationTime;
49
50
        /**
51
         * An entry stores information for a simulation time and the corresponding event number and file offset ranges.
52
         * It actually describes a range of lines in the event log file.
53
         * The range might be temporarily smaller than what is actually present in the file for the given
54
         * simulation time or event number. The range gets closer and finally reaches the exact values by subsequent search operations.
55
         */
56
        class CacheEntry
57
        {
58
            public:
59
                simtime_t simulationTime;
60
                eventnumber_t beginEventNumber; // begin event with simulation time
61
                eventnumber_t endEventNumber; // end event with simulation time
62
                file_offset_t beginOffset; // begin offset of begin event
63
                file_offset_t endEventBeginOffset; // begin offset of end event
64
                file_offset_t endOffset; // end offset of end event
65
66
            public:
67
                CacheEntry();
68
                CacheEntry(eventnumber_t eventNumber, simtime_t simulationTime, file_offset_t beginOffset, file_offset_t endOffset);
69
                void include(eventnumber_t eventNumber, simtime_t simulationTime, file_offset_t beginOffset, file_offset_t endOffset);
70
                void getBeginKey(eventnumber_t &key);
71
                void getBeginKey(simtime_t &key);
72
                void getEndKey(eventnumber_t &key);
73
                void getEndKey(simtime_t &key);
74
        };
75
76
        /**
77
         * Subsequent events in an event log file may not have subsequent event numbers,
78
         * therefore it is insufficient to store the file offset only in the cache.
79
         */
80
        typedef std::map<eventnumber_t, CacheEntry> EventNumberToCacheEntryMap;
81
        EventNumberToCacheEntryMap eventNumberToCacheEntryMap;
82
83
        /**
84
         * Subsequent events in an event log file may have the same simulation time,
85
         * therefore it is insufficient to store the file offset only in the cache.
86
         */
87
        typedef std::map<simtime_t, CacheEntry> SimulationTimeToCacheEntryMap;
88
        SimulationTimeToCacheEntryMap simulationTimeToCacheEntryMap;
89
90
    protected:
91
        void cacheEntry(eventnumber_t eventNumber, simtime_t simulationTime, file_offset_t beginOffset, file_offset_t endOffset);
92
93
        /**
94
         * Search for the file offset based on the key with the given match kind.
95
         * The key is either an event number or a simulation time.
96
         */
97
        template <typename T> file_offset_t searchForOffset(std::map<T, CacheEntry> &map, T key, MatchKind matchKind);
98
        /**
99
         * Search the internal cache finding the file offset(s and keys) for the given key with the given match kind.
100
         * Sets lower and upper keys and offsets to the closest appropriate values found in the cache.
101
         * Lower is less than or equal to key, while upper is greater than or equal that could theoretically be found in the event log file.
102
         * Sets found offset or returns false if the offset cannot be exactly determined.
103
         */
104
        template <typename T> bool cacheSearchForOffset(std::map<T, CacheEntry> &map, T key, MatchKind matchKind, T& lowerKey, T& upperKey, file_offset_t& foundOffset, file_offset_t& lowerOffset, file_offset_t& upperOffset);
105
        /**
106
         * Binary search through the event log file finding the file offset for the given key with the given match kind.
107
         * Sets the closest lower and upper keys and offsets around the key found in the event log file.
108
         * Returns -1 if the offset cannot be determined.
109
         */
110
        template <typename T> file_offset_t  binarySearchForOffset(T key, MatchKind matchKind, T& lowerKey, T& upperKey, file_offset_t& lowerOffset, file_offset_t& upperOffset);
111
        /**
112
         * Linear search through the event log file finding the file offset for the given key.
113
         * The search starts from begin offset and continues in the direction specified by the forward flag.
114
         * Returns -1 if no such event found otherwise the last exact match or the first non exact match depending
115
         * on the exact match required flag.
116
         */
117
        template <typename T> file_offset_t linearSearchForOffset(T key, file_offset_t beginOffset, bool forward, bool exactMatchRequired);
118
119
        void clearInternalState(FileReader::FileChangedState change = FileReader::OVERWRITTEN);
120
121
        bool isEventBeginOffset(file_offset_t offset);
122
123
    public:
124
        /**
125
         * The reader will be deleted with this object.
126
         */
127
        EventLogIndex(FileReader *reader);
128
        virtual ~EventLogIndex();
129
130
        virtual void synchronize(FileReader::FileChangedState change);
131
        eventnumber_t getFirstEventNumber();
132
        eventnumber_t getLastEventNumber();
133
        simtime_t getFirstSimulationTime();
134
        simtime_t getLastSimulationTime();
135
        file_offset_t getFirstEventOffset();
136
        file_offset_t getLastEventOffset();
137
        void ensureFirstEventAndLastEventCached();
138
        /**
139
         * Returns the begin file offset of an event reading linearly backward from its end file offset.
140
         */
141
        file_offset_t getBeginOffsetForEndOffset(file_offset_t endOffset);
142
        /**
143
         * Returns the end file offset of an event reading linearly forward from its begin file offset.
144
         */
145
        file_offset_t getEndOffsetForBeginOffset(file_offset_t beginOffset);
146
        /**
147
         * Returns the begin file offset of the requested event. See MatchKind for details.
148
         */
149
        file_offset_t getOffsetForEventNumber(eventnumber_t eventNumber, MatchKind matchKind = EXACT);
150
        /**
151
         * Returns the begin file offset of the requested simulation time. See MatchKind for details.
152
         */
153
        file_offset_t getOffsetForSimulationTime(simtime_t simulationTime, MatchKind matchKind = EXACT);
154
        /**
155
         * Returns true if OK, false if no "E" line found till the end of file in the given direction.
156
         * Reads the first event line in the given direction starting from the given offset.
157
         */
158
        bool readToEventLine(bool forward, file_offset_t readBeginOffset, eventnumber_t& eventNumber, simtime_t& simulationTime, file_offset_t& lineBeginOffset, file_offset_t& lineEndOffset);
159
        void dump();
160
};
161
162
NAMESPACE_END
163
164
#endif