source: proto/CSV/csv2xml/src/csv.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: 18.3 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  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
128        temp1 = simd_andc(basis_bits.bit_1, basis_bits.bit_0);
129        temp2 = simd_andc(basis_bits.bit_3, basis_bits.bit_2);
130        temp3 = simd_and(temp1, temp2);
131        temp4 = simd_and(basis_bits.bit_4, basis_bits.bit_5);
132        temp5 = simd_or(basis_bits.bit_6, basis_bits.bit_7);
133        temp6 = simd_andc(temp4, temp5);
134        lex.BackSlash = simd_and(temp3, temp6);
135        temp7 = simd_or(basis_bits.bit_0, basis_bits.bit_1);
136        temp8 = simd_andc(basis_bits.bit_2, basis_bits.bit_3);
137        temp9 = simd_andc(temp8, temp7);
138        temp10 = simd_or(basis_bits.bit_4, basis_bits.bit_5);
139        temp11 = simd_andc(basis_bits.bit_6, basis_bits.bit_7);
140        temp12 = simd_andc(temp11, temp10);
141        lex.DQuote = simd_and(temp9, temp12);
142        temp13 = simd_andc(basis_bits.bit_5, basis_bits.bit_4);
143        temp14 = simd_and(basis_bits.bit_6, basis_bits.bit_7);
144        temp15 = simd_and(temp13, temp14);
145        lex.SQuote = simd_and(temp9, temp15);
146        temp16 = simd_or(basis_bits.bit_2, basis_bits.bit_3);
147        temp17 = simd_or(temp7, temp16);
148        temp18 = simd_andc(basis_bits.bit_7, basis_bits.bit_6);
149        temp19 = simd_and(temp4, temp18);
150        lex.CR = simd_andc(temp19, temp17);
151        temp20 = simd_andc(basis_bits.bit_4, basis_bits.bit_5);
152        temp21 = simd_and(temp20, temp11);
153        lex.LF = simd_andc(temp21, temp17);
154        lex.Comma = simd_and(temp9, temp6);
155        temp22 = simd_and(temp20, temp18);
156        lex.HT = simd_andc(temp22, temp17);
157        temp23 = simd_and(temp4, temp11);
158        lex.Period = simd_and(temp9, temp23);
159        temp24 = simd_and(temp13, temp11);
160        lex.AndSymbol = simd_and(temp9, temp24);
161  }
162  void do_final_block(Basis_bits & basis_bits, Lex & lex, BitBlock EOF_mask) {
163                BitBlock temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10;
164                BitBlock temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18;
165                BitBlock temp19, temp20, temp21, temp22, temp23, temp24;
166
167
168
169        temp1 = simd_andc(basis_bits.bit_1, basis_bits.bit_0);
170        temp2 = simd_andc(basis_bits.bit_3, basis_bits.bit_2);
171        temp3 = simd_and(temp1, temp2);
172        temp4 = simd_and(basis_bits.bit_4, basis_bits.bit_5);
173        temp5 = simd_or(basis_bits.bit_6, basis_bits.bit_7);
174        temp6 = simd_andc(temp4, temp5);
175        lex.BackSlash = simd_and(temp3, temp6);
176        temp7 = simd_or(basis_bits.bit_0, basis_bits.bit_1);
177        temp8 = simd_andc(basis_bits.bit_2, basis_bits.bit_3);
178        temp9 = simd_andc(temp8, temp7);
179        temp10 = simd_or(basis_bits.bit_4, basis_bits.bit_5);
180        temp11 = simd_andc(basis_bits.bit_6, basis_bits.bit_7);
181        temp12 = simd_andc(temp11, temp10);
182        lex.DQuote = simd_and(temp9, temp12);
183        temp13 = simd_andc(basis_bits.bit_5, basis_bits.bit_4);
184        temp14 = simd_and(basis_bits.bit_6, basis_bits.bit_7);
185        temp15 = simd_and(temp13, temp14);
186        lex.SQuote = simd_and(temp9, temp15);
187        temp16 = simd_or(basis_bits.bit_2, basis_bits.bit_3);
188        temp17 = simd_or(temp7, temp16);
189        temp18 = simd_andc(basis_bits.bit_7, basis_bits.bit_6);
190        temp19 = simd_and(temp4, temp18);
191        lex.CR = simd_andc(temp19, temp17);
192        temp20 = simd_andc(basis_bits.bit_4, basis_bits.bit_5);
193        temp21 = simd_and(temp20, temp11);
194        lex.LF = simd_andc(temp21, temp17);
195        lex.Comma = simd_and(temp9, temp6);
196        temp22 = simd_and(temp20, temp18);
197        lex.HT = simd_andc(temp22, temp17);
198        temp23 = simd_and(temp4, temp11);
199        lex.Period = simd_and(temp9, temp23);
200        temp24 = simd_and(temp13, temp11);
201        lex.AndSymbol = simd_and(temp9, temp24);
202  }
203  void do_segment(Basis_bits basis_bits[], Lex lex[], int segment_blocks) {
204  int i;
205  for (i = 0; i < segment_blocks; i++)
206    do_block(basis_bits[i], lex[i]);
207  }
208 
209  };
210
211  struct Parse_marker {
212  Parse_marker() { 
213 }
214  IDISA_INLINE void do_block(Lex & lex, Marker & marker) {
215                BitBlock odd, even, start, even_start, even_final, escape, odd_start;
216                BitBlock odd_final;
217                BitBlock tempvar0, tempvar1;
218
219
220        odd = Simd_const_odd;
221        even = Simd_const_even;
222        tempvar0 = carryQ.BitBlock_advance_ci_co(lex.BackSlash, carryQ.get_carry_in(0), 0);
223        start = simd_andc(lex.BackSlash, tempvar0);
224        even_start = simd_and(start, even);
225        even_final = carryQ.BitBlock_scanthru_ci_co(even_start, lex.BackSlash, carryQ.get_carry_in(1), 1);
226        escape = simd_and(even_final, odd);
227        odd_start = simd_and(start, odd);
228        odd_final = carryQ.BitBlock_scanthru_ci_co(odd_start, lex.BackSlash, carryQ.get_carry_in(2), 2);
229        marker.escape = simd_or(escape, simd_and(odd_final, even));
230        marker.quote = simd_andc(lex.DQuote, marker.escape);
231        marker.quote_mask = parse_quote_mask(marker.quote);
232        if (bitblock::any(FlipSignal)) {
233          marker.quote_mask = simd_not(marker.quote_mask);
234        }
235        if (bitblock::any(UseTabSignal)) {
236          marker.delim = simd_andc(simd_andc(lex.HT, escape), marker.quote_mask);
237        }
238        else {
239          marker.delim = simd_andc(simd_andc(lex.Comma, escape), marker.quote_mask);
240        }
241        marker.eol = simd_andc(simd_or(lex.CR, lex.LF), marker.quote_mask);
242        tempvar1 = carryQ.BitBlock_advance_ci_co(lex.CR, carryQ.get_carry_in(3), 3);
243        marker.hide = simd_or(marker.quote, simd_andc(simd_and(tempvar1, lex.LF), marker.quote_mask));
244        marker.eol = simd_andc(marker.eol, marker.hide);
245        carryQ.CarryQ_Adjust(4);
246  }
247  void do_final_block(Lex & lex, Marker & marker, BitBlock EOF_mask) {
248                BitBlock odd, even, start, even_start, even_final, escape, odd_start;
249                BitBlock odd_final;
250                BitBlock tempvar0, tempvar1;
251
252
253        odd = Simd_const_odd;
254        even = Simd_const_even;
255        tempvar0 = carryQ.BitBlock_advance_ci_co(lex.BackSlash, carryQ.get_carry_in(0), 0);
256        start = simd_andc(lex.BackSlash, tempvar0);
257        even_start = simd_and(start, even);
258        even_final = carryQ.BitBlock_scanthru_ci_co(even_start, lex.BackSlash, carryQ.get_carry_in(1), 1);
259        escape = simd_and(even_final, odd);
260        odd_start = simd_and(start, odd);
261        odd_final = carryQ.BitBlock_scanthru_ci_co(odd_start, lex.BackSlash, carryQ.get_carry_in(2), 2);
262        marker.escape = simd_or(escape, simd_and(odd_final, even));
263        marker.quote = simd_andc(lex.DQuote, marker.escape);
264        marker.quote_mask = parse_quote_mask(marker.quote);
265        if (bitblock::any(FlipSignal)) {
266          marker.quote_mask = simd_not(marker.quote_mask);
267        }
268        if (bitblock::any(UseTabSignal)) {
269          marker.delim = simd_andc(simd_andc(lex.HT, escape), marker.quote_mask);
270        }
271        else {
272          marker.delim = simd_andc(simd_andc(lex.Comma, escape), marker.quote_mask);
273        }
274        marker.eol = simd_andc(simd_or(lex.CR, lex.LF), marker.quote_mask);
275        tempvar1 = carryQ.BitBlock_advance_ci_co(lex.CR, carryQ.get_carry_in(3), 3);
276        marker.hide = simd_or(marker.quote, simd_andc(simd_and(tempvar1, lex.LF), marker.quote_mask));
277        marker.eol = simd_andc(marker.eol, marker.hide);
278  }
279  void do_segment(Lex lex[], Marker marker[], int segment_blocks) {
280  int i;
281  for (i = 0; i < segment_blocks; i++)
282    do_block(lex[i], marker[i]);
283  }
284  CarryArray<4, 0> carryQ;
285  };
286
287
288
289//////////////////////////////////////////////////////////////////////////////////////////
290// Headers that depend @ global stream struct types.
291//////////////////////////////////////////////////////////////////////////////////////////
292#include "../lib/transpose.hpp"
293#include "../util/csv2xmlwriter.hpp"
294#include "../util/bitsegment_iterator.hpp"
295
296static void do_process(FILE *infile, FILE *outfile);
297
298const BitBlock ZERO = convert(0);
299const BitBlock ONE = convert(1);
300const BitBlock HIGH_ONE = bitblock::slli<BLOCK_SIZE-1>(convert(1));
301
302int main(int argc, char * argv[])
303{
304    char infilename[100] = "sample.csv";
305    char outfilename[100] = "sample_xml.txt";
306
307    UseTabSignal = ZERO;
308    if (argc == 3)
309    {
310        strcpy(infilename, argv[1]);
311        strcpy(outfilename, argv[2]);
312    }
313    else if (argc == 4)
314    {
315        if (strcmp(argv[1], "-tab") != 0)
316        {
317            printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
318            return 0;
319        }
320        else
321        {
322            UseTabSignal = ONE;
323            strcpy(infilename, argv[2]);
324            strcpy(outfilename, argv[3]);
325        }
326    }
327    else
328    {
329        printf("Usage: %s [-tab] [infile] [outfile]\n", argv[0]);
330    }
331
332    printf("Process %s as input and %s as output\n", infilename, outfilename);
333
334    FILE *infile = fopen(infilename, "rb");
335    FILE *outfile = fopen(outfilename, "wb");
336    setbuf(outfile, NULL); //shutdown default buffer system
337    // printf("setvbuf = %d\n", setvbuf(outfile, NULL, _IOFBF, SEGMENT_SIZE * 16));
338
339    PERF_SEC_BIND(1);
340
341    PERF_SEC_INIT(parser_timer);
342
343    do_process(infile, outfile);
344
345    PERF_SEC_DUMP(parser_timer);
346
347    PERF_SEC_DESTROY(parser_timer);
348
349    fclose(infile);
350    fclose(outfile);
351
352    return(0);
353}
354
355class IteratorPackage
356{
357public:
358    BitSegment<SEGMENT_BLOCKS> delimSeg, eolSeg, andSeg, hideSeg;
359
360    IteratorPackage()
361    {
362        init();
363    }
364
365    void init()
366    {
367        delimSeg.clear();
368        eolSeg.clear();
369        andSeg.clear();
370        hideSeg.clear();
371    }
372
373    void append(Marker &marker, Lex &lex)
374    {
375        delimSeg.append(marker.delim);
376        eolSeg.append(marker.eol);
377        andSeg.append(lex.AndSymbol);
378        hideSeg.append(marker.hide);
379    }
380};
381
382class BufferToXMLParser
383{
384    BitSegmentForwardIterator delimIter, eolIter, andIter, hideIter;
385    uint8_t *src_buffer;
386    Csv2XmlWriter *writer;
387    IteratorPackage *package;
388
389public:
390
391    BufferToXMLParser(uint8_t *buffer, Csv2XmlWriter *_writer, IteratorPackage *_package, int n)
392        : delimIter(_package->delimSeg.address(), n), eolIter(_package->eolSeg.address(), n),
393            andIter(_package->andSeg.address(), n), hideIter(_package->hideSeg.address(), n)
394    {
395        src_buffer = buffer;
396        writer = _writer;
397        package = _package;
398    }
399
400    void parseEachRow(int buffer_size)
401    {
402        int pos = 0;
403
404        while (!eolIter.is_end())
405        {
406            parseRowWithoutLastColumn(pos, *eolIter);
407
408            if (pos <= *eolIter)
409            {
410                int length = *eolIter - pos;
411                bufPrintWithAndSymbol(pos, length);
412                writer->nextCol();
413            }
414            pos = *eolIter + 1;
415
416            ++ eolIter;
417            writer->nextRow();
418        }
419
420        if (pos <= buffer_size)
421        {
422            //last line within a block
423            parseRowWithoutLastColumn(pos, buffer_size);
424
425            if (pos < buffer_size)
426            {
427                int length = buffer_size - pos;
428                bufPrintWithAndSymbol(pos, length);
429            }
430        }
431    }
432
433private:
434    void parseRowWithoutLastColumn(int &pos, int endofline)
435    {
436        while ((!delimIter.is_end()) && (*delimIter < endofline))
437        {
438            int length = *delimIter - pos;
439            bufPrintWithAndSymbol(pos, length);
440            writer->nextCol();
441            pos = (*delimIter) + 1;
442            ++delimIter;
443        }
444    }
445
446    void bufPrintWithAndSymbol(int startPos, int length)
447    {
448        char text[10] = "&amp;";
449
450        while (length > 0)
451        {
452            while ((!andIter.is_end()) && *andIter < startPos) ++andIter;
453
454            if (!andIter.is_end() && *andIter < startPos + length)
455            {
456                bufPrintWithHideSymbol(startPos, *andIter - startPos);
457                writer->writeColumn(text, 5);
458
459                length -= *andIter - startPos + 1;
460                startPos = *andIter + 1;
461            }
462            else
463            {
464                bufPrintWithHideSymbol(startPos, length);
465                length = 0;
466            }
467        }
468    }
469
470    void bufPrintWithHideSymbol(int startPos, int length)
471    {
472        while (length > 0)
473        {
474            while (!hideIter.is_end() && *hideIter < startPos) ++hideIter;
475
476            if (!hideIter.is_end() && *hideIter < startPos + length)
477            {
478                bufPrintSimple(startPos, *hideIter - startPos);
479                length -= *hideIter - startPos + 1;
480                startPos = *hideIter + 1;
481            }
482            else
483            {
484                bufPrintSimple(startPos, length);
485                length = 0;
486            }
487        }
488    }
489
490    void bufPrintSimple(int startPos, int length)
491    {
492        uint8_t *p = src_buffer + startPos;
493        writer->writeColumn((char *)p, length);
494    }
495};
496
497void do_process(FILE *infile, FILE *outfile) {
498
499      struct Basis_bits basis_bits;
500
501  struct Lex lex;
502
503  struct Marker marker;
504
505;
506
507    BitBlock buf[9];//watch out buffer size, may cause memory leak!! shit!!
508    BitBlock segBuf[9 * SEGMENT_BLOCKS];
509
510    uint8_t * src_buffer = (uint8_t *) buf;
511    uint8_t * seg_buffer = (uint8_t *) segBuf;
512    size_t count;
513
514      Classify_bytes classify_bytes;
515  Parse_marker parse_marker;
516;
517
518    Csv2XmlWriter writer(outfile);
519    FlipSignal = ZERO;
520
521    bool infile_end = false;
522    int segment_count;
523    int segment_blocks;
524    unsigned long long infile_count = 0;
525    IteratorPackage package;
526
527    while (!infile_end)
528    {
529        segment_count = 0;
530        segment_blocks = 0;
531        package.init();
532        PERF_SEC_START(parser_timer);
533
534
535        //if quoted string spanned more than 1 block, next block's FlipSignal should be 1
536        while (segment_blocks < SEGMENT_BLOCKS && (count = fread(src_buffer, sizeof(uint8_t), BLOCK_SIZE, infile)) > 0)
537        {
538            memcpy(seg_buffer + segment_count, src_buffer, count);
539            segment_blocks ++;
540            segment_count += count;
541            infile_count += count;
542
543            if (count < BLOCK_SIZE)
544            {
545                EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-count));
546                s2p_do_final_block((BytePack *) src_buffer, basis_bits, EOF_mask);
547               
548  classify_bytes.do_final_block(basis_bits, lex, EOF_mask);
549  parse_marker.do_final_block(lex, marker, EOF_mask);
550            }
551            else
552            {
553                s2p_do_block((BytePack *) src_buffer, basis_bits);
554               
555  classify_bytes.do_block(basis_bits, lex);
556  parse_marker.do_block(lex, marker);
557                FlipSignal = ZERO;
558                if (bitblock::any(simd_and(marker.quote_mask, HIGH_ONE)))
559                {
560                    FlipSignal = ONE;
561                }
562            }
563
564            package.append(marker, lex);
565        }
566
567        if (segment_count)
568        {
569            BufferToXMLParser bufParser(seg_buffer, &writer, &package, segment_blocks);
570            bufParser.parseEachRow(segment_count);
571            writer.flush();
572
573            PERF_SEC_END(parser_timer, segment_count);
574        }
575
576        if (segment_blocks < SEGMENT_BLOCKS)
577        {
578            infile_end = true;
579        }
580    }
581
582
583    printf("input: %lld\t", infile_count);
584    printf("output: %lld\t", writer._outCount);
585    printf("rate: %lf\n", (double) writer._outCount / (double) infile_count);
586}
Note: See TracBrowser for help on using the repository browser.