Statistics
| Branch: | Revision:

root / src / scave / indexfile.h @ 7c7d95e5

History | View | Annotate | Download (10 KB)

1
//=========================================================================
2
//  INDEXFILE.H - part of
3
//                  OMNeT++/OMNEST
4
//           Discrete System Simulation in C++
5
//
6
//  Author: Tamas Borbely
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 _INDEXFILE_H_
18
#define _INDEXFILE_H_
19

    
20
#include <float.h>
21
#include <map>
22
#include <vector>
23
#include "platmisc.h"
24
#include "scavedefs.h"
25
#include "commonutil.h"
26
#include "statistics.h"
27

    
28
NAMESPACE_BEGIN
29

    
30
/**
31
 * Data of one block stored in the index file.
32
 */
33
struct Block {
34
    file_offset_t startOffset;
35
    int64 size;
36
    long startSerial;
37
    eventnumber_t startEventNum;
38
    eventnumber_t endEventNum;
39
    simultime_t startTime;
40
    simultime_t endTime;
41
    Statistics stat;
42

    
43
    Block() : startOffset(-1), size(0), startSerial(-1), startEventNum(-1), endEventNum(-1),
44
        startTime(0.0), endTime(0.0) {}
45

    
46
    long getCount() const { return stat.getCount(); }
47
    double getMin() const { return stat.getMin(); }
48
    double getMax() const { return stat.getMax(); }
49
    double getSum() const { return stat.getSum(); }
50
    double getSumSqr() const { return stat.getSumSqr(); }
51

    
52
    long endSerial() const { return startSerial + getCount(); }
53

    
54
    bool contains(long serial) const { return startSerial <= serial && serial < endSerial(); }
55

    
56
    void collect(eventnumber_t eventNum, simultime_t simtime, double value)
57
    {
58
        if (getCount() == 0)
59
        {
60
            startEventNum = eventNum;
61
            startTime = simtime;
62
        }
63
        endEventNum = eventNum;
64
        endTime = simtime;
65
        stat.collect(value);
66
    }
67
};
68

    
69
typedef std::vector<Block> Blocks;
70

    
71
typedef std::map<std::string, std::string> StringMap;
72

    
73
/**
74
 * Entry for one vector in the index.
75
 */
76
struct VectorData {
77
    int vectorId;
78
    std::string moduleName;
79
    std::string name;
80
    std::string columns;
81
    StringMap attributes;
82
    int64 blockSize;
83
    eventnumber_t startEventNum;
84
    eventnumber_t endEventNum;
85
    simultime_t startTime;
86
    simultime_t endTime;
87
    Statistics stat;
88
    Blocks blocks;
89

    
90
    /**
91
     * Creates an index entry for a vector.
92
     */
93
    VectorData() : vectorId(-1), blockSize(0) {}
94
    VectorData(int vectorId, std::string moduleName, std::string name, std::string columns, int64 blockSize)
95
        : vectorId(vectorId), moduleName(moduleName), name(name), columns(columns), blockSize(blockSize),
96
          startEventNum(-1), endEventNum(-1), startTime(0.0), endTime(0.0) {}
97

    
98
    long getCount() const { return stat.getCount(); }
99
    double getMin() const { return stat.getMin(); }
100
    double getMax() const { return stat.getMax(); }
101
    double getSum() const { return stat.getSum(); }
102
    double getSumSqr() const { return stat.getSumSqr(); }
103

    
104
    /**
105
     * Adds the block statistics to the vector statistics.
106
     */
107
    void collect(const Block &block)
108
    {
109
        if (getCount() == 0)
110
        {
111
            startEventNum = block.startEventNum;
112
            startTime = block.startTime;
113
        }
114
        endEventNum = block.endEventNum;
115
        endTime = block.endTime;
116
        stat.adjoin(block.stat);
117
        if (block.size > blockSize)
118
            blockSize = block.size;
119
    }
120

    
121
    void addBlock(const Block &block) { blocks.push_back(block); collect(block); }
122

    
123
    /**
124
     * Returns true if the vector contains the specified column.
125
     */
126
    bool hasColumn(char column) const { return columns.find(column) != std::string::npos; }
127

    
128
    /**
129
     * Returns a pointer to the block containing the entry with the given serial,
130
     * or NULL if no such entry.
131
     */
132
    const Block *getBlockBySerial(long serial) const;
133

    
134
    /**
135
     * Returns the first block which endTime >= simtime (when after == true)
136
     * or the last block whose startTime <= simtime (when after == false).
137
     * Returns NULL if no such block.
138
     */
139
    const Block *getBlockBySimtime(simultime_t simtime, bool after) const;
140

    
141
    /**
142
     * Returns the first block which endEventNum >= eventNum (when after == true)
143
     * or the last block whose startEventNum <= eventNum (when after == false).
144
     * Returns NULL if no such block.
145
     */
146
    const Block *getBlockByEventnum(eventnumber_t eventNum, bool after) const;
147

    
148
    /**
149
     * Finds the start (inclusive) and end (exclusive) indeces of the range of blocks,
150
     * containing entries in the [startTime,endTime] interval (both inclusive).
151
     * Returns the number of blocks found.
152
     */
153
    Blocks::size_type getBlocksInSimtimeInterval(simultime_t startTime, simultime_t endTime, Blocks::size_type &startIndex, Blocks::size_type &endIndex) const;
154

    
155
    /**
156
     * Finds the start (inclusive) and end (exclusive) indeces of the range of blocks,
157
     * containing entries in the [startEventNum,endEventNum] interval (both inclusive).
158
     * Returns the number of blocks found.
159
     */
160
    Blocks::size_type getBlocksInEventnumInterval(eventnumber_t startEventNum, eventnumber_t endEventNum, Blocks::size_type &startIndex, Blocks::size_type &endIndex) const;
161
};
162

    
163
typedef std::vector<VectorData> Vectors;
164

    
165
/**
166
 * Run attributes written into the index file.
167
 */
