| 782 | |
| 783 | template <typename ArrowType> |
| 784 | void MergeNulls(CompressedChunkLocation* nulls_begin, |
| 785 | CompressedChunkLocation* nulls_middle, |
| 786 | CompressedChunkLocation* nulls_end, |
| 787 | CompressedChunkLocation* temp_indices, int64_t null_count) { |
| 788 | if constexpr (has_null_like_values<ArrowType>()) { |
| 789 | // Merge rows with a null or a null-like in the first sort key |
| 790 | auto& comparator = comparator_; |
| 791 | const auto& first_sort_key = sort_keys_[0]; |
| 792 | |
| 793 | std::merge(nulls_begin, nulls_middle, nulls_middle, nulls_end, temp_indices, |
| 794 | [&](CompressedChunkLocation left, CompressedChunkLocation right) { |
| 795 | // First column is either null or nan |
| 796 | const auto left_loc = ChunkLocation{left}; |
| 797 | const auto right_loc = ChunkLocation{right}; |
| 798 | const auto chunk_left = first_sort_key.GetChunk(left_loc); |
| 799 | const auto chunk_right = first_sort_key.GetChunk(right_loc); |
| 800 | const auto left_is_null = chunk_left.IsNull(); |
| 801 | const auto right_is_null = chunk_right.IsNull(); |
| 802 | if (left_is_null == right_is_null) { |
| 803 | return comparator.Compare(left_loc, right_loc, 1); |
| 804 | } else if (options_.null_placement == NullPlacement::AtEnd) { |
| 805 | return right_is_null; |
| 806 | } else { |
| 807 | return left_is_null; |
| 808 | } |
| 809 | }); |
| 810 | // Copy back temp area into main buffer |
| 811 | std::copy(temp_indices, temp_indices + (nulls_end - nulls_begin), nulls_begin); |
| 812 | } else { |
| 813 | MergeNullsOnly(nulls_begin, nulls_middle, nulls_end, temp_indices, null_count); |
| 814 | } |
| 815 | } |
| 816 | |
| 817 | void MergeNullsOnly(CompressedChunkLocation* nulls_begin, |
| 818 | CompressedChunkLocation* nulls_middle, |