Project

General

Profile

Statistics
| Branch: | Revision:

root / src / scave / indexedvectorfilereader.cc @ a3be1d55

History | View | Annotate | Download (5.94 KB)

1
//=========================================================================
2
//  INDEXEDVECTORFILEREADER.CC - 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
#include <algorithm>
18
#include "platmisc.h"
19
#include "opp_ctype.h"
20
#include "channel.h"
21
#include "scaveutils.h"
22
#include "vectorfilereader.h"
23
#include "indexedvectorfilereader.h"
24

    
25
USING_NAMESPACE
26

    
27
using namespace std;
28

    
29
#define LL  INT64_PRINTF_FORMAT
30

    
31
IndexedVectorFileReaderNode::IndexedVectorFileReaderNode(const char *filename, size_t bufferSize) :
32
  ReaderNode(filename, bufferSize), index(NULL), currentBlockIndex(0)
33
{
34

    
35
}
36

    
37
IndexedVectorFileReaderNode::~IndexedVectorFileReaderNode()
38
{
39
    if (index) {
40
        delete index;
41
        index = NULL;
42
    }
43
}
44

    
45
Port *IndexedVectorFileReaderNode::addVector(const VectorResult &vector)
46
{
47
    PortData& portdata = ports[vector.vectorId];
48
    portdata.ports.push_back(Port(this));
49
    Port& port = portdata.ports.back();
50
    return &port;
51
}
52

    
53
bool IndexedVectorFileReaderNode::isReady() const
54
{
55
    return true;
56
}
57

    
58
void IndexedVectorFileReaderNode::process()
59
{
60
    if (!index)
61
        readIndexFile();
62

    
63
    long bytesRead = 0;
64
    while (currentBlockIndex < blocksToRead.size() && bytesRead < 64 * 1024)
65
    {
66
        BlockAndPortData &blockAndPort = blocksToRead[currentBlockIndex++];
67
        bytesRead += readBlock(blockAndPort.blockPtr, blockAndPort.portDataPtr);
68
    }
69
}
70

    
71
bool IndexedVectorFileReaderNode::isFinished() const
72
{
73
    return index && currentBlockIndex >= blocksToRead.size();
74
}
75

    
76
void IndexedVectorFileReaderNode::readIndexFile()
77
{
78
    const char *fn = filename.c_str();
79

    
80
    if (!IndexFile::isVectorFile(fn))
81
        throw opp_runtime_error("indexed vector file reader: not a vector file, file %s", fn);
82
    if (!IndexFile::isIndexFileUpToDate(fn))
83
        throw opp_runtime_error("indexed vector file reader: index file is not up to date, file %s", fn);
84

    
85
    string indexFileName = IndexFile::getIndexFileName(fn);
86
    IndexFileReader reader(indexFileName.c_str());
87
    index = reader.readAll();
88

    
89
    for (VectorIdToPortMap::iterator it = ports.begin(); it != ports.end(); ++it)
90
    {
91
        int vectorId = it->first;
92
        PortData &portData = it->second;
93

    
94
        portData.vector = index->getVectorById(vectorId);
95

    
96
        if (!portData.vector)
97
            throw opp_runtime_error("indexed vector file reader: vector %d not found, file %s",
98
                                        vectorId, indexFileName.c_str());
99

    
100
        Blocks &blocks = portData.vector->blocks;
101
        for (Blocks::iterator it = blocks.begin(); it != blocks.end(); ++it)
102
            blocksToRead.push_back(BlockAndPortData(&(*it), &portData));
103
    }
104

    
105
    sort(blocksToRead.begin(), blocksToRead.end());
106
}
107

    
108

    
109
long IndexedVectorFileReaderNode::readBlock(const Block *blockPtr, const PortData *portDataPtr)
110
{
111
    assert(blockPtr);
112
    assert(portDataPtr->vector);
113

    
114
    const char *file = filename.c_str();
115
    file_offset_t offset;
116
#define CHECK(cond, msg) {if (!cond) throw opp_runtime_error(msg ", file %s, offset %"LL"d", file, (int64)offset); }
117

    
118
    VectorData *vector = portDataPtr->vector;
119
    file_offset_t startOffset = blockPtr->startOffset;
120
    long count = blockPtr->getCount();
121

    
122
    reader.seekTo(startOffset);
123

    
124
    long readTime=0;
125
    long tokenizeTime = 0;
126
    long parseTime = 0;
127
//  printf("readBlock ");
128

    
129
    char *line;
130
    for (long k = 0; k < count /*&& (line=reader.getNextLineBufferPointer())!=NULL*/; ++k)
131
    {
132
        TIME(readTime,line=reader.getNextLineBufferPointer());
133

    
134
        if (!line)
135
            break;
136

    
137

    
138
        offset = reader.getCurrentLineStartOffset();
139
        int length = reader.getCurrentLineLength();
140
        TIME(tokenizeTime, tokenizer.tokenize(line, length));
141

    
142
        int numtokens = tokenizer.numTokens();
143
        char **vec = tokenizer.tokens();
144
        int vectorId;
145

    
146
        // check vector id
147
        CHECK((numtokens >= 3) && opp_isdigit(vec[0][0]), "vector file reader: data line too short");
148
        CHECK(parseInt(vec[0], vectorId), "invalid vector file syntax: invalid vector id column");
149
        CHECK(vectorId == vector->vectorId, "vector file reader: unexpected vector id");
150

    
151
        // parse columns
152
        Datum a;
153
        TIME(parseTime, a = parseColumns(vec, numtokens, vector->columns, file, -1, offset));
154

    
155
        // write to port(s)
156
        for (PortVector::const_iterator port = portDataPtr->ports.begin(); port != portDataPtr->ports.end(); ++port)
157
            port->getChannel()->write(&a,1);
158
    }
159

    
160
//    printf("read: %ldms tokenize: %ldms parse: %ldms\n",
161
//          readTime/1000, tokenizeTime/1000, parseTime/1000);
162

    
163
    return blockPtr->size;
164
}
165

    
166
//-----
167

    
168
const char *IndexedVectorFileReaderNodeType::getDescription() const
169
{
170
    return "Reads indexed output vector files.";
171
}
172

    
173
void IndexedVectorFileReaderNodeType::getAttributes(StringMap& attrs) const
174
{
175
    attrs["filename"] = "name of the output vector file (.vec)";
176
}
177

    
178
Node *IndexedVectorFileReaderNodeType::create(DataflowManager *mgr, StringMap& attrs) const
179
{
180
    checkAttrNames(attrs);
181

    
182
    const char *fname = attrs["filename"].c_str();
183

    
184
    Node *node = new IndexedVectorFileReaderNode(fname);
185
    node->setNodeType(this);
186
    mgr->addNode(node);
187
    return node;
188
}
189

    
190
Port *IndexedVectorFileReaderNodeType::getPort(Node *node, const char *portname) const
191
{
192
    // vector id is used as port name
193
    IndexedVectorFileReaderNode *node1 = dynamic_cast<IndexedVectorFileReaderNode *>(node);
194
    VectorResult vector;
195
    if (!parseInt(portname, vector.vectorId))
196
        throw opp_runtime_error("indexed file reader node: port should be a vector id, received: %s", portname);
197
    return node1->addVector(vector);
198
}
199