Changeset 384 for proto/CSV


Ignore:
Timestamp:
Mar 27, 2010, 2:14:44 PM (9 years ago)
Author:
lindanl
Message:

Direct bit stream generation; Parallel prefix quote mask.

Location:
proto/CSV/postgres
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • proto/CSV/postgres/copy.c

    r383 r384  
    1414 */
    1515 
    16 
     16//#define BITSTREAM
     17#define BUFFER_PROFILING
     18
     19#ifdef BUFFER_PROFILING
     20#include "Profiling/BOM_Profiler.c"
     21BOM_Table * copyloadrawbuf_timer;
     22BOM_Table * bitstreamgen_timer;
     23BOM_Table * readline_timer;
     24BOM_Table * readattr_timer;
     25BOM_Table * userattr_timer;
     26BOM_Table * tupleattr_timer;
     27BOM_Table * loop_timer;
     28BOM_Table * copy_timer;
     29
     30#endif
    1731
    1832#include "postgres.h"
     
    11801194        cstate->copy_dest = COPY_FILE;          /* default */
    11811195        cstate->filename = stmt->filename;
     1196#ifdef BUFFER_PROFILING
     1197  copy_timer = init_BOM_timer(7067652);
     1198  start_BOM_interval(copy_timer);
     1199#endif
    11821200
    11831201        if (is_from)
     
    11851203        else
    11861204                DoCopyTo(cstate);               /* copy from database to file */
    1187 
     1205               
     1206#ifdef BUFFER_PROFILING
     1207    end_BOM_interval(copy_timer);
     1208        fprintf(stderr,"copy_timer!\n");
     1209        dump_BOM_table(copy_timer);
     1210#endif
    11881211        /*
    11891212         * Close the relation or query.  If reading, we can release the
     
    16971720        BulkInsertState bistate;
    16981721
     1722#ifdef BUFFER_PROFILING
     1723  copyloadrawbuf_timer = init_BOM_timer(RAW_BUF_SIZE);
     1724  bitstreamgen_timer = init_BOM_timer(RAW_BUF_SIZE);
     1725  readline_timer = init_BOM_timer(128);
     1726  readattr_timer = init_BOM_timer(128);
     1727  userattr_timer = init_BOM_timer(128);
     1728  tupleattr_timer = init_BOM_timer(128);
     1729  loop_timer = init_BOM_timer(128);
     1730#endif
     1731
    16991732        Assert(cstate->rel);
    17001733
     
    19441977        while (!done)
    19451978        {
     1979#ifdef BUFFER_PROFILING
     1980    start_BOM_interval(loop_timer);
     1981#endif
    19461982                bool            skip_tuple;
    19471983                Oid                     loaded_oid = InvalidOid;
     
    19672003                        int                     fieldno;
    19682004                        char       *string;
    1969 
     2005#ifdef BUFFER_PROFILING
     2006    start_BOM_interval(readline_timer);
     2007#endif
    19702008                        /* Actually read the line into memory here */
    19712009                        done = CopyReadLine(cstate);
    19722010
     2011#ifdef BUFFER_PROFILING
     2012    end_BOM_interval(readline_timer);
     2013#endif
    19732014                        /*
    19742015                         * EOF at start of line means we're done.  If we see EOF after
     
    19782019                        if (done && cstate->line_buf.len == 0)
    19792020                                break;
    1980 
     2021                               
     2022#ifdef BUFFER_PROFILING
     2023    start_BOM_interval(readattr_timer);
     2024#endif
    19812025                        /* Parse the line into de-escaped field values */
    19822026                        if (cstate->csv_mode)
     
    19842028                        else
    19852029                                fldct = CopyReadAttributesText(cstate, nfields, field_strings);
     2030#ifdef BUFFER_PROFILING
     2031    end_BOM_interval(readattr_timer);
     2032#endif                         
     2033
    19862034                        fieldno = 0;
    19872035
     
    20132061                                }
    20142062                        }
    2015 
     2063#ifdef BUFFER_PROFILING
     2064    start_BOM_interval(userattr_timer);
     2065#endif
    20162066                        /* Loop to read the user attributes on the line. */
    20172067                        foreach(cur, cstate->attnumlist)
     
    20452095                                cstate->cur_attval = NULL;
    20462096                        }
    2047 
     2097#ifdef BUFFER_PROFILING
     2098    end_BOM_interval(userattr_timer);
     2099#endif 
    20482100                        Assert(fieldno == nfields);
    20492101                }
     
    21212173                /* Triggers and stuff need to be invoked in query context. */
    21222174                MemoryContextSwitchTo(oldcontext);
     2175#ifdef BUFFER_PROFILING
     2176    start_BOM_interval(tupleattr_timer);
     2177#endif 
    21232178
    21242179                skip_tuple = false;
     
    21662221                        cstate->processed++;
    21672222                }
     2223#ifdef BUFFER_PROFILING
     2224    end_BOM_interval(tupleattr_timer);
     2225#endif 
     2226#ifdef BUFFER_PROFILING
     2227    end_BOM_interval(loop_timer);
     2228#endif 
    21682229        }
    21692230
     
    22112272        if (hi_options & HEAP_INSERT_SKIP_WAL)
    22122273                heap_sync(cstate->rel);
     2274       
     2275#ifdef BUFFER_PROFILING
     2276//  FILE * timerout;
     2277//  timerout = fopen("/home/lindanl/workspace/postgres-csv/installdir/timerout","w");
     2278  fprintf(stderr,"copyloadrawbuf_timer!\n");
     2279  dump_BOM_table(copyloadrawbuf_timer);
     2280  fprintf(stderr,"bitstreamgen_timer!\n");
     2281  dump_BOM_table(bitstreamgen_timer);
     2282  fprintf(stderr,"readline_timer!\n");
     2283  dump_BOM_table(readline_timer);
     2284  fprintf(stderr,"readattr_timer!\n");
     2285  dump_BOM_table(readattr_timer);
     2286  fprintf(stderr,"userattr_timer!\n");
     2287  dump_BOM_table(userattr_timer);
     2288//  fclose(timerout);
     2289  fprintf(stderr,"tupleattr_timer!\n");
     2290  dump_BOM_table(tupleattr_timer);
     2291  fprintf(stderr,"loop_timer!\n");
     2292  dump_BOM_table(loop_timer);
     2293#endif
    22132294}
    22142295
     
    23052386        return result;
    23062387}
     2388#ifndef BITSTREAM
    23072389/*
    23082390 * CopyReadLineText - inner loop of CopyReadLine for text mode
    23092391 */
    2310 //static bool
    2311 //CopyReadLineText(CopyState cstate)
    2312 //{
    2313 //      char       *copy_raw_buf;
    2314 //      int                     raw_buf_ptr;
    2315 //      int                     copy_buf_len;
    2316 //      bool            need_data = false;
    2317 //      bool            hit_eof = false;
    2318 //      bool            result = false;
    2319 //      char            mblen_str[2];
    2320 //
    2321 //      /* CSV variables */
    2322 //      bool            first_char_in_line = true;
    2323 //      bool            in_quote = false,
    2324 //                              last_was_esc = false;
    2325 //      char            quotec = '\0';
    2326 //      char            escapec = '\0';
    2327 //
    2328 //      if (cstate->csv_mode)
    2329 //      {
    2330 //              quotec = cstate->quote[0];
    2331 //              escapec = cstate->escape[0];
    2332 //              /* ignore special escape processing if it's the same as quotec */
    2333 //              if (quotec == escapec)
    2334 //                      escapec = '\0';
    2335 //      }
    2336 //
    2337 //      mblen_str[1] = '\0';
    2338 //
    2339 //      /*
    2340 //       * The objective of this loop is to transfer the entire next input line
    2341 //       * into line_buf.  Hence, we only care for detecting newlines (\r and/or
    2342 //       * \n) and the end-of-copy marker (\.).
    2343 //       *
    2344 //       * In CSV mode, \r and \n inside a quoted field are just part of the data
    2345 //       * value and are put in line_buf.  We keep just enough state to know if we
    2346 //       * are currently in a quoted field or not.
    2347 //       *
    2348 //       * These four characters, and the CSV escape and quote characters, are
    2349 //       * assumed the same in frontend and backend encodings.
    2350 //       *
    2351 //       * For speed, we try to move data from raw_buf to line_buf in chunks
    2352 //       * rather than one character at a time.  raw_buf_ptr points to the next
    2353 //       * character to examine; any characters from raw_buf_index to raw_buf_ptr
    2354 //       * have been determined to be part of the line, but not yet transferred to
    2355 //       * line_buf.
    2356 //       *
    2357 //       * For a little extra speed within the loop, we copy raw_buf and
    2358 //       * raw_buf_len into local variables.
    2359 //       */
    2360 //      copy_raw_buf = cstate->raw_buf;
    2361 //      raw_buf_ptr = cstate->raw_buf_index;
    2362 //      copy_buf_len = cstate->raw_buf_len;
    2363 //
    2364 //      for (;;)
    2365 //      {
    2366 //              int                     prev_raw_ptr;
    2367 //              char            c;
    2368 //
    2369 //              /*
    2370 //               * Load more data if needed.  Ideally we would just force four bytes
    2371 //               * of read-ahead and avoid the many calls to
    2372 //               * IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(), but the COPY_OLD_FE protocol
    2373 //               * does not allow us to read too far ahead or we might read into the
    2374 //               * next data, so we read-ahead only as far we know we can.      One
    2375 //               * optimization would be to read-ahead four byte here if
    2376 //               * cstate->copy_dest != COPY_OLD_FE, but it hardly seems worth it,
    2377 //               * considering the size of the buffer.
    2378 //               */
    2379 //              if (raw_buf_ptr >= copy_buf_len || need_data)
    2380 //              {
    2381 //                      REFILL_LINEBUF;
    2382 //
    2383 //                      /*
    2384 //                       * Try to read some more data.  This will certainly reset
    2385 //                       * raw_buf_index to zero, and raw_buf_ptr must go with it.
    2386 //                       */
    2387 //                      if (!CopyLoadRawBuf(cstate))
    2388 //                              hit_eof = true;
    2389 //                      raw_buf_ptr = 0;
    2390 //                      copy_buf_len = cstate->raw_buf_len;
    2391 //
    2392 //                      /*
    2393 //                       * If we are completely out of data, break out of the loop,
    2394 //                       * reporting EOF.
    2395 //                       */
    2396 //                      if (copy_buf_len <= 0)
    2397 //                      {
    2398 //                              result = true;
    2399 //                              break;
    2400 //                      }
    2401 //                      need_data = false;
    2402 //              }
    2403 //
    2404 //              /* OK to fetch a character */
    2405 //              prev_raw_ptr = raw_buf_ptr;
    2406 //              c = copy_raw_buf[raw_buf_ptr++];
    2407 //
    2408 //              if (cstate->csv_mode)
    2409 //              {
    2410 //                      /*
    2411 //                       * If character is '\\' or '\r', we may need to look ahead below.
    2412 //                       * Force fetch of the next character if we don't already have it.
    2413 //                       * We need to do this before changing CSV state, in case one of
    2414 //                       * these characters is also the quote or escape character.
    2415 //                       *
    2416 //                       * Note: old-protocol does not like forced prefetch, but it's OK
    2417 //                       * here since we cannot validly be at EOF.
    2418 //                       */
    2419 //                      if (c == '\\' || c == '\r')
    2420 //                      {
    2421 //                              IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
    2422 //                      }
    2423 //
    2424 //                      /*
    2425 //                       * Dealing with quotes and escapes here is mildly tricky. If the
    2426 //                       * quote char is also the escape char, there's no problem - we
    2427 //                       * just use the char as a toggle. If they are different, we need
    2428 //                       * to ensure that we only take account of an escape inside a
    2429 //                       * quoted field and immediately preceding a quote char, and not
    2430 //                       * the second in a escape-escape sequence.
    2431 //                       */
    2432 //                      if (in_quote && c == escapec)
    2433 //                              last_was_esc = !last_was_esc;
    2434 //                      if (c == quotec && !last_was_esc)
    2435 //                              in_quote = !in_quote;
    2436 //                      if (c != escapec)
    2437 //                              last_was_esc = false;
    2438 //
    2439 //                      /*
    2440 //                       * Updating the line count for embedded CR and/or LF chars is
    2441 //                       * necessarily a little fragile - this test is probably about the
    2442 //                       * best we can do.      (XXX it's arguable whether we should do this
    2443 //                       * at all --- is cur_lineno a physical or logical count?)
    2444 //                       */
    2445 //                      if (in_quote && c == (cstate->eol_type == EOL_NL ? '\n' : '\r'))
    2446 //                              cstate->cur_lineno++;
    2447 //              }
    2448 //
    2449 //              /* Process \r */
    2450 //              if (c == '\r' && (!cstate->csv_mode || !in_quote))
    2451 //              {
    2452 //                      /* Check for \r\n on first line, _and_ handle \r\n. */
    2453 //                      if (cstate->eol_type == EOL_UNKNOWN ||
    2454 //                              cstate->eol_type == EOL_CRNL)
    2455 //                      {
    2456 //                              /*
    2457 //                               * If need more data, go back to loop top to load it.
    2458 //                               *
    2459 //                               * Note that if we are at EOF, c will wind up as '\0' because
    2460 //                               * of the guaranteed pad of raw_buf.
    2461 //                               */
    2462 //                              IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
    2463 //
    2464 //                              /* get next char */
    2465 //                              c = copy_raw_buf[raw_buf_ptr];
    2466 //
    2467 //                              if (c == '\n')
    2468 //                              {
    2469 //                                      raw_buf_ptr++;          /* eat newline */
    2470 //                                      cstate->eol_type = EOL_CRNL;            /* in case not set yet */
    2471 //                              }
    2472 //                              else
    2473 //                              {
    2474 //                                      /* found \r, but no \n */
    2475 //                                      if (cstate->eol_type == EOL_CRNL)
    2476 //                                              ereport(ERROR,
    2477 //                                                              (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2478 //                                                               !cstate->csv_mode ?
    2479 //                                                      errmsg("literal carriage return found in data") :
    2480 //                                                      errmsg("unquoted carriage return found in data"),
    2481 //                                                               !cstate->csv_mode ?
    2482 //                                              errhint("Use \"\\r\" to represent carriage return.") :
    2483 //                                                               errhint("Use quoted CSV field to represent carriage return.")));
    2484 //
    2485 //                                      /*
    2486 //                                       * if we got here, it is the first line and we didn't find
    2487 //                                       * \n, so don't consume the peeked character
    2488 //                                       */
    2489 //                                      cstate->eol_type = EOL_CR;
    2490 //                              }
    2491 //                      }
    2492 //                      else if (cstate->eol_type == EOL_NL)
    2493 //                              ereport(ERROR,
    2494 //                                              (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2495 //                                               !cstate->csv_mode ?
    2496 //                                               errmsg("literal carriage return found in data") :
    2497 //                                               errmsg("unquoted carriage return found in data"),
    2498 //                                               !cstate->csv_mode ?
    2499 //                                         errhint("Use \"\\r\" to represent carriage return.") :
    2500 //                                               errhint("Use quoted CSV field to represent carriage return.")));
    2501 //                      /* If reach here, we have found the line terminator */
    2502 //                      break;
    2503 //              }
    2504 //
    2505 //              /* Process \n */
    2506 //              if (c == '\n' && (!cstate->csv_mode || !in_quote))
    2507 //              {
    2508 //                      if (cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL)
    2509 //                              ereport(ERROR,
    2510 //                                              (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2511 //                                               !cstate->csv_mode ?
    2512 //                                               errmsg("literal newline found in data") :
    2513 //                                               errmsg("unquoted newline found in data"),
    2514 //                                               !cstate->csv_mode ?
    2515 //                                               errhint("Use \"\\n\" to represent newline.") :
    2516 //                                       errhint("Use quoted CSV field to represent newline.")));
    2517 //                      cstate->eol_type = EOL_NL;      /* in case not set yet */
    2518 //                      /* If reach here, we have found the line terminator */
    2519 //                      break;
    2520 //              }
    2521 //
    2522 //              /*
    2523 //               * In CSV mode, we only recognize \. alone on a line.  This is because
    2524 //               * \. is a valid CSV data value.
    2525 //               */
    2526 //              if (c == '\\' && (!cstate->csv_mode || first_char_in_line))
    2527 //              {
    2528 //                      char            c2;
    2529 //
    2530 //                      IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
    2531 //                      IF_NEED_REFILL_AND_EOF_BREAK(0);
    2532 //
    2533 //                      /* -----
    2534 //                       * get next character
    2535 //                       * Note: we do not change c so if it isn't \., we can fall
    2536 //                       * through and continue processing for client encoding.
    2537 //                       * -----
    2538 //                       */
    2539 //                      c2 = copy_raw_buf[raw_buf_ptr];
    2540 //
    2541 //                      if (c2 == '.')
    2542 //                      {
    2543 //                              raw_buf_ptr++;  /* consume the '.' */
    2544 //
    2545 //                              /*
    2546 //                               * Note: if we loop back for more data here, it does not
    2547 //                               * matter that the CSV state change checks are re-executed; we
    2548 //                               * will come back here with no important state changed.
    2549 //                               */
    2550 //                              if (cstate->eol_type == EOL_CRNL)
    2551 //                              {
    2552 //                                      /* Get the next character */
    2553 //                                      IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
    2554 //                                      /* if hit_eof, c2 will become '\0' */
    2555 //                                      c2 = copy_raw_buf[raw_buf_ptr++];
    2556 //
    2557 //                                      if (c2 == '\n')
    2558 //                                      {
    2559 //                                              if (!cstate->csv_mode)
    2560 //                                                      ereport(ERROR,
    2561 //                                                                      (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2562 //                                                                       errmsg("end-of-copy marker does not match previous newline style")));
    2563 //                                              else
    2564 //                                                      NO_END_OF_COPY_GOTO;
    2565 //                                      }
    2566 //                                      else if (c2 != '\r')
    2567 //                                      {
    2568 //                                              if (!cstate->csv_mode)
    2569 //                                                      ereport(ERROR,
    2570 //                                                                      (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2571 //                                                                       errmsg("end-of-copy marker corrupt")));
    2572 //                                              else
    2573 //                                                      NO_END_OF_COPY_GOTO;
    2574 //                                      }
    2575 //                              }
    2576 //
    2577 //                              /* Get the next character */
    2578 //                              IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
    2579 //                              /* if hit_eof, c2 will become '\0' */
    2580 //                              c2 = copy_raw_buf[raw_buf_ptr++];
    2581 //
    2582 //                              if (c2 != '\r' && c2 != '\n')
    2583 //                              {
    2584 //                                      if (!cstate->csv_mode)
    2585 //                                              ereport(ERROR,
    2586 //                                                              (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2587 //                                                               errmsg("end-of-copy marker corrupt")));
    2588 //                                      else
    2589 //                                              NO_END_OF_COPY_GOTO;
    2590 //                              }
    2591 //
    2592 //                              if ((cstate->eol_type == EOL_NL && c2 != '\n') ||
    2593 //                                      (cstate->eol_type == EOL_CRNL && c2 != '\n') ||
    2594 //                                      (cstate->eol_type == EOL_CR && c2 != '\r'))
    2595 //                              {
    2596 //                                      ereport(ERROR,
    2597 //                                                      (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
    2598 //                                                       errmsg("end-of-copy marker does not match previous newline style")));
    2599 //                              }
    2600 //
    2601 //                              /*
    2602 //                               * Transfer only the data before the \. into line_buf, then
    2603 //                               * discard the data and the \. sequence.
    2604 //                               */
    2605 //                              if (prev_raw_ptr > cstate->raw_buf_index)
    2606 //                                      appendBinaryStringInfo(&cstate->line_buf,
    2607 //                                                                       cstate->raw_buf + cstate->raw_buf_index,
    2608 //                                                                         prev_raw_ptr - cstate->raw_buf_index);
    2609 //                              cstate->raw_buf_index = raw_buf_ptr;
    2610 //                              result = true;  /* report EOF */
    2611 //                              break;
    2612 //                      }
    2613 //                      else if (!cstate->csv_mode)
    2614 //
    2615 //                              /*
    2616 //                               * If we are here, it means we found a backslash followed by
    2617 //                               * something other than a period.  In non-CSV mode, anything
    2618 //                               * after a backslash is special, so we skip over that second
    2619 //                               * character too.  If we didn't do that \\. would be
    2620 //                               * considered an eof-of copy, while in non-CVS mode it is a
    2621 //                               * literal backslash followed by a period.      In CSV mode,
    2622 //                               * backslashes are not special, so we want to process the
    2623 //                               * character after the backslash just like a normal character,
    2624 //                               * so we don't increment in those cases.
    2625 //                               */
    2626 //                              raw_buf_ptr++;
    2627 //              }
    2628 //
    2629 //              /*
    2630 //               * This label is for CSV cases where \. appears at the start of a
    2631 //               * line, but there is more text after it, meaning it was a data value.
    2632 //               * We are more strict for \. in CSV mode because \. could be a data
    2633 //               * value, while in non-CSV mode, \. cannot be a data value.
    2634 //               */
    2635 //not_end_of_copy:
    2636 //
    2637 //              /*
    2638 //               * Process all bytes of a multi-byte character as a group.
    2639 //               *
    2640 //               * We only support multi-byte sequences where the first byte has the
    2641 //               * high-bit set, so as an optimization we can avoid this block
    2642 //               * entirely if it is not set.
    2643 //               */
    2644 //              if (cstate->encoding_embeds_ascii && IS_HIGHBIT_SET(c))
    2645 //              {
    2646 //                      int                     mblen;
    2647 //
    2648 //                      mblen_str[0] = c;
    2649 //                      /* All our encodings only read the first byte to get the length */
    2650 //                      mblen = pg_encoding_mblen(cstate->client_encoding, mblen_str);
    2651 //                      IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(mblen - 1);
    2652 //                      IF_NEED_REFILL_AND_EOF_BREAK(mblen - 1);
    2653 //                      raw_buf_ptr += mblen - 1;
    2654 //              }
    2655 //              first_char_in_line = false;
    2656 //      }                                                       /* end of outer loop */
    2657 //
    2658 //      /*
    2659 //       * Transfer any still-uncopied data to line_buf.
    2660 //       */
    2661 //      REFILL_LINEBUF;
    2662 //
    2663 //      return result;
    2664 //}
    2665 
    2666 
    26672392static bool
    26682393CopyReadLineText(CopyState cstate)
     
    26782403        /* CSV variables */
    26792404        bool            first_char_in_line = true;
     2405        bool            in_quote = false,
     2406                                last_was_esc = false;
     2407        char            quotec = '\0';
     2408        char            escapec = '\0';
     2409
     2410        if (cstate->csv_mode)
     2411        {
     2412                quotec = cstate->quote[0];
     2413                escapec = cstate->escape[0];
     2414                /* ignore special escape processing if it's the same as quotec */
     2415                if (quotec == escapec)
     2416                        escapec = '\0';
     2417        }
     2418
     2419        mblen_str[1] = '\0';
     2420
     2421        /*
     2422         * The objective of this loop is to transfer the entire next input line
     2423         * into line_buf.  Hence, we only care for detecting newlines (\r and/or
     2424         * \n) and the end-of-copy marker (\.).
     2425         *
     2426         * In CSV mode, \r and \n inside a quoted field are just part of the data
     2427         * value and are put in line_buf.  We keep just enough state to know if we
     2428         * are currently in a quoted field or not.
     2429         *
     2430         * These four characters, and the CSV escape and quote characters, are
     2431         * assumed the same in frontend and backend encodings.
     2432         *
     2433         * For speed, we try to move data from raw_buf to line_buf in chunks
     2434         * rather than one character at a time.  raw_buf_ptr points to the next
     2435         * character to examine; any characters from raw_buf_index to raw_buf_ptr
     2436         * have been determined to be part of the line, but not yet transferred to
     2437         * line_buf.
     2438         *
     2439         * For a little extra speed within the loop, we copy raw_buf and
     2440         * raw_buf_len into local variables.
     2441         */
     2442        copy_raw_buf = cstate->raw_buf;
     2443        raw_buf_ptr = cstate->raw_buf_index;
     2444        copy_buf_len = cstate->raw_buf_len;
     2445
     2446        for (;;)
     2447        {
     2448                int                     prev_raw_ptr;
     2449                char            c;
     2450
     2451                /*
     2452                 * Load more data if needed.  Ideally we would just force four bytes
     2453                 * of read-ahead and avoid the many calls to
     2454                 * IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(), but the COPY_OLD_FE protocol
     2455                 * does not allow us to read too far ahead or we might read into the
     2456                 * next data, so we read-ahead only as far we know we can.      One
     2457                 * optimization would be to read-ahead four byte here if
     2458                 * cstate->copy_dest != COPY_OLD_FE, but it hardly seems worth it,
     2459                 * considering the size of the buffer.
     2460                 */
     2461                if (raw_buf_ptr >= copy_buf_len || need_data)
     2462                {
     2463                        REFILL_LINEBUF;
     2464
     2465                        /*
     2466                         * Try to read some more data.  This will certainly reset
     2467                         * raw_buf_index to zero, and raw_buf_ptr must go with it.
     2468                         */
     2469                        if (!CopyLoadRawBuf(cstate))
     2470                                hit_eof = true;
     2471                        raw_buf_ptr = 0;
     2472                        copy_buf_len = cstate->raw_buf_len;
     2473
     2474                        /*
     2475                         * If we are completely out of data, break out of the loop,
     2476                         * reporting EOF.
     2477                         */
     2478                        if (copy_buf_len <= 0)
     2479                        {
     2480                                result = true;
     2481                                break;
     2482                        }
     2483                        need_data = false;
     2484                }
     2485
     2486                /* OK to fetch a character */
     2487                prev_raw_ptr = raw_buf_ptr;
     2488                c = copy_raw_buf[raw_buf_ptr++];
     2489
     2490                if (cstate->csv_mode)
     2491                {
     2492                        /*
     2493                         * If character is '\\' or '\r', we may need to look ahead below.
     2494                         * Force fetch of the next character if we don't already have it.
     2495                         * We need to do this before changing CSV state, in case one of
     2496                         * these characters is also the quote or escape character.
     2497                         *
     2498                         * Note: old-protocol does not like forced prefetch, but it's OK
     2499                         * here since we cannot validly be at EOF.
     2500                         */
     2501                        if (c == '\\' || c == '\r')
     2502                        {
     2503                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
     2504                        }
     2505
     2506                        /*
     2507                         * Dealing with quotes and escapes here is mildly tricky. If the
     2508                         * quote char is also the escape char, there's no problem - we
     2509                         * just use the char as a toggle. If they are different, we need
     2510                         * to ensure that we only take account of an escape inside a
     2511                         * quoted field and immediately preceding a quote char, and not
     2512                         * the second in a escape-escape sequence.
     2513                         */
     2514                        if (in_quote && c == escapec)
     2515                                last_was_esc = !last_was_esc;
     2516                        if (c == quotec && !last_was_esc)
     2517                                in_quote = !in_quote;
     2518                        if (c != escapec)
     2519                                last_was_esc = false;
     2520
     2521                        /*
     2522                         * Updating the line count for embedded CR and/or LF chars is
     2523                         * necessarily a little fragile - this test is probably about the
     2524                         * best we can do.      (XXX it's arguable whether we should do this
     2525                         * at all --- is cur_lineno a physical or logical count?)
     2526                         */
     2527                        if (in_quote && c == (cstate->eol_type == EOL_NL ? '\n' : '\r'))
     2528                                cstate->cur_lineno++;
     2529                }
     2530
     2531                /* Process \r */
     2532                if (c == '\r' && (!cstate->csv_mode || !in_quote))
     2533                {
     2534                        /* Check for \r\n on first line, _and_ handle \r\n. */
     2535                        if (cstate->eol_type == EOL_UNKNOWN ||
     2536                                cstate->eol_type == EOL_CRNL)
     2537                        {
     2538                                /*
     2539                                 * If need more data, go back to loop top to load it.
     2540                                 *
     2541                                 * Note that if we are at EOF, c will wind up as '\0' because
     2542                                 * of the guaranteed pad of raw_buf.
     2543                                 */
     2544                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
     2545
     2546                                /* get next char */
     2547                                c = copy_raw_buf[raw_buf_ptr];
     2548
     2549                                if (c == '\n')
     2550                                {
     2551                                        raw_buf_ptr++;          /* eat newline */
     2552                                        cstate->eol_type = EOL_CRNL;            /* in case not set yet */
     2553                                }
     2554                                else
     2555                                {
     2556                                        /* found \r, but no \n */
     2557                                        if (cstate->eol_type == EOL_CRNL)
     2558                                                ereport(ERROR,
     2559                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2560                                                                 !cstate->csv_mode ?
     2561                                                        errmsg("literal carriage return found in data") :
     2562                                                        errmsg("unquoted carriage return found in data"),
     2563                                                                 !cstate->csv_mode ?
     2564                                                errhint("Use \"\\r\" to represent carriage return.") :
     2565                                                                 errhint("Use quoted CSV field to represent carriage return.")));
     2566
     2567                                        /*
     2568                                         * if we got here, it is the first line and we didn't find
     2569                                         * \n, so don't consume the peeked character
     2570                                         */
     2571                                        cstate->eol_type = EOL_CR;
     2572                                }
     2573                        }
     2574                        else if (cstate->eol_type == EOL_NL)
     2575                                ereport(ERROR,
     2576                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2577                                                 !cstate->csv_mode ?
     2578                                                 errmsg("literal carriage return found in data") :
     2579                                                 errmsg("unquoted carriage return found in data"),
     2580                                                 !cstate->csv_mode ?
     2581                                           errhint("Use \"\\r\" to represent carriage return.") :
     2582                                                 errhint("Use quoted CSV field to represent carriage return.")));
     2583                        /* If reach here, we have found the line terminator */
     2584                        break;
     2585                }
     2586
     2587                /* Process \n */
     2588                if (c == '\n' && (!cstate->csv_mode || !in_quote))
     2589                {
     2590                        if (cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL)
     2591                                ereport(ERROR,
     2592                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2593                                                 !cstate->csv_mode ?
     2594                                                 errmsg("literal newline found in data") :
     2595                                                 errmsg("unquoted newline found in data"),
     2596                                                 !cstate->csv_mode ?
     2597                                                 errhint("Use \"\\n\" to represent newline.") :
     2598                                         errhint("Use quoted CSV field to represent newline.")));
     2599                        cstate->eol_type = EOL_NL;      /* in case not set yet */
     2600                        /* If reach here, we have found the line terminator */
     2601                        break;
     2602                }
     2603
     2604                /*
     2605                 * In CSV mode, we only recognize \. alone on a line.  This is because
     2606                 * \. is a valid CSV data value.
     2607                 */
     2608                if (c == '\\' && (!cstate->csv_mode || first_char_in_line))
     2609                {
     2610                        char            c2;
     2611
     2612                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
     2613                        IF_NEED_REFILL_AND_EOF_BREAK(0);
     2614
     2615                        /* -----
     2616                         * get next character
     2617                         * Note: we do not change c so if it isn't \., we can fall
     2618                         * through and continue processing for client encoding.
     2619                         * -----
     2620                         */
     2621                        c2 = copy_raw_buf[raw_buf_ptr];
     2622
     2623                        if (c2 == '.')
     2624                        {
     2625                                raw_buf_ptr++;  /* consume the '.' */
     2626
     2627                                /*
     2628                                 * Note: if we loop back for more data here, it does not
     2629                                 * matter that the CSV state change checks are re-executed; we
     2630                                 * will come back here with no important state changed.
     2631                                 */
     2632                                if (cstate->eol_type == EOL_CRNL)
     2633                                {
     2634                                        /* Get the next character */
     2635                                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
     2636                                        /* if hit_eof, c2 will become '\0' */
     2637                                        c2 = copy_raw_buf[raw_buf_ptr++];
     2638
     2639                                        if (c2 == '\n')
     2640                                        {
     2641                                                if (!cstate->csv_mode)
     2642                                                        ereport(ERROR,
     2643                                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2644                                                                         errmsg("end-of-copy marker does not match previous newline style")));
     2645                                                else
     2646                                                        NO_END_OF_COPY_GOTO;
     2647                                        }
     2648                                        else if (c2 != '\r')
     2649                                        {
     2650                                                if (!cstate->csv_mode)
     2651                                                        ereport(ERROR,
     2652                                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2653                                                                         errmsg("end-of-copy marker corrupt")));
     2654                                                else
     2655                                                        NO_END_OF_COPY_GOTO;
     2656                                        }
     2657                                }
     2658
     2659                                /* Get the next character */
     2660                                IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0);
     2661                                /* if hit_eof, c2 will become '\0' */
     2662                                c2 = copy_raw_buf[raw_buf_ptr++];
     2663
     2664                                if (c2 != '\r' && c2 != '\n')
     2665                                {
     2666                                        if (!cstate->csv_mode)
     2667                                                ereport(ERROR,
     2668                                                                (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2669                                                                 errmsg("end-of-copy marker corrupt")));
     2670                                        else
     2671                                                NO_END_OF_COPY_GOTO;
     2672                                }
     2673
     2674                                if ((cstate->eol_type == EOL_NL && c2 != '\n') ||
     2675                                        (cstate->eol_type == EOL_CRNL && c2 != '\n') ||
     2676                                        (cstate->eol_type == EOL_CR && c2 != '\r'))
     2677                                {
     2678                                        ereport(ERROR,
     2679                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     2680                                                         errmsg("end-of-copy marker does not match previous newline style")));
     2681                                }
     2682
     2683                                /*
     2684                                 * Transfer only the data before the \. into line_buf, then
     2685                                 * discard the data and the \. sequence.
     2686                                 */
     2687                                if (prev_raw_ptr > cstate->raw_buf_index)
     2688                                        appendBinaryStringInfo(&cstate->line_buf,
     2689                                                                         cstate->raw_buf + cstate->raw_buf_index,
     2690                                                                           prev_raw_ptr - cstate->raw_buf_index);
     2691                                cstate->raw_buf_index = raw_buf_ptr;
     2692                                result = true;  /* report EOF */
     2693                                break;
     2694                        }
     2695                        else if (!cstate->csv_mode)
     2696
     2697                                /*
     2698                                 * If we are here, it means we found a backslash followed by
     2699                                 * something other than a period.  In non-CSV mode, anything
     2700                                 * after a backslash is special, so we skip over that second
     2701                                 * character too.  If we didn't do that \\. would be
     2702                                 * considered an eof-of copy, while in non-CVS mode it is a
     2703                                 * literal backslash followed by a period.      In CSV mode,
     2704                                 * backslashes are not special, so we want to process the
     2705                                 * character after the backslash just like a normal character,
     2706                                 * so we don't increment in those cases.
     2707                                 */
     2708                                raw_buf_ptr++;
     2709                }
     2710
     2711                /*
     2712                 * This label is for CSV cases where \. appears at the start of a
     2713                 * line, but there is more text after it, meaning it was a data value.
     2714                 * We are more strict for \. in CSV mode because \. could be a data
     2715                 * value, while in non-CSV mode, \. cannot be a data value.
     2716                 */
     2717not_end_of_copy:
     2718
     2719                /*
     2720                 * Process all bytes of a multi-byte character as a group.
     2721                 *
     2722                 * We only support multi-byte sequences where the first byte has the
     2723                 * high-bit set, so as an optimization we can avoid this block
     2724                 * entirely if it is not set.
     2725                 */
     2726                if (cstate->encoding_embeds_ascii && IS_HIGHBIT_SET(c))
     2727                {
     2728                        int                     mblen;
     2729
     2730                        mblen_str[0] = c;
     2731                        /* All our encodings only read the first byte to get the length */
     2732                        mblen = pg_encoding_mblen(cstate->client_encoding, mblen_str);
     2733                        IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(mblen - 1);
     2734                        IF_NEED_REFILL_AND_EOF_BREAK(mblen - 1);
     2735                        raw_buf_ptr += mblen - 1;
     2736                }
     2737                first_char_in_line = false;
     2738        }                                                       /* end of outer loop */
     2739
     2740        /*
     2741         * Transfer any still-uncopied data to line_buf.
     2742         */
     2743        REFILL_LINEBUF;
     2744
     2745        return result;
     2746}
     2747#endif
     2748#ifdef BITSTREAM
     2749static bool
     2750CopyReadLineText(CopyState cstate)
     2751{
     2752        char       *copy_raw_buf;
     2753        int                     raw_buf_ptr;
     2754        int                     copy_buf_len;
     2755        bool            need_data = false;
     2756        bool            hit_eof = false;
     2757        bool            result = false;
     2758        char            mblen_str[2];
     2759
     2760        /* CSV variables */
     2761        bool            first_char_in_line = true;
    26802762        char            c,c2;
    26812763       
     
    26972779                                raw_buf_ptr = copy_buf_len;
    26982780                                c = copy_raw_buf[raw_buf_ptr-1];
     2781#ifdef BUFFER_PROFILING
     2782    start_BOM_interval(copyloadrawbuf_timer);
     2783#endif
    26992784                                if (!CopyLoadRawBuf(cstate))
    27002785                                        cstate->fe_eof = true;
     2786#ifdef BUFFER_PROFILING
     2787    if (!cstate->fe_eof) end_BOM_interval(copyloadrawbuf_timer);
     2788#endif
     2789#ifdef BUFFER_PROFILING
     2790    start_BOM_interval(bitstreamgen_timer);
     2791#endif                                 
     2792
     2793                                if(cstate->quote[0]==cstate->escape[0])
     2794                                        direct_bitstream_gen(cstate);
     2795                                else
     2796                                        direct_bitstream_gen_with_escape(cstate);
    27012797                                       
    2702                                 bitstream_gen(cstate);
    2703 //                              if(cstate->quote[0]==cstate->escape[0])
    2704 //                                      bitstream_gen(cstate);
    2705 //                              else
    2706 //                                      bitstream_gen2(cstate);
     2798#ifdef BUFFER_PROFILING
     2799    if (!cstate->fe_eof) end_BOM_interval(bitstreamgen_timer);
     2800#endif
    27072801                                raw_buf_ptr = 0;
    2708                                 copy_buf_len = cstate->raw_buf_len;
    2709        
     2802                                copy_buf_len = cstate->raw_buf_len;     
    27102803                        }
    27112804                        if(bitblock_has_bit(cstate->EOL_stream[raw_buf_ptr/BLOCK_SIZE_BITS])){
     
    27182811                        }
    27192812                }
    2720                
    2721                 raw_buf_ptr = raw_buf_ptr/BLOCK_SIZE_BITS*BLOCK_SIZE_BITS + count_forward_zeroes(cstate->EOL_stream[raw_buf_ptr/BLOCK_SIZE_BITS]);
    2722                 cstate->EOL_stream[raw_buf_ptr/BLOCK_SIZE_BITS] = simd_and(cstate->EOL_stream[raw_buf_ptr/BLOCK_SIZE_BITS],simd_sll_128(simd_const_1(1),sisd_from_int(raw_buf_ptr%BLOCK_SIZE_BITS+1)));
     2813                int stream_index = raw_buf_ptr/BLOCK_SIZE_BITS;
     2814                raw_buf_ptr = stream_index*BLOCK_SIZE_BITS + count_forward_zeroes(cstate->EOL_stream[stream_index]);
     2815                cstate->EOL_stream[stream_index] = simd_and(cstate->EOL_stream[stream_index],simd_sll_128(simd_const_1(1),sisd_from_int(raw_buf_ptr%BLOCK_SIZE_BITS+1)));
    27232816               
    27242817                if(raw_buf_ptr!=0){
     
    30023095        return result;
    30033096}
     3097#endif
    30043098/*
    30053099 *      Return decimal value for a hexadecimal digit
     
    32453339 * "standard" (i.e. common) CSV usage.
    32463340 */
     3341
     3342#ifndef BITSTREAM
    32473343static int
    32483344CopyReadAttributesCSV(CopyState cstate, int maxfields, char **fieldvals)
     
    34073503        return fieldno;
    34083504}
    3409 
     3505#endif
     3506
     3507#ifdef BITSTREAM
     3508static int
     3509CopyReadAttributesCSV(CopyState cstate, int maxfields, char **fieldvals)
     3510{
     3511        char            delimc = cstate->delim[0];
     3512        char            quotec = cstate->quote[0];
     3513        char            escapec = cstate->escape[0];
     3514        int                     fieldno;
     3515        char       *output_ptr;
     3516        char       *cur_ptr;
     3517        char       *line_end_ptr;
     3518
     3519        /*
     3520         * We need a special case for zero-column tables: check that the input
     3521         * line is empty, and return.
     3522         */
     3523        if (maxfields <= 0)
     3524        {
     3525                if (cstate->line_buf.len != 0)
     3526                        ereport(ERROR,
     3527                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     3528                                         errmsg("extra data after last expected column")));
     3529                return 0;
     3530        }
     3531
     3532        resetStringInfo(&cstate->attribute_buf);
     3533
     3534        /*
     3535         * The de-escaped attributes will certainly not be longer than the input
     3536         * data line, so we can just force attribute_buf to be large enough and
     3537         * then transfer data without any checks for enough space.      We need to do
     3538         * it this way because enlarging attribute_buf mid-stream would invalidate
     3539         * pointers already stored into fieldvals[].
     3540         */
     3541        if (cstate->attribute_buf.maxlen <= cstate->line_buf.len)
     3542                enlargeStringInfo(&cstate->attribute_buf, cstate->line_buf.len);
     3543        output_ptr = cstate->attribute_buf.data;
     3544
     3545        /* set pointer variables for loop */
     3546        cur_ptr = cstate->line_buf.data;
     3547        line_end_ptr = cstate->line_buf.data + cstate->line_buf.len;
     3548
     3549        /* Outer loop iterates over fields */
     3550        fieldno = 0;
     3551        for (;;)
     3552        {
     3553                bool            found_delim = false;
     3554                bool            saw_quote = false;
     3555                char       *start_ptr;
     3556                char       *end_ptr;
     3557                int                     input_len;
     3558
     3559                /* Make sure space remains in fieldvals[] */
     3560                if (fieldno >= maxfields)
     3561                        ereport(ERROR,
     3562                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     3563                                         errmsg("extra data after last expected column")));
     3564
     3565                /* Remember start of field on both input and output sides */
     3566                start_ptr = cur_ptr;
     3567                fieldvals[fieldno] = output_ptr;
     3568
     3569                /*
     3570                 * Scan data for field,
     3571                 *
     3572                 * The loop starts in "not quote" mode and then toggles between that
     3573                 * and "in quote" mode. The loop exits normally if it is in "not
     3574                 * quote" mode and a delimiter or line end is seen.
     3575                 */
     3576                for (;;)
     3577                {
     3578                        char            c;
     3579
     3580                        /* Not in quote */
     3581                        for (;;)
     3582                        {
     3583                                end_ptr = cur_ptr;
     3584                                if (cur_ptr >= line_end_ptr)
     3585                                        goto endfield;
     3586                                c = *cur_ptr++;
     3587                                /* unquoted field delimiter */
     3588                                if (c == delimc)
     3589                                {
     3590                                        found_delim = true;
     3591                                        goto endfield;
     3592                                }
     3593                                /* start of quoted field (or part of field) */
     3594                                if (c == quotec)
     3595                                {
     3596                                        saw_quote = true;
     3597                                        break;
     3598                                }
     3599                                /* Add c to output string */
     3600                                *output_ptr++ = c;
     3601                        }
     3602
     3603                        /* In quote */
     3604                        for (;;)
     3605                        {
     3606                                end_ptr = cur_ptr;
     3607                                if (cur_ptr >= line_end_ptr)
     3608                                        ereport(ERROR,
     3609                                                        (errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
     3610                                                         errmsg("unterminated CSV quoted field")));
     3611
     3612                                c = *cur_ptr++;
     3613
     3614                                /* escape within a quoted field */
     3615                                if (c == escapec)
     3616                                {
     3617                                        /*
     3618                                         * peek at the next char if available, and escape it if it
     3619                                         * is an escape char or a quote char
     3620                                         */
     3621                                        if (cur_ptr < line_end_ptr)
     3622                                        {
     3623                                                char            nextc = *cur_ptr;
     3624
     3625                                                if (nextc == escapec || nextc == quotec)
     3626                                                {
     3627                                                        *output_ptr++ = nextc;
     3628                                                        cur_ptr++;
     3629                                                        continue;
     3630                                                }
     3631                                        }
     3632                                }
     3633
     3634                                /*
     3635                                 * end of quoted field. Must do this test after testing for
     3636                                 * escape in case quote char and escape char are the same
     3637                                 * (which is the common case).
     3638                                 */
     3639                                if (c == quotec)
     3640                                        break;
     3641
     3642                                /* Add c to output string */
     3643                                *output_ptr++ = c;
     3644                        }
     3645                }
     3646endfield:
     3647
     3648                /* Terminate attribute value in output area */
     3649                *output_ptr++ = '\0';
     3650
     3651                /* Check whether raw input matched null marker */
     3652                input_len = end_ptr - start_ptr;
     3653                if (!saw_quote && input_len == cstate->null_print_len &&
     3654                        strncmp(start_ptr, cstate->null_print, input_len) == 0)
     3655                        fieldvals[fieldno] = NULL;
     3656
     3657                fieldno++;
     3658                /* Done if we hit EOL instead of a delim */
     3659                if (!found_delim)
     3660                        break;
     3661        }
     3662
     3663        /* Clean up state of attribute_buf */
     3664        output_ptr--;
     3665        Assert(*output_ptr == '\0');
     3666        cstate->attribute_buf.len = (output_ptr - cstate->attribute_buf.data);
     3667
     3668        return fieldno;
     3669}
     3670#endif
    34103671
    34113672/*
  • proto/CSV/postgres/copy_simd.c

    r383 r384  
    167167}while(0)
    168168
    169 void bitstream_gen2(CopyState cstate) {
    170 
    171 
    172         int carry1=0;
    173         int carry0=0;
    174         int carry3=0;
    175         int carry2=0;
    176         int carry5=0;
    177         int carry4=0;
    178         int carry7=0;
    179         int carry6=0;
    180         int carry5_i=0;
    181         int CarryTemp36=0;
    182         int carry4_i=0;
    183         int carry6_i=0;
    184         int carry3_i=0;
    185         int carry_brw0=0;
    186         BitBlock array_bit__6_;
    187         BitBlock _strct_csvclass__classify_bytes__strct_lex__CR_;
    188         BitBlock quote_end;
    189         BitBlock _strct_csvclass__classify_bytes__strct_lex__Comma_;
    190         BitBlock start;
    191         BitBlock _strct_csvclass__classify_bytes__temp16;
    192         BitBlock _strct_csvclass__classify_bytes__temp17;
    193         BitBlock _strct_csvclass__classify_bytes__temp10;
    194         BitBlock array_bit__2_;
    195         BitBlock _strct_csvclass__classify_bytes__temp12;
    196         BitBlock _strct_csvclass__classify_bytes__temp18;
    197         BitBlock _strct_csvclass__classify_bytes__temp19;
    198         BitBlock _strct_csvclass__classify_bytes__temp11;
    199         BitBlock array_bit__7_;
    200         BitBlock even_start;
    201         BitBlock _strct_csvclass__classify_bytes__temp9;
    202         BitBlock odd_final;
    203         BitBlock quote_mask;
    204         BitBlock escape_0;
    205         BitBlock _strct_csvclass__classify_bytes__temp21;
    206         BitBlock _strct_csvclass__classify_bytes__temp20;
    207         BitBlock array_bit__3_;
    208         BitBlock _strct_csvclass__classify_bytes__strct_lex__BackSlash_;
    209         BitBlock quote_start;
    210         BitBlock _strct_csvclass__classify_bytes__temp6;
    211         BitBlock _strct_csvclass__classify_bytes__temp7;
    212         BitBlock _strct_csvclass__classify_bytes__temp4;
    213         BitBlock _strct_csvclass__classify_bytes__temp5;
    214         BitBlock _strct_csvclass__classify_bytes__temp2;
    215         BitBlock _strct_csvclass__classify_bytes__temp3;
    216         BitBlock _strct_csvclass__classify_bytes__temp1;
    217         BitBlock delim;
    218         BitBlock _strct_csvclass__classify_bytes__temp8;
    219         BitBlock CSV_cursor;
    220         BitBlock Temp17;
    221         BitBlock Temp16;
    222         BitBlock escape;
    223         BitBlock eol;
    224         BitBlock odd;
    225         BitBlock even;
    226         BitBlock array_bit__4_;
    227         BitBlock array_bit__0_;
    228         BitBlock quote;
    229         BitBlock odd_start;
    230         BitBlock array_bit__5_;
    231         BitBlock _strct_csvclass__classify_bytes__strct_lex__DQuote_;
    232         BitBlock AllOne = simd_const_1(1);
    233         BitBlock AllZero = simd_const_1(0);
    234         BitBlock even_final;
    235         BitBlock Temp23;
    236         BitBlock _strct_csvclass__classify_bytes__strct_lex__LF_;
    237         BitBlock Temp24;
    238         BitBlock Temp25;
    239         BitBlock Temp3;
    240         BitBlock Temp2;
    241         BitBlock Temp1;
    242         BitBlock Temp7;
    243         BitBlock Temp4;
    244         BitBlock array_bit__1_;
    245         BitBlock Temp8;
    246 
    247 
    248 
    249         BytePack * U8;
    250 
    251         int block_pos = 0;
    252         int i=0;
    253         int chars_read = 0;
    254        
    255 
    256         U8 = simd_new(8);
    257        
    258         do{
    259                 U8 = (BytePack *)(&(cstate->raw_buf[block_pos]));       
    260                 chars_read = min(cstate->raw_buf_len-block_pos,BLOCK_SIZE_BITS);
    261                 if(chars_read==0)break;
    262                 for (i = chars_read;i < BLOCK_SIZE_BITS; i++) {
    263                         ((char *) U8)[i] = 0;
    264                 }
    265 
    266                 s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
    267                 array_bit__0_,array_bit__1_,array_bit__2_,array_bit__3_,array_bit__4_,array_bit__5_,array_bit__6_,array_bit__7_);
    268                
    269                 odd = simd_const_2(1);
    270                 even = simd_const_2(2);
    271        
    272                 _strct_csvclass__classify_bytes__temp1 = simd_andc(array_bit__1_,array_bit__0_);
    273                 _strct_csvclass__classify_bytes__temp2 = simd_andc(array_bit__3_,array_bit__2_);
    274                 _strct_csvclass__classify_bytes__temp3 = simd_and(_strct_csvclass__classify_bytes__temp1,_strct_csvclass__classify_bytes__temp2);
    275                 _strct_csvclass__classify_bytes__temp4 = simd_and(array_bit__4_,array_bit__5_);
    276                 _strct_csvclass__classify_bytes__temp5 = simd_or(array_bit__6_,array_bit__7_);
    277                 _strct_csvclass__classify_bytes__temp6 = simd_andc(_strct_csvclass__classify_bytes__temp4,_strct_csvclass__classify_bytes__temp5);
    278                 _strct_csvclass__classify_bytes__strct_lex__BackSlash_ = simd_and(_strct_csvclass__classify_bytes__temp3,_strct_csvclass__classify_bytes__temp6);
    279                 _strct_csvclass__classify_bytes__temp7 = simd_or(array_bit__0_,array_bit__1_);
    280                 _strct_csvclass__classify_bytes__temp8 = simd_andc(array_bit__2_,array_bit__3_);
    281                 _strct_csvclass__classify_bytes__temp9 = simd_andc(_strct_csvclass__classify_bytes__temp8,_strct_csvclass__classify_bytes__temp7);
    282                 _strct_csvclass__classify_bytes__temp10 = simd_or(array_bit__4_,array_bit__5_);
    283                 _strct_csvclass__classify_bytes__temp11 = simd_andc(array_bit__6_,array_bit__7_);
    284                 _strct_csvclass__classify_bytes__temp12 = simd_andc(_strct_csvclass__classify_bytes__temp11,_strct_csvclass__classify_bytes__temp10);
    285                 _strct_csvclass__classify_bytes__strct_lex__DQuote_ = simd_and(_strct_csvclass__classify_bytes__temp9,_strct_csvclass__classify_bytes__temp12);
    286                 _strct_csvclass__classify_bytes__temp16 = simd_or(array_bit__2_,array_bit__3_);
    287                 _strct_csvclass__classify_bytes__temp17 = simd_or(_strct_csvclass__classify_bytes__temp7,_strct_csvclass__classify_bytes__temp16);
    288                 _strct_csvclass__classify_bytes__temp18 = simd_andc(array_bit__7_,array_bit__6_);
    289                 _strct_csvclass__classify_bytes__temp19 = simd_and(_strct_csvclass__classify_bytes__temp4,_strct_csvclass__classify_bytes__temp18);
    290                 _strct_csvclass__classify_bytes__strct_lex__CR_ = simd_andc(_strct_csvclass__classify_bytes__temp19,_strct_csvclass__classify_bytes__temp17);
    291                 _strct_csvclass__classify_bytes__temp20 = simd_andc(array_bit__4_,array_bit__5_);
    292                 _strct_csvclass__classify_bytes__temp21 = simd_and(_strct_csvclass__classify_bytes__temp20,_strct_csvclass__classify_bytes__temp11);
    293                 _strct_csvclass__classify_bytes__strct_lex__LF_ = simd_andc(_strct_csvclass__classify_bytes__temp21,_strct_csvclass__classify_bytes__temp17);
    294                 _strct_csvclass__classify_bytes__strct_lex__Comma_ = simd_and(_strct_csvclass__classify_bytes__temp9,_strct_csvclass__classify_bytes__temp6);
    295                 adc128(_strct_csvclass__classify_bytes__strct_lex__BackSlash_, _strct_csvclass__classify_bytes__strct_lex__BackSlash_, carry0, Temp1);
    296                 start = simd_andc(_strct_csvclass__classify_bytes__strct_lex__BackSlash_,Temp1);
    297                 even_start = simd_and(start,even);
    298                 adc128(even_start, _strct_csvclass__classify_bytes__strct_lex__BackSlash_, carry1, Temp2);
    299                 even_final = simd_andc(Temp2,_strct_csvclass__classify_bytes__strct_lex__BackSlash_);
    300                 escape_0 = simd_and(even_final,odd);
    301                 odd_start = simd_and(start,odd);
    302                 adc128(odd_start, _strct_csvclass__classify_bytes__strct_lex__BackSlash_, carry2, Temp3);
    303                 odd_final = simd_andc(Temp3,_strct_csvclass__classify_bytes__strct_lex__BackSlash_);
    304                 Temp4 = simd_and(odd_final,even);
    305                 escape = simd_or(escape_0,Temp4);
    306                 quote = simd_andc(_strct_csvclass__classify_bytes__strct_lex__DQuote_,escape);
    307                 CSV_cursor = sisd_from_int(1);
    308                
    309                 while (bitblock_has_bit(CSV_cursor)|CarryTemp36>0) {
    310                 CarryTemp36 = 0;
    311                 Temp7 = simd_andc(AllOne,quote);
    312                 adc128(CSV_cursor, Temp7, carry3, Temp8);
    313                 CSV_cursor = simd_and(Temp8,quote);
    314                 quote_start = simd_or(quote_start,CSV_cursor);
    315                 adc128(CSV_cursor, CSV_cursor, carry4, CSV_cursor);
    316                 Temp16 = simd_andc(AllOne,quote);
    317                 adc128(CSV_cursor, Temp16, carry5, Temp17);
    318                 CSV_cursor = simd_and(Temp17,quote);
    319                 quote_end = simd_or(quote_end,CSV_cursor);
    320                 adc128(CSV_cursor, CSV_cursor, carry6, CSV_cursor);
    321                 carry3_i = carry3_i|carry3;
    322                 carry4_i = carry4_i|carry4;
    323                 carry5_i = carry5_i|carry5;
    324                 carry6_i = carry6_i|carry6;
    325                 carry3 = 0;
    326                 carry4 = 0;
    327                 carry5 = 0;
    328                 carry6 = 0;
    329                 }
    330                 carry6 = carry6_i;
    331                 carry5 = carry5_i;
    332                 carry4 = carry4_i;
    333                 carry3 = carry3_i;
    334                 carry6_i = 0;
    335                 carry5_i = 0;
    336                 carry4_i = 0;
    337                 carry3_i = 0;
    338                 CarryTemp36 = carry3|carry4;
    339                 CarryTemp36 = CarryTemp36|carry6;
    340                 CarryTemp36 = CarryTemp36|carry5;
    341                 sbb128(quote_end, quote_start, carry_brw0, quote_mask);
    342                 Temp23 = simd_andc(_strct_csvclass__classify_bytes__strct_lex__CR_,quote_mask);
    343                 adc128(Temp23, Temp23, carry7, Temp24);
    344                 Temp25 = simd_andc(_strct_csvclass__classify_bytes__strct_lex__LF_,quote_mask);
    345                 eol = simd_or(Temp24,Temp25);
    346                 delim = simd_andc(_strct_csvclass__classify_bytes__strct_lex__Comma_,quote_mask);
    347 
    348                                
    349                 cstate->EOL_stream[block_pos/BLOCK_SIZE_BITS]=eol;
    350                 cstate->delim_stream[block_pos/BLOCK_SIZE_BITS]=delim;
    351 
    352                 block_pos += chars_read;
    353         }while (chars_read == BLOCK_SIZE_BITS);
    354 }
    355 
     169/*
    356170void bitstream_gen(CopyState cstate) {
    357171
     
    506320                block_pos += chars_read;
    507321        }while (chars_read == BLOCK_SIZE_BITS);
     322}*/
     323/*quote as '\'',escape as '\\'*/
     324void bitstream_gen3(CopyState cstate) {
     325
     326
     327        BitBlock temp1;
     328        BitBlock temp2;
     329        BitBlock temp3;
     330        BitBlock temp4;
     331        BitBlock temp5;
     332        BitBlock temp6;
     333        BitBlock temp7;
     334        BitBlock temp8;
     335        BitBlock temp9;
     336        BitBlock temp10;
     337        BitBlock temp11;
     338        BitBlock temp12;
     339        BitBlock temp13;
     340        BitBlock temp14;
     341        BitBlock temp15;
     342        BitBlock temp16;
     343        BitBlock temp17;
     344        BitBlock temp18;
     345        BitBlock temp19;
     346        BitBlock temp20;
     347        BitBlock temp21;
     348        BitBlock temp22;
     349        BitBlock temp23;
     350        BitBlock temp24;
     351        BitBlock temp25;
     352       
     353        BitBlock CR;
     354        BitBlock LF;
     355        BitBlock Comma;
     356        BitBlock DQuote;
     357        BitBlock SQuote;
     358        BitBlock HT;
     359        BitBlock EOL;
     360        BitBlock Delim;
     361       
     362        BitBlock p2;
     363        BitBlock p4;   
     364        BitBlock p8;
     365        BitBlock p16;
     366        BitBlock p32;
     367        BitBlock p64;
     368        BitBlock quote_mask;
     369        BitBlock BackSlash;
     370        BitBlock quote_base;
     371
     372        BytePack * U8;
     373        BitBlock * bit;
     374
     375        int block_pos = 0;
     376        int i=0;
     377        int chars_read = 0;
     378       
     379
     380        quote_base = simd_const_8(0);
     381
     382        U8 = simd_new(8);
     383        bit = simd_new(8);
     384        do{
     385                U8 = (BytePack *)(&(cstate->raw_buf[block_pos]));       
     386                chars_read = min(cstate->raw_buf_len-block_pos,BLOCK_SIZE_BITS);
     387                if(chars_read==0)break;
     388                for (i = chars_read;i < BLOCK_SIZE_BITS; i++) {
     389                        ((char *) U8)[i] = 0;
     390                }
     391
     392                s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
     393                bit[0],bit[1],bit[2],bit[3],bit[4],bit[5],bit[6],bit[7]);
     394               
     395
     396                temp1 = simd_andc(bit[1], bit[0]);
     397                temp2 = simd_andc(bit[3], bit[2]);
     398                temp3 = simd_and(temp1, temp2);
     399                temp4 = simd_and(bit[4], bit[5]);
     400                temp5 = simd_or(bit[6], bit[7]);
     401                temp6 = simd_andc(temp4, temp5);
     402                BackSlash = simd_and(temp3, temp6);
     403                temp7 = simd_or(bit[0], bit[1]);
     404                temp8 = simd_andc(bit[2], bit[3]);
     405                temp9 = simd_andc(temp8, temp7);
     406                temp10 = simd_or(bit[4], bit[5]);
     407                temp11 = simd_andc(bit[6], bit[7]);
     408                temp12 = simd_andc(temp11, temp10);
     409                DQuote = simd_and(temp9, temp12);
     410                temp13 = simd_andc(bit[5], bit[4]);
     411                temp14 = simd_and(bit[6], bit[7]);
     412                temp15 = simd_and(temp13, temp14);
     413                SQuote = simd_and(temp9, temp15);
     414                temp16 = simd_or(bit[2], bit[3]);
     415                temp17 = simd_or(temp7, temp16);
     416                temp18 = simd_andc(bit[7], bit[6]);
     417                temp19 = simd_and(temp4, temp18);
     418                CR = simd_andc(temp19, temp17);
     419                temp20 = simd_andc(bit[4], bit[5]);
     420                temp21 = simd_and(temp20, temp11);
     421                LF = simd_andc(temp21, temp17);
     422                Comma = simd_and(temp9, temp6);
     423                temp22 = simd_and(temp20, temp18);
     424                HT = simd_andc(temp22, temp17);
     425               
     426                int carry0=0;
     427                int carry1=0;
     428                int carry2=0;
     429                BitBlock even;
     430                BitBlock odd;
     431                BitBlock start;
     432                BitBlock even_start;
     433                BitBlock even_final;
     434                BitBlock odd_start;
     435                BitBlock odd_final;
     436                BitBlock escape;
     437
     438                odd = simd_const_2(1);
     439                even = simd_const_2(2);
     440
     441                adc128(BackSlash,BackSlash,carry0,temp23);
     442                start = simd_andc(BackSlash,temp23);
     443                even_start = simd_and(start,even);
     444                adc128(even_start, BackSlash, carry1, temp24);
     445                even_final = simd_andc(temp24,BackSlash);
     446                escape = simd_and(even_final,odd);
     447               
     448                odd_start = simd_and(start,odd);
     449                adc128(odd_start, BackSlash, carry2, temp25);
     450                odd_final = simd_andc(temp25,BackSlash);
     451                escape = simd_or(escape, simd_and(odd_final,even));
     452       
     453                SQuote = simd_andc(SQuote,escape);
     454
     455                p2 = simd_xor(SQuote,simd_slli_128(SQuote,1));
     456                p4 = simd_xor(p2,simd_slli_128(p2,2));
     457                p8 = simd_xor(p4,simd_slli_128(p4,4));
     458                p16 = simd_xor(p8,simd_slli_128(p8,8));
     459                p32 = simd_xor(p16,simd_slli_128(p16,16));
     460                p64 = simd_xor(p32,simd_slli_128(p32,32));
     461                quote_mask = simd_xor(p64,simd_slli_128(p64,64));
     462                quote_mask = simd_xor(quote_base,quote_mask);
     463                quote_base = simd_shufflei_32(simd_srai_32(quote_mask,31),0xFF);
     464
     465
     466                Delim = simd_andc(Comma,quote_mask);
     467                EOL =  simd_andc(simd_or(simd_slli_128(CR,1),LF),quote_mask);
     468
     469                cstate->EOL_stream[block_pos/BLOCK_SIZE_BITS]=EOL;
     470                cstate->delim_stream[block_pos/BLOCK_SIZE_BITS]=Delim;
     471
     472                block_pos += chars_read;
     473        }while (chars_read == BLOCK_SIZE_BITS);
    508474}
     475/*quote and escape as '\"'*/
     476void bitstream_gen(CopyState cstate) {
     477
     478
     479        BitBlock temp1;
     480        BitBlock temp2;
     481        BitBlock temp3;
     482        BitBlock temp4;
     483        BitBlock temp5;
     484        BitBlock temp6;
     485        BitBlock temp7;
     486        BitBlock temp8;
     487        BitBlock temp9;
     488        BitBlock temp10;
     489        BitBlock temp11;
     490        BitBlock temp12;
     491        BitBlock temp13;
     492        BitBlock temp14;
     493        BitBlock temp15;
     494        BitBlock temp16;
     495        BitBlock temp17;
     496        BitBlock temp18;
     497        BitBlock temp19;
     498        BitBlock temp20;
     499        BitBlock temp21;
     500        BitBlock temp22;
     501       
     502        BitBlock CR;
     503        BitBlock LF;
     504        BitBlock Comma;
     505        BitBlock DQuote;
     506        BitBlock SQuote;
     507        BitBlock HT;
     508        BitBlock EOL;
     509        BitBlock Delim;
     510       
     511        BitBlock p2;
     512        BitBlock p4;   
     513        BitBlock p8;
     514        BitBlock p16;
     515        BitBlock p32;
     516        BitBlock p64;
     517        BitBlock quote_mask;
     518        BitBlock BackSlash;
     519        BitBlock quote_base;
     520
     521        BytePack * U8;
     522        BitBlock * bit;
     523
     524        int block_pos = 0;
     525        int i=0;
     526        int chars_read = 0;
     527       
     528
     529        quote_base = simd_const_8(0);
     530
     531        U8 = simd_new(8);
     532        bit = simd_new(8);
     533        do{
     534                U8 = (BytePack *)(&(cstate->raw_buf[block_pos]));       
     535                chars_read = min(cstate->raw_buf_len-block_pos,BLOCK_SIZE_BITS);
     536                if(chars_read==0)break;
     537                for (i = chars_read;i < BLOCK_SIZE_BITS; i++) {
     538                        ((char *) U8)[i] = 0;
     539                }
     540
     541                s2p_bytepack(U8[7], U8[6], U8[5], U8[4], U8[3], U8[2], U8[1], U8[0],
     542                bit[0],bit[1],bit[2],bit[3],bit[4],bit[5],bit[6],bit[7]);
     543               
     544
     545                temp1 = simd_andc(bit[1], bit[0]);
     546                temp2 = simd_andc(bit[3], bit[2]);
     547                temp3 = simd_and(temp1, temp2);
     548                temp4 = simd_and(bit[4], bit[5]);
     549                temp5 = simd_or(bit[6], bit[7]);
     550                temp6 = simd_andc(temp4, temp5);
     551                BackSlash = simd_and(temp3, temp6);
     552                temp7 = simd_or(bit[0], bit[1]);
     553                temp8 = simd_andc(bit[2], bit[3]);
     554                temp9 = simd_andc(temp8, temp7);
     555                temp10 = simd_or(bit[4], bit[5]);
     556                temp11 = simd_andc(bit[6], bit[7]);
     557                temp12 = simd_andc(temp11, temp10);
     558                DQuote = simd_and(temp9, temp12);
     559                temp13 = simd_andc(bit[5], bit[4]);
     560                temp14 = simd_and(bit[6], bit[7]);
     561                temp15 = simd_and(temp13, temp14);
     562                SQuote = simd_and(temp9, temp15);
     563                temp16 = simd_or(bit[2], bit[3]);
     564                temp17 = simd_or(temp7, temp16);
     565                temp18 = simd_andc(bit[7], bit[6]);
     566                temp19 = simd_and(temp4, temp18);
     567                CR = simd_andc(temp19, temp17);
     568                temp20 = simd_andc(bit[4], bit[5]);
     569                temp21 = simd_and(temp20, temp11);
     570                LF = simd_andc(temp21, temp17);
     571                Comma = simd_and(temp9, temp6);
     572                temp22 = simd_and(temp20, temp18);
     573                HT = simd_andc(temp22, temp17);
     574
     575                p2 = simd_xor(DQuote,simd_slli_128(DQuote,1));
     576                p4 = simd_xor(p2,simd_slli_128(p2,2));
     577                p8 = simd_xor(p4,simd_slli_128(p4,4));
     578                p16 = simd_xor(p8,simd_slli_128(p8,8));
     579                p32 = simd_xor(p16,simd_slli_128(p16,16));
     580                p64 = simd_xor(p32,simd_slli_128(p32,32));
     581                quote_mask = simd_xor(p64,simd_slli_128(p64,64));
     582                quote_mask = simd_xor(quote_base,quote_mask);
     583                quote_base = simd_shufflei_32(simd_srai_32(quote_mask,31),0xFF);
     584
     585
     586                Delim = simd_andc(Comma,quote_mask);
     587                EOL =  simd_andc(simd_or(simd_slli_128(CR,1),LF),quote_mask);
     588
     589                cstate->EOL_stream[block_pos/BLOCK_SIZE_BITS]=EOL;
     590                cstate->delim_stream[block_pos/BLOCK_SIZE_BITS]=Delim;
     591
     592                block_pos += chars_read;
     593        }while (chars_read == BLOCK_SIZE_BITS);
     594}
     595
     596void direct_bitstream_gen(CopyState cstate) {
     597
     598
     599        BitBlock Quote;
     600        BitBlock EOL;
     601        BitBlock CR;
     602        BitBlock LF;
     603       
     604        BitBlock p2;
     605        BitBlock p4;   
     606        BitBlock p8;
     607        BitBlock p16;
     608        BitBlock p32;
     609        BitBlock p64;
     610        BitBlock quote_mask;
     611        BitBlock quote_base;
     612        BitBlock quote_splat;
     613        BitBlock CR_splat;
     614        BitBlock LF_splat;
     615        BytePack * bytepack;
     616       
     617       
     618        int block_pos = 0;
     619        int i=0;
     620        int chars_read = 0;
     621       
     622
     623        quote_base = simd_const_8(0);
     624
     625        quote_splat = simd_const_8(cstate->quote[0]);
     626        CR_splat = simd_const_8('\r');
     627        LF_splat = simd_const_8('\n');
     628
     629        bytepack = simd_new(8);
     630       
     631        do{
     632                bytepack = (BytePack *)(&(cstate->raw_buf[block_pos]));
     633               
     634                chars_read = min(cstate->raw_buf_len-block_pos,BLOCK_SIZE_BITS);
     635                if(chars_read==0)break;
     636                for (i = chars_read;i < BLOCK_SIZE_BITS; i++) {
     637                        ((char *) bytepack)[i] = 0;
     638                }
     639
     640                for(i=0;i<8;i++){
     641                        ((short*)&Quote)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], quote_splat));
     642                        ((short*)&CR)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], CR_splat));
     643                        ((short*)&LF)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], LF_splat));
     644                }
     645
     646                p2 = simd_xor(Quote,simd_slli_128(Quote,1));
     647                p4 = simd_xor(p2,simd_slli_128(p2,2));
     648                p8 = simd_xor(p4,simd_slli_128(p4,4));
     649                p16 = simd_xor(p8,simd_slli_128(p8,8));
     650                p32 = simd_xor(p16,simd_slli_128(p16,16));
     651                p64 = simd_xor(p32,simd_slli_128(p32,32));
     652                quote_mask = simd_xor(p64,simd_slli_128(p64,64));
     653                quote_mask = simd_xor(quote_base,quote_mask);
     654                quote_base = simd_shufflei_32(simd_srai_32(quote_mask,31),0xFF);
     655
     656                EOL =  simd_andc(simd_or(simd_slli_128(CR,1),LF),quote_mask);
     657
     658                cstate->EOL_stream[block_pos/BLOCK_SIZE_BITS]=EOL;
     659
     660
     661                block_pos += chars_read;
     662        }while (chars_read == BLOCK_SIZE_BITS);
     663}
     664
     665void direct_bitstream_gen_with_escape(CopyState cstate) {
     666
     667
     668        BitBlock Quote;
     669        BitBlock EOL;
     670        BitBlock CR;
     671        BitBlock LF;
     672        BitBlock Escape;
     673       
     674        BitBlock p2;
     675        BitBlock p4;   
     676        BitBlock p8;
     677        BitBlock p16;
     678        BitBlock p32;
     679        BitBlock p64;
     680        BitBlock quote_mask;
     681        BitBlock quote_base;
     682        BitBlock quote_splat;
     683        BitBlock escape_splat;
     684        BitBlock CR_splat;
     685        BitBlock LF_splat;
     686        BytePack * bytepack;
     687       
     688        int carry0=0;
     689        int carry1=0;
     690        int carry2=0;
     691        BitBlock even;
     692        BitBlock odd;
     693        BitBlock start;
     694        BitBlock even_start;
     695        BitBlock even_final;
     696        BitBlock odd_start;
     697        BitBlock odd_final;
     698        BitBlock escape;
     699        BitBlock temp0;
     700        BitBlock temp1;
     701        BitBlock temp2;
     702        BitBlock escape_outof_quote;
     703        BitBlock cursor;
     704        BitBlock temp_Quote;
     705       
     706        int block_pos = 0;
     707        int i=0;
     708        int chars_read = 0;
     709       
     710        quote_base = simd_const_8(0);
     711
     712        quote_splat = simd_const_8(cstate->quote[0]);
     713        escape_splat = simd_const_8(cstate->escape[0]);
     714        CR_splat = simd_const_8('\r');
     715        LF_splat = simd_const_8('\n');
     716
     717        bytepack = simd_new(8);
     718       
     719        do{
     720                bytepack = (BytePack *)(&(cstate->raw_buf[block_pos]));
     721               
     722                chars_read = min(cstate->raw_buf_len-block_pos,BLOCK_SIZE_BITS);
     723                if(chars_read==0)break;
     724                for (i = chars_read;i < BLOCK_SIZE_BITS; i++) {
     725                        ((char *) bytepack)[i] = 0;
     726                }
     727
     728                for(i=0;i<8;i++){
     729                        ((short*)&Quote)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], quote_splat));
     730                        ((short*)&CR)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], CR_splat));
     731                        ((short*)&LF)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], LF_splat)); 
     732                        ((short*)&Escape)[i] = (short)_mm_movemask_epi8(simd_eq_8(bytepack[i], escape_splat));
     733                }
     734               
     735                if(bitblock_has_bit(Escape)){
     736                        odd = simd_const_2(1);
     737                        even = simd_const_2(2);
     738       
     739                        adc128(Escape,Escape,carry0,temp0);
     740                        start = simd_andc(Escape,temp0);
     741                        even_start = simd_and(start,even);
     742                        adc128(even_start, Escape, carry1, temp1);
     743                        even_final = simd_andc(temp1,Escape);
     744                        escape = simd_and(even_final,odd);
     745                       
     746                        odd_start = simd_and(start,odd);
     747                        adc128(odd_start, Escape, carry2, temp2);
     748                        odd_final = simd_andc(temp2,Escape);
     749                        escape = simd_or(escape, simd_and(odd_final,even));
     750               
     751                        temp_Quote = simd_andc(Quote,escape);                                           
     752                        p2 = simd_xor(temp_Quote,simd_slli_128(temp_Quote,1));
     753                        p4 = simd_xor(p2,simd_slli_128(p2,2));
     754                        p8 = simd_xor(p4,simd_slli_128(p4,4));
     755                        p16 = simd_xor(p8,simd_slli_128(p8,8));
     756                        p32 = simd_xor(p16,simd_slli_128(p16,16));
     757                        p64 = simd_xor(p32,simd_slli_128(p32,32));
     758                        quote_mask = simd_xor(p64,simd_slli_128(p64,64));
     759                        quote_mask = simd_xor(quote_base,quote_mask);
     760
     761                        escape_outof_quote = simd_andc(escape,quote_mask);
     762                        while (bitblock_has_bit(escape_outof_quote)){
     763                                cursor = sisd_from_int(1);
     764                                cursor = simd_and(simd_add_64(cursor, simd_not(escape_outof_quote)),escape_outof_quote);
     765                                escape = simd_andc(escape, cursor);
     766                                temp_Quote = simd_andc(Quote,escape);
     767                                p2 = simd_xor(temp_Quote,simd_slli_128(temp_Quote,1));
     768                                p4 = simd_xor(p2,simd_slli_128(p2,2));
     769                                p8 = simd_xor(p4,simd_slli_128(p4,4));
     770                                p16 = simd_xor(p8,simd_slli_128(p8,8));
     771                                p32 = simd_xor(p16,simd_slli_128(p16,16));
     772                                p64 = simd_xor(p32,simd_slli_128(p32,32));
     773                                quote_mask = simd_xor(p64,simd_slli_128(p64,64));
     774                                quote_mask = simd_xor(quote_base,quote_mask);
     775                                escape_outof_quote = simd_andc(escape,quote_mask);
     776                                break;
     777                        }
     778                       
     779                        quote_base = simd_shufflei_32(simd_srai_32(quote_mask,31),0xFF);
     780                        Quote = temp_Quote;
     781                }
     782                else{
     783                        p2 = simd_xor(Quote,simd_slli_128(Quote,1));
     784                        p4 = simd_xor(p2,simd_slli_128(p2,2));
     785                        p8 = simd_xor(p4,simd_slli_128(p4,4));
     786                        p16 = simd_xor(p8,simd_slli_128(p8,8));
     787                        p32 = simd_xor(p16,simd_slli_128(p16,16));
     788                        p64 = simd_xor(p32,simd_slli_128(p32,32));
     789                        quote_mask = simd_xor(p64,simd_slli_128(p64,64));
     790                        quote_mask = simd_xor(quote_base,quote_mask);
     791                        quote_base = simd_shufflei_32(simd_srai_32(quote_mask,31),0xFF);
     792                }
     793
     794                EOL =  simd_andc(simd_or(simd_slli_128(CR,1),LF),quote_mask);
     795                cstate->EOL_stream[block_pos/BLOCK_SIZE_BITS]=EOL;
     796
     797
     798                block_pos += chars_read;
     799        }while (chars_read == BLOCK_SIZE_BITS);
     800}
Note: See TracChangeset for help on using the changeset viewer.