| 553 | } |
| 554 | |
| 555 | Status HdfsTextScanner::FindFirstTuple(MemPool* pool) { |
| 556 | DCHECK_EQ(scan_state_, SCAN_RANGE_INITIALIZED); |
| 557 | |
| 558 | // Either we're at the start of the file and thus skip all header lines, or we're in the |
| 559 | // middle of the file and look for the next tuple. |
| 560 | bool tuple_found = true; |
| 561 | int num_rows_to_skip = stream_->scan_range()->offset() == 0 |
| 562 | ? scan_node_->skip_header_line_count() : 1; |
| 563 | if (num_rows_to_skip > 0) { |
| 564 | int num_skipped_rows = 0; |
| 565 | bool eosr = false; |
| 566 | tuple_found = false; |
| 567 | // Offset maybe not point to a tuple boundary, skip ahead to the first tuple start in |
| 568 | // this scan range (if one exists). |
| 569 | do { |
| 570 | RETURN_IF_ERROR(FillByteBufferWrapper(nullptr, &eosr)); |
| 571 | |
| 572 | delimited_text_parser_->ParserReset(); |
| 573 | SCOPED_TIMER(parse_delimiter_timer_); |
| 574 | int64_t next_tuple_offset = 0; |
| 575 | int64_t bytes_left = byte_buffer_read_size_; |
| 576 | while (num_skipped_rows < num_rows_to_skip) { |
| 577 | next_tuple_offset = delimited_text_parser_->FindFirstInstance(byte_buffer_ptr_, |
| 578 | bytes_left); |
| 579 | if (next_tuple_offset == -1) break; |
| 580 | byte_buffer_ptr_ += next_tuple_offset; |
| 581 | bytes_left -= next_tuple_offset; |
| 582 | ++num_skipped_rows; |
| 583 | } |
| 584 | if (next_tuple_offset != -1) tuple_found = true; |
| 585 | } while (!tuple_found && !eosr); |
| 586 | |
| 587 | // Special case: if the first delimiter is at the end of the current buffer, it's |
| 588 | // possible it's a split "\r\n" delimiter. |
| 589 | if (tuple_found && byte_buffer_ptr_ == byte_buffer_end_) { |
| 590 | bool split_delimiter; |
| 591 | RETURN_IF_ERROR(CheckForSplitDelimiter(&split_delimiter)); |
| 592 | if (split_delimiter) { |
| 593 | if (eosr) { |
| 594 | // Split delimiter at the end of the scan range. The next tuple is considered |
| 595 | // part of the next scan range, so we report no tuple found. |
| 596 | tuple_found = false; |
| 597 | } else { |
| 598 | // Split delimiter at the end of the current buffer, but not eosr. Advance to |
| 599 | // the correct position in the next buffer. |
| 600 | RETURN_IF_ERROR(FillByteBufferWrapper(pool, &eosr)); |
| 601 | DCHECK_GT(byte_buffer_read_size_, 0); |
| 602 | DCHECK_EQ(*byte_buffer_ptr_, '\n'); |
| 603 | byte_buffer_ptr_ += 1; |
| 604 | } |
| 605 | } |
| 606 | } |
| 607 | if (num_rows_to_skip > 1 && num_skipped_rows != num_rows_to_skip) { |
| 608 | DCHECK(!tuple_found); |
| 609 | stringstream ss; |
| 610 | ss << "Could only skip " << num_skipped_rows << " header lines in first scan range " |
| 611 | << "but expected " << num_rows_to_skip << ". Try increasing " |
| 612 | << "max_scan_range_length to a value larger than the size of the file's header."; |
nothing calls this directly
no test coverage detected