| 79 | private: |
| 80 | template <typename Type> |
| 81 | Status SortInternal() { |
| 82 | using ArrayType = typename TypeTraits<Type>::ArrayType; |
| 83 | ArraySortOptions options(order_, null_placement_); |
| 84 | const auto num_chunks = static_cast<int>(physical_chunks_.size()); |
| 85 | if (num_chunks == 0) { |
| 86 | *output_ = {indices_end_, indices_end_, indices_end_, indices_end_}; |
| 87 | return Status::OK(); |
| 88 | } |
| 89 | const int64_t num_indices = static_cast<int64_t>(indices_end_ - indices_begin_); |
| 90 | const auto arrays = GetArrayPointers(physical_chunks_); |
| 91 | |
| 92 | // Sort each chunk independently and merge to sorted indices. |
| 93 | // This is a serial implementation. |
| 94 | std::vector<NullPartitionResult> sorted(num_chunks); |
| 95 | |
| 96 | // First sort all individual chunks |
| 97 | int64_t begin_offset = 0; |
| 98 | int64_t end_offset = 0; |
| 99 | int64_t null_count = 0; |
| 100 | for (int i = 0; i < num_chunks; ++i) { |
| 101 | const auto array = checked_cast<const ArrayType*>(arrays[i]); |
| 102 | end_offset += array->length(); |
| 103 | null_count += array->null_count(); |
| 104 | ARROW_ASSIGN_OR_RAISE(sorted[i], array_sorter_(indices_begin_ + begin_offset, |
| 105 | indices_begin_ + end_offset, *array, |
| 106 | begin_offset, options, ctx_)); |
| 107 | begin_offset = end_offset; |
| 108 | } |
| 109 | DCHECK_EQ(end_offset, num_indices); |
| 110 | |
| 111 | // Then merge them by pairs, recursively |
| 112 | if (sorted.size() > 1) { |
| 113 | ChunkedIndexMapper chunked_mapper(arrays, indices_begin_, indices_end_); |
| 114 | ARROW_ASSIGN_OR_RAISE(auto chunked_indices_pair, |
| 115 | chunked_mapper.LogicalToPhysical()); |
| 116 | auto [chunked_indices_begin, chunked_indices_end] = chunked_indices_pair; |
| 117 | |
| 118 | std::vector<ChunkedNullPartitionResult> chunk_sorted(num_chunks); |
| 119 | for (int i = 0; i < num_chunks; ++i) { |
| 120 | chunk_sorted[i] = sorted[i].TranslateTo(indices_begin_, chunked_indices_begin); |
| 121 | } |
| 122 | |
| 123 | auto merge_nulls = [&](CompressedChunkLocation* nulls_begin, |
| 124 | CompressedChunkLocation* nulls_middle, |
| 125 | CompressedChunkLocation* nulls_end, |
| 126 | CompressedChunkLocation* temp_indices, int64_t null_count) { |
| 127 | if (has_null_like_values<typename ArrayType::TypeClass>()) { |
| 128 | PartitionNullsOnly<StablePartitioner>(nulls_begin, nulls_end, arrays, |
| 129 | null_count, null_placement_); |
| 130 | } |
| 131 | }; |
| 132 | auto merge_non_nulls = |
| 133 | [&](CompressedChunkLocation* range_begin, CompressedChunkLocation* range_middle, |
| 134 | CompressedChunkLocation* range_end, CompressedChunkLocation* temp_indices) { |
| 135 | MergeNonNulls<ArrayType>(range_begin, range_middle, range_end, arrays, |
| 136 | temp_indices); |
| 137 | }; |
| 138 |
nothing calls this directly
no test coverage detected