168
struct RunData {
169
    std::string runName;
170
    int runNumber;
171
    StringMap attributes;
172
    StringMap moduleParams;
173

    
174
    RunData() : runNumber(0) {}
175

    
176
    bool parseLine(char **tokens, int numTokens, const char *filename, int64 lineNo);
177
    void writeToFile(FILE *file, const char *filename) const;
178
};
179

    
180
/**
181
 * Attributes of the vector files that are stored in the index file to
182
 * check if it is up-to-date.
183
 */
184
struct FingerPrint {
185
    int64 lastModified;
186
    int64 fileSize;
187

    
188
    FingerPrint() : lastModified(0), fileSize(0) {}
189
    FingerPrint(const char *vectorFileName);
190
    bool check(const char *vectorFileName);
191
};
192

    
193
/**
194
 * Data of all vectors stored in the index file.
195
 */
196
struct VectorFileIndex {
197
    std::string vectorFileName;
198
    FingerPrint fingerprint;
199
    RunData run;
200
private:
201
    Vectors vectors;
202
    typedef std::map<int,int> VectorIdToIndexMap;
203
    VectorIdToIndexMap map; // maps vectorId to index in the vectors array
204

    
205
public:
206

    
207
    int getNumberOfVectors() const
208
    {
209
        return vectors.size();
210
    }
211

    
212
    void addVector(const VectorData &vector)
213
    {
214
        map[vector.vectorId] = vectors.size();
215
        vectors.push_back(vector);
216
    }
217

    
218
    const VectorData *getVectorAt(int index) const
219
    {
220
        Assert(0 <= index && index < (int)vectors.size());
221
        return &vectors[index];
222
    }
223

    
224
    VectorData *getVectorAt(int index)
225
    {
226
        Assert(0 <= index && index < (int)vectors.size());
227
        return &vectors[index];
228
    }
229

    
230
    VectorData *getVectorById(int vectorId)
231
    {
232
        VectorIdToIndexMap::const_iterator entry = map.find(vectorId);
233
        return entry!=map.end() ? getVectorAt(entry->second) : NULL;
234
    }
235
};
236

    
237
/**
238
 * FIXME comment
239
 */
240
class SCAVE_API IndexFile
241
{
242
    public:
243
        static bool isIndexFile(const char *indexFileName);
244
        static bool isVectorFile(const char *vectorFileName);
245
        static std::string getIndexFileName(const char *vectorFileName);
246
        static std::string getVectorFileName(const char *indexFileName);
247
        /**
248
         * Checks if the index file is up-to-date.
249
         * The fileName is either the name of the index file or the vector file.
250
         * The index file is up-to-date if the size and modification date stored in the index file
251
         * is equal to the size and date of the vector file.
252
         */
253
        static bool isIndexFileUpToDate(const char *fileName);
254
};
255

    
256
/**
257
 * Reader for an index file.
258
 */
259
class SCAVE_API IndexFileReader
260
{
261
   private:
262
        /** The name of the index file. */
263
        std::string filename;
264
    public:
265
        /**
266
         * Creates a reader for the specified index file.
267
         */
268
        IndexFileReader(const char *filename);
269

    
270
        /**
271
         * Reads the index fully into the memory.
272
         */
273
        VectorFileIndex *readAll();
274

    
275
        /**
276
         * Reads the fingerprint of the vector file this index file belongs to.
277
         */
278
        VectorFileIndex *readFingerprint();
279
    protected:
280
        /**
281
         * Parse one line of the index file.
282
         */
283
        void parseLine(char **tokens, int numTokens, VectorFileIndex *index, int64 lineNum);
284
};
285

    
286
/**
287
 * Writer for an index file.
288
 */
289
class SCAVE_API IndexFileWriter
290
{
291
    private:
292
        /** Name of the index file. */
293
        std::string filename;
294
        /** Precision of double values stored in the index file. */
295
        int precision;
296
        /** Handle of the opened index file. */
297
        FILE *file;
298
    public:
299
        /**
300
         * Creates a writer for the specified index file.
301
         */
302
        IndexFileWriter(const char *filename, int precision=14);
303
        /**
304
         * Deletes the writer. (Closes the index file first.)
305
         */
306
        ~IndexFileWriter();
307
        /**
308
         * Writes out the index fully.
309
         */
310
        void writeAll(const VectorFileIndex& index);
311
        /**
312
         * Writes out the fingerprint of the vector file this index file belongs to.
313
         */
314
        void writeFingerprint(std::string vectorFileName);
315
        /**
316
         * Writes out the run attributes.
317
         */
318
        void writeRun(const RunData &run);
319
        /**
320
         * Writes out the index of one vector (declaration+blocks).
321
         */
322
        void writeVector(const VectorData& vector);
323
        /**
324
         * Writes out the declaration of a vector.
325
         */
326
        void writeVectorDeclaration(const VectorData& vector);
327
        /**
328
         * Writes out the attributes of a vector.
329
         */
330
        void writeVectorAttributes(const VectorData& vector);
331
        /**
332
         * Writes out a block of the specified vector.
333
         */
334
        void writeBlock(const VectorData &vector, const Block& block);
335
    protected:
336
        /** Opens the index file. */
337
        void openFile();
338
        /** Closes the index file. */
339
        void closeFile();
340
};
341

    
342
NAMESPACE_END
343

    
344

    
345
#endif