Listing all parts in log have no sense. 
Should be either silenced, either combined into a single line.
{
            RangesInDataPart part = parts.back();
            parts.pop_back();
            size_t & marks_in_part = sum_marks_in_parts.back();
            
            if (marks_in_part >= min_marks_for_concurrent_read &&
                need_marks < min_marks_for_concurrent_read)
                need_marks = min_marks_for_concurrent_read;
            
            if (marks_in_part > need_marks &&
                marks_in_part - need_marks < min_marks_for_concurrent_read)
                need_marks = marks_in_part;
            MarkRanges ranges_to_get_from_part;
            
            if (marks_in_part <= need_marks)
            {
                ranges_to_get_from_part = part.ranges;
                need_marks -= marks_in_part;
                sum_marks_in_parts.pop_back();
            }
            else
            {
                
                while (need_marks > 0)
                {
                    if (part.ranges.empty())
                        throw Exception("Unexpected end of ranges while spreading marks among streams", ErrorCodes::LOGICAL_ERROR);
                    MarkRange & range = part.ranges.front();
                    const size_t marks_in_range = range.end - range.begin;
                    const size_t marks_to_get_from_range = std::min(marks_in_range, need_marks);