| 707 | } |
| 708 | |
| 709 | Status HdfsScanNodeBase::IssueInitialScanRanges(RuntimeState* state) { |
| 710 | DCHECK(!initial_ranges_issued_.Load()); |
| 711 | initial_ranges_issued_.Store(true); |
| 712 | // We want to decrement this remaining_scan_range_submissions in all cases. |
| 713 | auto remaining_scan_range_submissions_trigger = |
| 714 | MakeScopeExitTrigger([&](){ UpdateRemainingScanRangeSubmissions(-1); }); |
| 715 | |
| 716 | // No need to issue ranges with limit 0. |
| 717 | if (ReachedLimitShared()) { |
| 718 | DCHECK_EQ(limit_, 0); |
| 719 | return Status::OK(); |
| 720 | } |
| 721 | |
| 722 | if (filter_ctxs_.size() > 0) WaitForRuntimeFilters(); |
| 723 | // Apply dynamic partition-pruning per-file. |
| 724 | HdfsFileDesc::FileFormatsMap matching_per_type_files; |
| 725 | std::vector<HdfsFileDesc*>* file_list = |
| 726 | shared_state_->GetFilesForIssuingScanRangesForInstance( |
| 727 | runtime_state_->instance_ctx().fragment_instance_id); |
| 728 | if (file_list == nullptr) return Status::OK(); |
| 729 | for (HdfsFileDesc* file : *file_list) { |
| 730 | if (FilePassesFilterPredicates(state, file, filter_ctxs_)) { |
| 731 | matching_per_type_files[file->file_format].push_back(file); |
| 732 | } else { |
| 733 | SkipFile(file->file_format, file); |
| 734 | } |
| 735 | } |
| 736 | |
| 737 | // Issue initial ranges for all file types. Only call functions for file types that |
| 738 | // actually exist - trying to add empty lists of ranges can result in spurious |
| 739 | // CANCELLED errors - see IMPALA-6564. |
| 740 | for (auto& entry : matching_per_type_files) { |
| 741 | if (entry.second.empty()) continue; |
| 742 | // Randomize the order this node processes the files. We want to do this to avoid |
| 743 | // issuing remote reads to the same DN from different impalads. In file formats such |
| 744 | // as avro/seq/rc (i.e. splittable with a header), every node first reads the header. |
| 745 | // If every node goes through the files in the same order, all the remote reads are |
| 746 | // for the same file meaning a few DN serves a lot of remote reads at the same time. |
| 747 | random_shuffle(entry.second.begin(), entry.second.end()); |
| 748 | switch (entry.first) { |
| 749 | case THdfsFileFormat::PARQUET: |
| 750 | RETURN_IF_ERROR(HdfsParquetScanner::IssueInitialRanges(this, entry.second)); |
| 751 | break; |
| 752 | case THdfsFileFormat::TEXT: |
| 753 | RETURN_IF_ERROR(HdfsTextScanner::IssueInitialRanges(this, entry.second)); |
| 754 | break; |
| 755 | case THdfsFileFormat::SEQUENCE_FILE: |
| 756 | case THdfsFileFormat::RC_FILE: |
| 757 | case THdfsFileFormat::AVRO: |
| 758 | RETURN_IF_ERROR(BaseSequenceScanner::IssueInitialRanges(this, entry.second)); |
| 759 | break; |
| 760 | case THdfsFileFormat::ORC: |
| 761 | RETURN_IF_ERROR(HdfsOrcScanner::IssueInitialRanges(this, entry.second)); |
| 762 | break; |
| 763 | case THdfsFileFormat::JSON: |
| 764 | RETURN_IF_ERROR(HdfsJsonScanner::IssueInitialRanges(this, entry.second)); |
| 765 | break; |
| 766 | default: |
nothing calls this directly
no test coverage detected