source: proto/CSV/csv2xml/pablo_template.cpp @ 2663

Last change on this file since 2663 was 2663, checked in by linmengl, 6 years ago

use store_unaligned to for speed

File size: 10.1 KB
Line 
1#include <cstdio>
2#include <cstdlib>
3#include <cerrno>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <sstream>
7#include <cstring>
8
9#define LocalCarryDeclare(name, count)\
10CarryArray<count, 0> name;\
11
12#include "../lib/bitblock.hpp"
13#include "../lib/carryQ.hpp"
14#include "../lib/bitblock_iterator.hpp"
15#include "../lib/s2p.hpp"
16#include "../lib/perflib/perfsec.h"
17
18// Define the mappings for pablo.assert_0(strm, errkind) statements which
19// compile to the the form assert_0_error(errkind, strm)
20#define assert_0_error(errkind, errstrm) error_tracker.NoteError(errkind, errstrm);
21
22#ifdef BUFFER_PROFILING
23    BOM_Table * parser_timer;
24#elif CODE_CLOCKER
25    //#define NUM_EVENTS 1
26    //int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
27    //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
28    #define NUM_EVENTS 2
29    int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
30    int cal_size = 20;
31    CC * parser_timer = new CC(Events,NUM_EVENTS,cal_size);
32#else
33    void * parser_timer;
34#endif
35
36BitBlock EOF_mask = simd<1>::constant<1>();
37
38//////////////////////////////////////////////////////////////////////////////////////////
39// Buffer Management // WARNING: Do Not update #defines. Results in TagMatcher errors.
40//////////////////////////////////////////////////////////////////////////////////////////
41#define PADDING_BLOCKS 0
42#define PADDING_SIZE (BLOCK_SIZE * PADDING_BLOCKS)
43#define COPYBACK_BLOCKS 2
44#define COPYBACK_SIZE (BLOCK_SIZE * COPYBACK_BLOCKS)
45#define LOOKAHEAD_BLOCKS 1
46#define LOOKAHEAD_SIZE (BLOCK_SIZE * LOOKAHEAD_BLOCKS)
47#define SEGMENT_BLOCKS 15 // WARNING: TagMatcher.hpp causes xmlconf test suite failures for SEGMENT_BLOCKS < 3.
48#define SEGMENT_SIZE (BLOCK_SIZE * SEGMENT_BLOCKS)
49#define BUFFER_SIZE (COPYBACK_SIZE + SEGMENT_SIZE + LOOKAHEAD_SIZE + PADDING_SIZE)
50
51//////////////////////////////////////////////////////////////////////////////////////////
52// @ global depends on 'error_tracker' and 'EOF_mask' definitions.
53//////////////////////////////////////////////////////////////////////////////////////////
54BitBlock Simd_const_odd = simd<4>::constant<10>();
55BitBlock Simd_const_even = simd<4>::constant<5>();
56
57inline BitBlock parse_quote_mask(BitBlock quote)
58{
59    BitBlock p2, p4, p8, p16, p32, p64;
60    BitBlock t1, t2, t4, t8, t16, t32, t64;
61
62    t1 = bitblock::slli<1>(quote);
63    p2 = simd_xor(quote, t1);
64
65    t2 = bitblock::slli<2>(p2);
66    p4 = simd_xor(p2, t2);
67
68    t4 = bitblock::slli<4>(p4);
69    p8 = simd_xor(p4, t4);
70
71    t8 = bitblock::slli<8>(p8);
72    p16 = simd_xor(p8, t8);
73
74    t16 = bitblock::slli<16>(p16);
75    p32 = simd_xor(p16, t16);
76
77    t32 = bitblock::slli<32>(p32);
78    p64 = simd_xor(p32, t32);
79
80    t64 = bitblock::slli<64>(p64);
81    return simd_xor(p64, t64);
82}
83
84BitBlock FlipSignal;
85BitBlock UseTabSignal;
86
87@global
88
89//////////////////////////////////////////////////////////////////////////////////////////
90// Headers that depend @ global stream struct types.
91//////////////////////////////////////////////////////////////////////////////////////////
92#include "../lib/transpose.hpp"
93#include "../util/csv2xmlwriter.hpp"
94#include "../util/bitsegment_iterator.hpp"
95
96static void do_process(FILE *infile, FILE *outfile);
97
98const BitBlock ZERO = convert(0);
99const BitBlock ONE = convert(1);
100const BitBlock HIGH_ONE = bitblock::slli<BLOCK_SIZE-1>(convert(1));
101
102int main(int argc, char * argv[])
103{
104    char infilename[100] = "sample.csv";
105    char outfilename[100] = "sample_xml.txt";
106
107    UseTabSignal = ZERO;
108    if (argc == 3)
109    {
110        strcpy(infilename, argv[1]);
111        strcpy(outfilename, argv[2]);
112    }
113    else if (argc == 4)
114    {
115        if (strcmp(argv[1], "-tab") != 0)
116        {
117            printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
118            return 0;
119        }
120        else
121        {
122            UseTabSignal = ONE;
123            strcpy(infilename, argv[2]);
124            strcpy(outfilename, argv[3]);
125        }
126    }
127    else
128    {
129        printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
130    }
131
132    printf("Process %s as input and %s as output\n", infilename, outfilename);
133
134    FILE *infile = fopen(infilename, "rb");
135    FILE *outfile = fopen(outfilename, "wb");
136    setbuf(outfile, NULL); //shutdown default buffer system
137    // printf("setvbuf = %d\n", setvbuf(outfile, NULL, _IOFBF, SEGMENT_SIZE * 16));
138
139    PERF_SEC_BIND(1);
140
141    PERF_SEC_INIT(parser_timer);
142
143    do_process(infile, outfile);
144
145    PERF_SEC_DUMP(parser_timer);
146
147    PERF_SEC_DESTROY(parser_timer);
148
149    fclose(infile);
150    fclose(outfile);
151
152    return(0);
153}
154
155class IteratorPackage
156{
157public:
158    BitSegment<SEGMENT_BLOCKS> delimSeg, eolSeg, andSeg, hideSeg;
159
160    IteratorPackage()
161    {
162        init();
163    }
164
165    void init()
166    {
167        delimSeg.clear();
168        eolSeg.clear();
169        andSeg.clear();
170        hideSeg.clear();
171    }
172
173    void append(Marker &marker, Lex &lex)
174    {
175        delimSeg.append(marker.delim);
176        eolSeg.append(marker.eol);
177        andSeg.append(lex.AndSymbol);
178        hideSeg.append(marker.hide);
179    }
180};
181
182class BufferToXMLParser
183{
184    BitSegmentForwardIterator delimIter, eolIter, andIter, hideIter;
185    uint8_t *src_buffer;
186    Csv2XmlWriter *writer;
187    IteratorPackage *package;
188
189public:
190
191    BufferToXMLParser(uint8_t *buffer, Csv2XmlWriter *_writer, IteratorPackage *_package, int n)
192        : delimIter(_package->delimSeg.address(), n), eolIter(_package->eolSeg.address(), n),
193            andIter(_package->andSeg.address(), n), hideIter(_package->hideSeg.address(), n)
194    {
195        src_buffer = buffer;
196        writer = _writer;
197        package = _package;
198    }
199
200    void parseEachRow(int buffer_size)
201    {
202        int pos = 0;
203
204        while (!eolIter.is_end())
205        {
206            parseRowWithoutLastColumn(pos, *eolIter);
207
208            if (pos <= *eolIter)
209            {
210                int length = *eolIter - pos;
211                bufPrintWithAndSymbol(pos, length);
212                writer->nextCol();
213            }
214            pos = *eolIter + 1;
215
216            ++ eolIter;
217            writer->nextRow();
218        }
219
220        if (pos <= buffer_size)
221        {
222            //last line within a block
223            parseRowWithoutLastColumn(pos, buffer_size);
224
225            if (pos < buffer_size)
226            {
227                int length = buffer_size - pos;
228                bufPrintWithAndSymbol(pos, length);
229            }
230        }
231    }
232
233private:
234    void parseRowWithoutLastColumn(int &pos, int endofline)
235    {
236        while ((!delimIter.is_end()) && (*delimIter < endofline))
237        {
238            int length = *delimIter - pos;
239            bufPrintWithAndSymbol(pos, length);
240            writer->nextCol();
241            pos = (*delimIter) + 1;
242            ++delimIter;
243        }
244    }
245
246    void bufPrintWithAndSymbol(int startPos, int length)
247    {
248        char text[10] = "&amp;";
249
250        while (length > 0)
251        {
252            while ((!andIter.is_end()) && *andIter < startPos) ++andIter;
253
254            if (!andIter.is_end() && *andIter < startPos + length)
255            {
256                bufPrintWithHideSymbol(startPos, *andIter - startPos);
257                writer->writeColumn(text, 5);
258
259                length -= *andIter - startPos + 1;
260                startPos = *andIter + 1;
261            }
262            else
263            {
264                bufPrintWithHideSymbol(startPos, length);
265                length = 0;
266            }
267        }
268    }
269
270    void bufPrintWithHideSymbol(int startPos, int length)
271    {
272        while (length > 0)
273        {
274            while (!hideIter.is_end() && *hideIter < startPos) ++hideIter;
275
276            if (!hideIter.is_end() && *hideIter < startPos + length)
277            {
278                bufPrintSimple(startPos, *hideIter - startPos);
279                length -= *hideIter - startPos + 1;
280                startPos = *hideIter + 1;
281            }
282            else
283            {
284                bufPrintSimple(startPos, length);
285                length = 0;
286            }
287        }
288    }
289
290    void bufPrintSimple(int startPos, int length)
291    {
292        uint8_t *p = src_buffer + startPos;
293        writer->writeColumn((char *)p, length);
294    }
295};
296
297void do_process(FILE *infile, FILE *outfile) {
298
299    @decl;
300
301    BitBlock buf[9];//watch out buffer size, may cause memory leak!! shit!!
302    BitBlock segBuf[9 * SEGMENT_BLOCKS];
303
304    uint8_t * src_buffer = (uint8_t *) buf;
305    uint8_t * seg_buffer = (uint8_t *) segBuf;
306    size_t count;
307
308    @stream_stmts;
309
310    Csv2XmlWriter writer(outfile);
311    FlipSignal = ZERO;
312
313    bool infile_end = false;
314    int segment_count;
315    int segment_blocks;
316    unsigned long long infile_count = 0;
317    IteratorPackage package;
318
319    while (!infile_end)
320    {
321        segment_count = 0;
322        segment_blocks = 0;
323        package.init();
324        PERF_SEC_START(parser_timer);
325
326
327        //if quoted string spanned more than 1 block, next block's FlipSignal should be 1
328        while (segment_blocks < SEGMENT_BLOCKS && (count = fread(src_buffer, sizeof(uint8_t), BLOCK_SIZE, infile)) > 0)
329        {
330            memcpy(seg_buffer + segment_count, src_buffer, count);
331            segment_blocks ++;
332            segment_count += count;
333            infile_count += count;
334
335            if (count < BLOCK_SIZE)
336            {
337                EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-count));
338                s2p_do_final_block((BytePack *) src_buffer, basis_bits, EOF_mask);
339                @final_block_stmts
340            }
341            else
342            {
343                s2p_do_block((BytePack *) src_buffer, basis_bits);
344                @block_stmts
345                FlipSignal = ZERO;
346                if (bitblock::any(simd_and(marker.quote_mask, HIGH_ONE)))
347                {
348                    FlipSignal = ONE;
349                }
350            }
351
352            package.append(marker, lex);
353        }
354
355        if (segment_count)
356        {
357            BufferToXMLParser bufParser(seg_buffer, &writer, &package, segment_blocks);
358            bufParser.parseEachRow(segment_count);
359            writer.flush();
360
361            PERF_SEC_END(parser_timer, segment_count);
362        }
363
364        if (segment_blocks < SEGMENT_BLOCKS)
365        {
366            infile_end = true;
367        }
368    }
369
370
371    printf("input: %lld\t", infile_count);
372    printf("output: %lld\t", writer._outCount);
373    printf("rate: %lf\n", (double) writer._outCount / (double) infile_count);
374}
Note: See TracBrowser for help on using the repository browser.