source: proto/CSV/csv2xml/src/csv.cpp @ 2611

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

finish test with PERF_SEC

File size: 16.7 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  12 // 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
57BitBlock 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  struct Basis_bits {
88  BitBlock bit_0;
89  BitBlock bit_1;
90  BitBlock bit_2;
91  BitBlock bit_3;
92  BitBlock bit_4;
93  BitBlock bit_5;
94  BitBlock bit_6;
95  BitBlock bit_7;
96};
97
98  struct Lex {
99  BitBlock BackSlash;
100  BitBlock DQuote;
101  BitBlock SQuote;
102  BitBlock CR;
103  BitBlock LF;
104  BitBlock Comma;
105  BitBlock Period;
106  BitBlock HT;
107  BitBlock AndSymbol;
108};
109
110  struct Marker {
111  BitBlock delim;
112  BitBlock quote;
113  BitBlock quote_mask;
114  BitBlock escape;
115  BitBlock eol;
116  BitBlock hide;
117};
118
119  struct Classify_bytes {
120 
121  IDISA_INLINE void do_block(Basis_bits & basis_bits, Lex & lex) {
122                BitBlock temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10;
123                BitBlock temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
124                BitBlock temp19, temp20, temp21, temp22, temp23, temp24;
125
126
127        temp1 = simd_andc(basis_bits.bit_1, basis_bits.bit_0);
128        temp2 = simd_andc(basis_bits.bit_3, basis_bits.bit_2);
129        temp3 = simd_and(temp1, temp2);
130        temp4 = simd_and(basis_bits.bit_4, basis_bits.bit_5);
131        temp5 = simd_or(basis_bits.bit_6, basis_bits.bit_7);
132        temp6 = simd_andc(temp4, temp5);
133        lex.BackSlash = simd_and(temp3, temp6);
134        temp7 = simd_or(basis_bits.bit_0, basis_bits.bit_1);
135        temp8 = simd_andc(basis_bits.bit_2, basis_bits.bit_3);
136        temp9 = simd_andc(temp8, temp7);
137        temp10 = simd_or(basis_bits.bit_4, basis_bits.bit_5);
138        temp11 = simd_andc(basis_bits.bit_6, basis_bits.bit_7);
139        temp12 = simd_andc(temp11, temp10);
140        lex.DQuote = simd_and(temp9, temp12);
141        temp13 = simd_andc(basis_bits.bit_5, basis_bits.bit_4);
142        temp14 = simd_and(basis_bits.bit_6, basis_bits.bit_7);
143        temp15 = simd_and(temp13, temp14);
144        lex.SQuote = simd_and(temp9, temp15);
145        temp16 = simd_or(basis_bits.bit_2, basis_bits.bit_3);
146        temp17 = simd_or(temp7, temp16);
147        temp18 = simd_andc(basis_bits.bit_7, basis_bits.bit_6);
148        temp19 = simd_and(temp4, temp18);
149        lex.CR = simd_andc(temp19, temp17);
150        temp20 = simd_andc(basis_bits.bit_4, basis_bits.bit_5);
151        temp21 = simd_and(temp20, temp11);
152        lex.LF = simd_andc(temp21, temp17);
153        lex.Comma = simd_and(temp9, temp6);
154        temp22 = simd_and(temp20, temp18);
155        lex.HT = simd_andc(temp22, temp17);
156        temp23 = simd_and(temp4, temp11);
157        lex.Period = simd_and(temp9, temp23);
158        temp24 = simd_and(temp13, temp11);
159        lex.AndSymbol = simd_and(temp9, temp24);
160  }
161  void do_final_block(Basis_bits & basis_bits, Lex & lex, BitBlock EOF_mask) {
162                BitBlock temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10;
163                BitBlock temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
164                BitBlock temp19, temp20, temp21, temp22, temp23, temp24;
165
166
167        temp1 = simd_andc(basis_bits.bit_1, basis_bits.bit_0);
168        temp2 = simd_andc(basis_bits.bit_3, basis_bits.bit_2);
169        temp3 = simd_and(temp1, temp2);
170        temp4 = simd_and(basis_bits.bit_4, basis_bits.bit_5);
171        temp5 = simd_or(basis_bits.bit_6, basis_bits.bit_7);
172        temp6 = simd_andc(temp4, temp5);
173        lex.BackSlash = simd_and(temp3, temp6);
174        temp7 = simd_or(basis_bits.bit_0, basis_bits.bit_1);
175        temp8 = simd_andc(basis_bits.bit_2, basis_bits.bit_3);
176        temp9 = simd_andc(temp8, temp7);
177        temp10 = simd_or(basis_bits.bit_4, basis_bits.bit_5);
178        temp11 = simd_andc(basis_bits.bit_6, basis_bits.bit_7);
179        temp12 = simd_andc(temp11, temp10);
180        lex.DQuote = simd_and(temp9, temp12);
181        temp13 = simd_andc(basis_bits.bit_5, basis_bits.bit_4);
182        temp14 = simd_and(basis_bits.bit_6, basis_bits.bit_7);
183        temp15 = simd_and(temp13, temp14);
184        lex.SQuote = simd_and(temp9, temp15);
185        temp16 = simd_or(basis_bits.bit_2, basis_bits.bit_3);
186        temp17 = simd_or(temp7, temp16);
187        temp18 = simd_andc(basis_bits.bit_7, basis_bits.bit_6);
188        temp19 = simd_and(temp4, temp18);
189        lex.CR = simd_andc(temp19, temp17);
190        temp20 = simd_andc(basis_bits.bit_4, basis_bits.bit_5);
191        temp21 = simd_and(temp20, temp11);
192        lex.LF = simd_andc(temp21, temp17);
193        lex.Comma = simd_and(temp9, temp6);
194        temp22 = simd_and(temp20, temp18);
195        lex.HT = simd_andc(temp22, temp17);
196        temp23 = simd_and(temp4, temp11);
197        lex.Period = simd_and(temp9, temp23);
198        temp24 = simd_and(temp13, temp11);
199        lex.AndSymbol = simd_and(temp9, temp24);
200  }
201  void do_segment(Basis_bits basis_bits[], Lex lex[], int segment_blocks) {
202  int i;
203  for (i = 0; i < segment_blocks; i++)
204    do_block(basis_bits[i], lex[i]);
205  }
206 
207  };
208
209  struct Parse_marker {
210  Parse_marker() { 
211 }
212  IDISA_INLINE void do_block(Lex & lex, Marker & marker) {
213                BitBlock odd, even, start, even_start, even_final, escape, odd_start;
214                BitBlock odd_final;
215
216
217        odd = Simd_const_odd;
218        even = Simd_const_even;
219        start = simd_andc(lex.BackSlash, carryQ.BitBlock_advance_ci_co(lex.BackSlash, carryQ.get_carry_in(0), 0));
220        even_start = simd_and(start, even);
221        even_final = carryQ.BitBlock_scanthru_ci_co(even_start, lex.BackSlash, carryQ.get_carry_in(1), 1);
222        escape = simd_and(even_final, odd);
223        odd_start = simd_and(start, odd);
224        odd_final = carryQ.BitBlock_scanthru_ci_co(odd_start, lex.BackSlash, carryQ.get_carry_in(2), 2);
225        marker.escape = simd_or(escape, simd_and(odd_final, even));
226        marker.quote = simd_andc(lex.DQuote, marker.escape);
227        marker.quote_mask = parse_quote_mask(marker.quote);
228        if (bitblock::any(FlipSignal)) {
229          marker.quote_mask = simd_not(marker.quote_mask);
230        }
231        if (bitblock::any(UseTabSignal)) {
232          marker.delim = simd_andc(simd_andc(lex.HT, escape), marker.quote_mask);
233        }
234        else {
235          marker.delim = simd_andc(simd_andc(lex.Comma, escape), marker.quote_mask);
236        }
237        marker.eol = simd_andc(simd_or(lex.CR, lex.LF), marker.quote_mask);
238        marker.hide = simd_or(marker.quote, simd_andc(simd_and(carryQ.BitBlock_advance_ci_co(lex.CR, carryQ.get_carry_in(3), 3), lex.LF), marker.quote_mask));
239        marker.eol = simd_andc(marker.eol, marker.hide);
240        carryQ.CarryQ_Adjust(4);
241  }
242  void do_final_block(Lex & lex, Marker & marker, BitBlock EOF_mask) {
243                BitBlock odd, even, start, even_start, even_final, escape, odd_start;
244                BitBlock odd_final;
245
246
247        odd = Simd_const_odd;
248        even = Simd_const_even;
249        start = simd_andc(lex.BackSlash, carryQ.BitBlock_advance_ci_co(lex.BackSlash, carryQ.get_carry_in(0), 0));
250        even_start = simd_and(start, even);
251        even_final = carryQ.BitBlock_scanthru_ci_co(even_start, lex.BackSlash, carryQ.get_carry_in(1), 1);
252        escape = simd_and(even_final, odd);
253        odd_start = simd_and(start, odd);
254        odd_final = carryQ.BitBlock_scanthru_ci_co(odd_start, lex.BackSlash, carryQ.get_carry_in(2), 2);
255        marker.escape = simd_or(escape, simd_and(odd_final, even));
256        marker.quote = simd_andc(lex.DQuote, marker.escape);
257        marker.quote_mask = parse_quote_mask(marker.quote);
258        if (bitblock::any(FlipSignal)) {
259          marker.quote_mask = simd_not(marker.quote_mask);
260        }
261        if (bitblock::any(UseTabSignal)) {
262          marker.delim = simd_andc(simd_andc(lex.HT, escape), marker.quote_mask);
263        }
264        else {
265          marker.delim = simd_andc(simd_andc(lex.Comma, escape), marker.quote_mask);
266        }
267        marker.eol = simd_andc(simd_or(lex.CR, lex.LF), marker.quote_mask);
268        marker.hide = simd_or(marker.quote, simd_andc(simd_and(carryQ.BitBlock_advance_ci_co(lex.CR, carryQ.get_carry_in(3), 3), lex.LF), marker.quote_mask));
269        marker.eol = simd_andc(marker.eol, marker.hide);
270  }
271  void do_segment(Lex lex[], Marker marker[], int segment_blocks) {
272  int i;
273  for (i = 0; i < segment_blocks; i++)
274    do_block(lex[i], marker[i]);
275  }
276  CarryArray<4, 0> carryQ;
277  };
278
279
280
281//////////////////////////////////////////////////////////////////////////////////////////
282// Headers that depend @ global stream struct types.
283//////////////////////////////////////////////////////////////////////////////////////////
284#include "../lib/transpose.hpp"
285#include "../util/csv2xmlwriter.hpp"
286
287static void do_process(FILE *infile, FILE *outfile);
288
289const BitBlock ZERO = convert(0);
290const BitBlock ONE = convert(1);
291const BitBlock HIGH_ONE = bitblock::slli<BLOCK_SIZE-1>(convert(1));
292
293int main(int argc, char * argv[])
294{
295    char infilename[100] = "sample.csv";
296    char outfilename[100] = "sample_xml.txt";
297
298    UseTabSignal = ZERO;
299    if (argc == 3)
300    {
301        strcpy(infilename, argv[1]);
302        strcpy(outfilename, argv[2]);
303    }
304    else if (argc == 4)
305    {
306        if (strcmp(argv[1], "-tab") != 0)
307        {
308            printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
309            return 0;
310        }
311        else
312        {
313            UseTabSignal = ONE;
314            strcpy(infilename, argv[2]);
315            strcpy(outfilename, argv[3]);
316        }
317    }
318    else
319    {
320        printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
321    }
322
323    printf("Process %s as input and %s as output\n", infilename, outfilename);
324
325    FILE *infile = fopen(infilename, "r");
326    FILE *outfile = fopen(outfilename, "w");
327
328    PERF_SEC_BIND(1);
329
330    PERF_SEC_INIT(parser_timer);
331
332    do_process(infile, outfile);
333
334    PERF_SEC_DUMP(parser_timer);
335
336    PERF_SEC_DESTROY(parser_timer);
337
338    fclose(infile);
339    fclose(outfile);
340
341    return(0);
342}
343
344class BufferToXMLParser
345{
346    BitBlockForwardIterator delimIter, eolIter, andIter, hideIter;
347    BitBlockForwardIterator end;
348    uint8_t *src_buffer;
349    Csv2XmlWriter *writer;
350
351public:
352
353    BufferToXMLParser(Marker &marker, Lex &lex, uint8_t *buffer, Csv2XmlWriter *_writer)
354    {
355        delimIter = BitBlockForwardIterator(&marker.delim);
356        eolIter = BitBlockForwardIterator(&marker.eol);
357        andIter = BitBlockForwardIterator(&lex.AndSymbol);
358        hideIter = BitBlockForwardIterator(&marker.hide);
359
360        src_buffer = buffer;
361        writer = _writer;
362    }
363
364    void parseEachRow(int buffer_size)
365    {
366        int pos = 0;
367
368        while (eolIter != end)
369        {
370            parseRowWithoutLastColumn(pos, *eolIter);
371
372            if (pos <= *eolIter)
373            {
374                int length = *eolIter - pos;
375                bufPrintWithAndSymbol(pos, length);
376                writer->nextCol();
377            }
378            pos = *eolIter + 1;
379
380            eolIter ++;
381            writer->nextRow();
382        }
383
384        if (pos <= buffer_size)
385        {
386            //last line within a block
387            parseRowWithoutLastColumn(pos, buffer_size);
388
389            if (pos < buffer_size)
390            {
391                int length = buffer_size - pos;
392                bufPrintWithAndSymbol(pos, length);
393            }
394        }
395    }
396
397private:
398    void parseRowWithoutLastColumn(int &pos, int endofline)
399    {
400        BitBlockForwardIterator end;
401        while ((delimIter != end) && (*delimIter < endofline))
402        {
403            int length = *delimIter - pos;
404            bufPrintWithAndSymbol(pos, length);
405            writer->nextCol();
406            pos = (*delimIter) + 1;
407            delimIter++;
408        }
409    }
410
411    void bufPrintWithAndSymbol(int startPos, int length)
412    {
413        char text[10] = "&amp;";
414
415        if (startPos + length >= BLOCK_SIZE + 1)
416        {
417            printf("bufPrint memory leak!\n");
418            exit(-1);
419        }
420
421        while (length > 0)
422        {
423            while ((andIter != end) && *andIter < startPos) andIter++;
424
425            if (andIter != end && *andIter < startPos + length)
426            {
427                bufPrintWithHideSymbol(startPos, *andIter - startPos);
428                writer->writeColumn(text);
429
430                length -= *andIter - startPos + 1;
431                startPos = *andIter + 1;
432            }
433            else
434            {
435                bufPrintWithHideSymbol(startPos, length);
436                length = 0;
437            }
438        }
439    }
440
441    void bufPrintWithHideSymbol(int startPos, int length)
442    {
443        while (length > 0)
444        {
445            while (hideIter != end && *hideIter < startPos) hideIter++;
446
447            if (hideIter != end && *hideIter < startPos + length)
448            {
449                bufPrintSimple(startPos, *hideIter - startPos);
450                length -= *hideIter - startPos + 1;
451                startPos = *hideIter + 1;
452            }
453            else
454            {
455                bufPrintSimple(startPos, length);
456                length = 0;
457            }
458        }
459    }
460
461    void bufPrintSimple(int startPos, int length)
462    {
463        uint8_t *p = src_buffer + startPos;
464        uint8_t temp = p[length];
465        p[length] = 0;
466        writer->writeColumn((char *)p);
467        p[length] = temp;
468    }
469};
470
471void do_process(FILE *infile, FILE *outfile) {
472
473      struct Basis_bits basis_bits;
474
475  struct Lex lex;
476
477  struct Marker marker;
478
479
480
481    BitBlock buf[9];//watch out buffer size, may cause memory leak!! shit!!
482
483    uint8_t * src_buffer = (uint8_t *) buf;
484    size_t count;
485
486      Classify_bytes classify_bytes;
487  Parse_marker parse_marker;
488
489
490    Csv2XmlWriter writer(outfile);
491    FlipSignal = ZERO;
492    //if quoted string spanned more than 1 block, next block's FlipSignal should be 1
493
494    while ((count = fread(src_buffer, sizeof(uint8_t), BLOCK_SIZE, infile)) > 0)
495    {
496        PERF_SEC_START(parser_timer);
497
498        if (count < BLOCK_SIZE)
499        {
500            EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-count));
501            s2p_do_final_block((BytePack *) src_buffer, basis_bits, EOF_mask);
502           
503  classify_bytes.do_final_block(basis_bits, lex, EOF_mask);
504  parse_marker.do_final_block(lex, marker, EOF_mask);
505        }
506        else
507        {
508            s2p_do_block((BytePack *) src_buffer, basis_bits);
509           
510  classify_bytes.do_block(basis_bits, lex);
511  parse_marker.do_block(lex, marker);
512        }
513
514        FlipSignal = ZERO;
515        if (bitblock::any(simd_and(marker.quote_mask, HIGH_ONE)))
516        {
517            FlipSignal = ONE;
518        }
519
520        PERF_SEC_END(parser_timer, count);
521
522        BufferToXMLParser bufParser(marker, lex, src_buffer, &writer);
523        bufParser.parseEachRow(count);
524    }
525}
Note: See TracBrowser for help on using the repository browser.