| 665 | } |
| 666 | |
| 667 | Status SortInternal() { |
| 668 | // Sort each batch independently and merge to sorted indices. |
| 669 | const int64_t num_batches = static_cast<int64_t>(batches_.size()); |
| 670 | if (num_batches == 0) { |
| 671 | return Status::OK(); |
| 672 | } |
| 673 | std::vector<NullPartitionResult> sorted(num_batches); |
| 674 | |
| 675 | // First sort all individual batches |
| 676 | int64_t begin_offset = 0; |
| 677 | int64_t end_offset = 0; |
| 678 | int64_t null_count = 0; |
| 679 | for (int64_t i = 0; i < num_batches; ++i) { |
| 680 | const auto& batch = *batches_[i]; |
| 681 | end_offset += batch.num_rows(); |
| 682 | RadixRecordBatchSorter sorter(indices_begin_ + begin_offset, |
| 683 | indices_begin_ + end_offset, batch, options_); |
| 684 | ARROW_ASSIGN_OR_RAISE(sorted[i], sorter.Sort(begin_offset)); |
| 685 | DCHECK_EQ(sorted[i].overall_begin(), indices_begin_ + begin_offset); |
| 686 | DCHECK_EQ(sorted[i].overall_end(), indices_begin_ + end_offset); |
| 687 | DCHECK_EQ(sorted[i].non_null_count() + sorted[i].null_count(), batch.num_rows()); |
| 688 | begin_offset = end_offset; |
| 689 | // XXX this is an upper bound on the true null count |
| 690 | null_count += sorted[i].null_count(); |
| 691 | } |
| 692 | DCHECK_EQ(end_offset, indices_end_ - indices_begin_); |
| 693 | |
| 694 | // Then merge them by pairs, recursively |
| 695 | if (sorted.size() > 1) { |
| 696 | ChunkedIndexMapper chunked_mapper(batches_, indices_begin_, indices_end_); |
| 697 | ARROW_ASSIGN_OR_RAISE(auto chunked_indices_pair, |
| 698 | chunked_mapper.LogicalToPhysical()); |
| 699 | auto [chunked_indices_begin, chunked_indices_end] = chunked_indices_pair; |
| 700 | |
| 701 | std::vector<ChunkedNullPartitionResult> chunk_sorted(num_batches); |
| 702 | for (int64_t i = 0; i < num_batches; ++i) { |
| 703 | chunk_sorted[i] = sorted[i].TranslateTo(indices_begin_, chunked_indices_begin); |
| 704 | } |
| 705 | |
| 706 | struct Visitor { |
| 707 | TableSorter* sorter; |
| 708 | std::vector<ChunkedNullPartitionResult>* chunk_sorted; |
| 709 | int64_t null_count; |
| 710 | |
| 711 | #define VISIT(TYPE) \ |
| 712 | Status Visit(const TYPE& type) { \ |
| 713 | return sorter->MergeInternal<TYPE>(chunk_sorted, null_count); \ |
| 714 | } |
| 715 | |
| 716 | VISIT_SORTABLE_PHYSICAL_TYPES(VISIT) |
| 717 | VISIT(NullType) |
| 718 | #undef VISIT |
| 719 | |
| 720 | Status Visit(const DataType& type) { |
| 721 | return Status::NotImplemented("Unsupported type for sorting: ", |
| 722 | type.ToString()); |
| 723 | } |
| 724 | }; |
nothing calls this directly
no test coverage detected