MCPcopy Create free account
hub / github.com/ByConity/ByConity / spreadMarkRangesAmongStreamsFinal

Method spreadMarkRangesAmongStreamsFinal

src/QueryPlan/ReadFromMergeTree.cpp:965–1126  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

963
964
965Pipe ReadFromMergeTree::spreadMarkRangesAmongStreamsFinal(
966 RangesInDataParts && parts_with_ranges,
967 const Names & column_names,
968 ActionsDAGPtr & out_projection)
969{
970 const auto & settings = context->getSettingsRef();
971 const auto data_settings = data.getSettings();
972
973 PartRangesReadInfo info(parts_with_ranges, settings, *data_settings);
974
975 size_t num_streams = requested_num_streams;
976 if (num_streams > settings.max_final_threads)
977 num_streams = settings.max_final_threads;
978
979 /// If setting do_not_merge_across_partitions_select_final is true than we won't merge parts from different partitions.
980 /// We have all parts in parts vector, where parts with same partition are nearby.
981 /// So we will store iterators pointed to the beginning of each partition range (and parts.end()),
982 /// then we will create a pipe for each partition that will run selecting processor and merging processor
983 /// for the parts with this partition. In the end we will unite all the pipes.
984 std::vector<RangesInDataParts::iterator> parts_to_merge_ranges;
985 auto it = parts_with_ranges.begin();
986 parts_to_merge_ranges.push_back(it);
987
988 if (settings.do_not_merge_across_partitions_select_final)
989 {
990 while (it != parts_with_ranges.end())
991 {
992 it = std::find_if(
993 it, parts_with_ranges.end(), [&it](auto & part) { return it->data_part->info.partition_id != part.data_part->info.partition_id; });
994 parts_to_merge_ranges.push_back(it);
995 }
996 /// We divide threads for each partition equally. But we will create at least the number of partitions threads.
997 /// (So, the total number of threads could be more than initial num_streams.
998 num_streams /= (parts_to_merge_ranges.size() - 1);
999 }
1000 else
1001 {
1002 /// If do_not_merge_across_partitions_select_final is false we just merge all the parts.
1003 parts_to_merge_ranges.push_back(parts_with_ranges.end());
1004 }
1005
1006 Pipes partition_pipes;
1007
1008 /// If do_not_merge_across_partitions_select_final is true and num_streams > 1
1009 /// we will store lonely parts with level > 0 to use parallel select on them.
1010 std::vector<RangesInDataPart> lonely_parts;
1011 size_t sum_marks_in_lonely_parts = 0;
1012
1013 for (size_t range_index = 0; range_index < parts_to_merge_ranges.size() - 1; ++range_index)
1014 {
1015 Pipe pipe;
1016
1017 {
1018 RangesInDataParts new_parts;
1019
1020 /// If do_not_merge_across_partitions_select_final is true and there is only one part in partition
1021 /// with level > 0 then we won't postprocess this part and if num_streams > 1 we
1022 /// can use parallel select on such parts. We save such parts in one vector and then use

Callers

nothing calls this directly

Calls 15

addMergingFinalFunction · 0.85
getActionsDAGMethod · 0.80
getSortingKeyColumnsMethod · 0.80
getPartitionKeyMethod · 0.80
createProjectionFunction · 0.70
readFunction · 0.50
maxFunction · 0.50
getSettingsMethod · 0.45
beginMethod · 0.45
push_backMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected