/root/doris/be/src/util/counts.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #pragma once |
19 | | |
20 | | #include <pdqsort.h> |
21 | | |
22 | | #include <algorithm> |
23 | | #include <cmath> |
24 | | #include <queue> |
25 | | |
26 | | #include "udf/udf.h" |
27 | | #include "vec/common/pod_array.h" |
28 | | #include "vec/common/string_buffer.hpp" |
29 | | #include "vec/io/io_helper.h" |
30 | | |
31 | | namespace doris { |
32 | | |
33 | | template <typename Ty> |
34 | | class Counts { |
35 | | public: |
36 | 7.25k | Counts() = default; Unexecuted instantiation: _ZN5doris6CountsIhEC2Ev Line | Count | Source | 36 | 68 | Counts() = default; |
Line | Count | Source | 36 | 408 | Counts() = default; |
Line | Count | Source | 36 | 4.45k | Counts() = default; |
Line | Count | Source | 36 | 1.78k | Counts() = default; |
Line | Count | Source | 36 | 60 | Counts() = default; |
Unexecuted instantiation: _ZN5doris6CountsIfEC2Ev Line | Count | Source | 36 | 482 | Counts() = default; |
|
37 | | |
38 | 2.58k | void merge(Counts* other) { |
39 | 2.58k | if (other != nullptr && !other->_nums.empty()) { |
40 | 2.58k | _sorted_nums_vec.emplace_back(std::move(other->_nums)); |
41 | 2.58k | } |
42 | 2.58k | } Unexecuted instantiation: _ZN5doris6CountsIhE5mergeEPS1_ Unexecuted instantiation: _ZN5doris6CountsIaE5mergeEPS1_ _ZN5doris6CountsIsE5mergeEPS1_ Line | Count | Source | 38 | 24 | void merge(Counts* other) { | 39 | 24 | if (other != nullptr && !other->_nums.empty()) { | 40 | 24 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 41 | 24 | } | 42 | 24 | } |
_ZN5doris6CountsIiE5mergeEPS1_ Line | Count | Source | 38 | 1.66k | void merge(Counts* other) { | 39 | 1.66k | if (other != nullptr && !other->_nums.empty()) { | 40 | 1.66k | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 41 | 1.66k | } | 42 | 1.66k | } |
_ZN5doris6CountsIlE5mergeEPS1_ Line | Count | Source | 38 | 738 | void merge(Counts* other) { | 39 | 738 | if (other != nullptr && !other->_nums.empty()) { | 40 | 738 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 41 | 738 | } | 42 | 738 | } |
Unexecuted instantiation: _ZN5doris6CountsInE5mergeEPS1_ Unexecuted instantiation: _ZN5doris6CountsIfE5mergeEPS1_ _ZN5doris6CountsIdE5mergeEPS1_ Line | Count | Source | 38 | 160 | void merge(Counts* other) { | 39 | 160 | if (other != nullptr && !other->_nums.empty()) { | 40 | 160 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 41 | 160 | } | 42 | 160 | } |
|
43 | | |
44 | | void increment(Ty key, uint32_t i) { |
45 | | auto old_size = _nums.size(); |
46 | | _nums.resize(_nums.size() + i); |
47 | | for (uint32_t j = 0; j < i; ++j) { |
48 | | _nums[old_size + j] = key; |
49 | | } |
50 | | } |
51 | | |
52 | 5.77k | void increment(Ty key) { _nums.push_back(key); } Unexecuted instantiation: _ZN5doris6CountsIhE9incrementEh _ZN5doris6CountsIaE9incrementEa Line | Count | Source | 52 | 128 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIsE9incrementEs Line | Count | Source | 52 | 1.08k | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIiE9incrementEi Line | Count | Source | 52 | 3.16k | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIlE9incrementEl Line | Count | Source | 52 | 824 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsInE9incrementEn Line | Count | Source | 52 | 72 | void increment(Ty key) { _nums.push_back(key); } |
Unexecuted instantiation: _ZN5doris6CountsIfE9incrementEf _ZN5doris6CountsIdE9incrementEd Line | Count | Source | 52 | 500 | void increment(Ty key) { _nums.push_back(key); } |
|
53 | | |
54 | 10 | void increment_batch(const vectorized::PaddedPODArray<Ty>& keys) { |
55 | 10 | _nums.insert(keys.begin(), keys.end()); |
56 | 10 | } Unexecuted instantiation: _ZN5doris6CountsIhE15increment_batchERKNS_10vectorized8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIaE15increment_batchERKNS_10vectorized8PODArrayIaLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIsE15increment_batchERKNS_10vectorized8PODArrayIsLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIiE15increment_batchERKNS_10vectorized8PODArrayIiLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE _ZN5doris6CountsIlE15increment_batchERKNS_10vectorized8PODArrayIlLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Line | Count | Source | 54 | 10 | void increment_batch(const vectorized::PaddedPODArray<Ty>& keys) { | 55 | 10 | _nums.insert(keys.begin(), keys.end()); | 56 | 10 | } |
Unexecuted instantiation: _ZN5doris6CountsInE15increment_batchERKNS_10vectorized8PODArrayInLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIfE15increment_batchERKNS_10vectorized8PODArrayIfLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIdE15increment_batchERKNS_10vectorized8PODArrayIdLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE |
57 | | |
58 | 3.52k | void serialize(vectorized::BufferWritable& buf) { |
59 | 3.52k | if (!_nums.empty()) { |
60 | 2.80k | pdqsort(_nums.begin(), _nums.end()); |
61 | 2.80k | size_t size = _nums.size(); |
62 | 2.80k | buf.write_binary(size); |
63 | 2.80k | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); |
64 | 2.80k | } else { |
65 | | // convert _sorted_nums_vec to _nums and do seiralize again |
66 | 712 | _convert_sorted_num_vec_to_nums(); |
67 | 712 | serialize(buf); |
68 | 712 | } |
69 | 3.52k | } Unexecuted instantiation: _ZN5doris6CountsIhE9serializeERNS_10vectorized14BufferWritableE Unexecuted instantiation: _ZN5doris6CountsIaE9serializeERNS_10vectorized14BufferWritableE _ZN5doris6CountsIsE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 58 | 24 | void serialize(vectorized::BufferWritable& buf) { | 59 | 24 | if (!_nums.empty()) { | 60 | 24 | pdqsort(_nums.begin(), _nums.end()); | 61 | 24 | size_t size = _nums.size(); | 62 | 24 | buf.write_binary(size); | 63 | 24 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 64 | 24 | } else { | 65 | | // convert _sorted_nums_vec to _nums and do seiralize again | 66 | 0 | _convert_sorted_num_vec_to_nums(); | 67 | 0 | serialize(buf); | 68 | 0 | } | 69 | 24 | } |
_ZN5doris6CountsIiE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 58 | 2.21k | void serialize(vectorized::BufferWritable& buf) { | 59 | 2.21k | if (!_nums.empty()) { | 60 | 1.82k | pdqsort(_nums.begin(), _nums.end()); | 61 | 1.82k | size_t size = _nums.size(); | 62 | 1.82k | buf.write_binary(size); | 63 | 1.82k | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 64 | 1.82k | } else { | 65 | | // convert _sorted_nums_vec to _nums and do seiralize again | 66 | 390 | _convert_sorted_num_vec_to_nums(); | 67 | 390 | serialize(buf); | 68 | 390 | } | 69 | 2.21k | } |
_ZN5doris6CountsIlE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 58 | 1.12k | void serialize(vectorized::BufferWritable& buf) { | 59 | 1.12k | if (!_nums.empty()) { | 60 | 802 | pdqsort(_nums.begin(), _nums.end()); | 61 | 802 | size_t size = _nums.size(); | 62 | 802 | buf.write_binary(size); | 63 | 802 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 64 | 802 | } else { | 65 | | // convert _sorted_nums_vec to _nums and do seiralize again | 66 | 322 | _convert_sorted_num_vec_to_nums(); | 67 | 322 | serialize(buf); | 68 | 322 | } | 69 | 1.12k | } |
Unexecuted instantiation: _ZN5doris6CountsInE9serializeERNS_10vectorized14BufferWritableE Unexecuted instantiation: _ZN5doris6CountsIfE9serializeERNS_10vectorized14BufferWritableE _ZN5doris6CountsIdE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 58 | 160 | void serialize(vectorized::BufferWritable& buf) { | 59 | 160 | if (!_nums.empty()) { | 60 | 160 | pdqsort(_nums.begin(), _nums.end()); | 61 | 160 | size_t size = _nums.size(); | 62 | 160 | buf.write_binary(size); | 63 | 160 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 64 | 160 | } else { | 65 | | // convert _sorted_nums_vec to _nums and do seiralize again | 66 | 0 | _convert_sorted_num_vec_to_nums(); | 67 | 0 | serialize(buf); | 68 | 0 | } | 69 | 160 | } |
|
70 | | |
71 | 2.58k | void unserialize(vectorized::BufferReadable& buf) { |
72 | 2.58k | size_t size; |
73 | 2.58k | buf.read_binary(size); |
74 | 2.58k | _nums.resize(size); |
75 | 2.58k | auto buff = buf.read(sizeof(Ty) * size); |
76 | 2.58k | memcpy(_nums.data(), buff.data, buff.size); |
77 | 2.58k | } Unexecuted instantiation: _ZN5doris6CountsIhE11unserializeERNS_10vectorized14BufferReadableE Unexecuted instantiation: _ZN5doris6CountsIaE11unserializeERNS_10vectorized14BufferReadableE _ZN5doris6CountsIsE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 71 | 24 | void unserialize(vectorized::BufferReadable& buf) { | 72 | 24 | size_t size; | 73 | 24 | buf.read_binary(size); | 74 | 24 | _nums.resize(size); | 75 | 24 | auto buff = buf.read(sizeof(Ty) * size); | 76 | 24 | memcpy(_nums.data(), buff.data, buff.size); | 77 | 24 | } |
_ZN5doris6CountsIiE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 71 | 1.66k | void unserialize(vectorized::BufferReadable& buf) { | 72 | 1.66k | size_t size; | 73 | 1.66k | buf.read_binary(size); | 74 | 1.66k | _nums.resize(size); | 75 | 1.66k | auto buff = buf.read(sizeof(Ty) * size); | 76 | 1.66k | memcpy(_nums.data(), buff.data, buff.size); | 77 | 1.66k | } |
_ZN5doris6CountsIlE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 71 | 738 | void unserialize(vectorized::BufferReadable& buf) { | 72 | 738 | size_t size; | 73 | 738 | buf.read_binary(size); | 74 | 738 | _nums.resize(size); | 75 | 738 | auto buff = buf.read(sizeof(Ty) * size); | 76 | 738 | memcpy(_nums.data(), buff.data, buff.size); | 77 | 738 | } |
Unexecuted instantiation: _ZN5doris6CountsInE11unserializeERNS_10vectorized14BufferReadableE Unexecuted instantiation: _ZN5doris6CountsIfE11unserializeERNS_10vectorized14BufferReadableE _ZN5doris6CountsIdE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 71 | 160 | void unserialize(vectorized::BufferReadable& buf) { | 72 | 160 | size_t size; | 73 | 160 | buf.read_binary(size); | 74 | 160 | _nums.resize(size); | 75 | 160 | auto buff = buf.read(sizeof(Ty) * size); | 76 | 160 | memcpy(_nums.data(), buff.data, buff.size); | 77 | 160 | } |
|
78 | | |
79 | 2.22k | double terminate(double quantile) { |
80 | 2.22k | if (_sorted_nums_vec.size() <= 1) { |
81 | 2.04k | if (_sorted_nums_vec.size() == 1) { |
82 | 842 | _nums = std::move(_sorted_nums_vec[0]); |
83 | 842 | } |
84 | | |
85 | 2.04k | if (_nums.empty()) { |
86 | | // Although set null here, but the value is 0.0 and the call method just |
87 | | // get val in aggregate_function_percentile_approx.h |
88 | 0 | return 0.0; |
89 | 0 | } |
90 | | |
91 | 2.04k | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { |
92 | 359 | pdqsort(_nums.begin(), _nums.end()); |
93 | 359 | } |
94 | | |
95 | 2.04k | if (quantile == 1 || _nums.size() == 1) { |
96 | 954 | return _nums.back(); |
97 | 954 | } |
98 | | |
99 | 1.08k | double u = (_nums.size() - 1) * quantile; |
100 | 1.08k | auto index = static_cast<uint32_t>(u); |
101 | 1.08k | return _nums[index] + |
102 | 1.08k | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); |
103 | 2.04k | } else { |
104 | 187 | DCHECK(_nums.empty()); |
105 | 187 | size_t rows = 0; |
106 | 482 | for (const auto& i : _sorted_nums_vec) { |
107 | 482 | rows += i.size(); |
108 | 482 | } |
109 | 187 | const bool reverse = quantile > 0.5 && rows > 2; |
110 | 187 | double u = (rows - 1) * quantile; |
111 | 187 | auto index = static_cast<uint32_t>(u); |
112 | | // if reverse, the step of target should start 0 like not reverse |
113 | | // so here rows need to minus index + 2 |
114 | | // eg: rows = 10, index = 5 |
115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 |
116 | | // if reverse, so the second number is 3, the first number is 4 |
117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. |
118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 |
119 | 187 | size_t target = reverse ? rows - index - 2 : index; |
120 | 187 | if (quantile == 1) { |
121 | 0 | target = 0; |
122 | 0 | } |
123 | 187 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); |
124 | 187 | if (quantile == 1) { |
125 | 0 | return second_number; |
126 | 0 | } |
127 | 187 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); |
128 | 187 | } |
129 | 2.22k | } Unexecuted instantiation: _ZN5doris6CountsIhE9terminateEd _ZN5doris6CountsIaE9terminateEd Line | Count | Source | 79 | 116 | double terminate(double quantile) { | 80 | 116 | if (_sorted_nums_vec.size() <= 1) { | 81 | 116 | if (_sorted_nums_vec.size() == 1) { | 82 | 0 | _nums = std::move(_sorted_nums_vec[0]); | 83 | 0 | } | 84 | | | 85 | 116 | if (_nums.empty()) { | 86 | | // Although set null here, but the value is 0.0 and the call method just | 87 | | // get val in aggregate_function_percentile_approx.h | 88 | 0 | return 0.0; | 89 | 0 | } | 90 | | | 91 | 116 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 92 | 48 | pdqsort(_nums.begin(), _nums.end()); | 93 | 48 | } | 94 | | | 95 | 116 | if (quantile == 1 || _nums.size() == 1) { | 96 | 68 | return _nums.back(); | 97 | 68 | } | 98 | | | 99 | 48 | double u = (_nums.size() - 1) * quantile; | 100 | 48 | auto index = static_cast<uint32_t>(u); | 101 | 48 | return _nums[index] + | 102 | 48 | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); | 103 | 116 | } else { | 104 | 0 | DCHECK(_nums.empty()); | 105 | 0 | size_t rows = 0; | 106 | 0 | for (const auto& i : _sorted_nums_vec) { | 107 | 0 | rows += i.size(); | 108 | 0 | } | 109 | 0 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 0 | double u = (rows - 1) * quantile; | 111 | 0 | auto index = static_cast<uint32_t>(u); | 112 | | // if reverse, the step of target should start 0 like not reverse | 113 | | // so here rows need to minus index + 2 | 114 | | // eg: rows = 10, index = 5 | 115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 116 | | // if reverse, so the second number is 3, the first number is 4 | 117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 119 | 0 | size_t target = reverse ? rows - index - 2 : index; | 120 | 0 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 0 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 0 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 0 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); | 128 | 0 | } | 129 | 116 | } |
_ZN5doris6CountsIsE9terminateEd Line | Count | Source | 79 | 592 | double terminate(double quantile) { | 80 | 592 | if (_sorted_nums_vec.size() <= 1) { | 81 | 586 | if (_sorted_nums_vec.size() == 1) { | 82 | 0 | _nums = std::move(_sorted_nums_vec[0]); | 83 | 0 | } | 84 | | | 85 | 586 | if (_nums.empty()) { | 86 | | // Although set null here, but the value is 0.0 and the call method just | 87 | | // get val in aggregate_function_percentile_approx.h | 88 | 0 | return 0.0; | 89 | 0 | } | 90 | | | 91 | 586 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 92 | 288 | pdqsort(_nums.begin(), _nums.end()); | 93 | 288 | } | 94 | | | 95 | 588 | if (quantile == 1 || _nums.size() == 1) { | 96 | 174 | return _nums.back(); | 97 | 174 | } | 98 | | | 99 | 412 | double u = (_nums.size() - 1) * quantile; | 100 | 412 | auto index = static_cast<uint32_t>(u); | 101 | 412 | return _nums[index] + | 102 | 412 | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); | 103 | 586 | } else { | 104 | 6 | DCHECK(_nums.empty()); | 105 | 6 | size_t rows = 0; | 106 | 24 | for (const auto& i : _sorted_nums_vec) { | 107 | 24 | rows += i.size(); | 108 | 24 | } | 109 | 6 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 6 | double u = (rows - 1) * quantile; | 111 | 6 | auto index = static_cast<uint32_t>(u); | 112 | | // if reverse, the step of target should start 0 like not reverse | 113 | | // so here rows need to minus index + 2 | 114 | | // eg: rows = 10, index = 5 | 115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 116 | | // if reverse, so the second number is 3, the first number is 4 | 117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 119 | 6 | size_t target = reverse ? rows - index - 2 : index; | 120 | 6 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 6 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 6 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 6 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); | 128 | 6 | } | 129 | 592 | } |
_ZN5doris6CountsIiE9terminateEd Line | Count | Source | 79 | 960 | double terminate(double quantile) { | 80 | 960 | if (_sorted_nums_vec.size() <= 1) { | 81 | 852 | if (_sorted_nums_vec.size() == 1) { | 82 | 694 | _nums = std::move(_sorted_nums_vec[0]); | 83 | 694 | } | 84 | | | 85 | 852 | if (_nums.empty()) { | 86 | | // Although set null here, but the value is 0.0 and the call method just | 87 | | // get val in aggregate_function_percentile_approx.h | 88 | 0 | return 0.0; | 89 | 0 | } | 90 | | | 91 | 852 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 92 | 22 | pdqsort(_nums.begin(), _nums.end()); | 93 | 22 | } | 94 | | | 95 | 852 | if (quantile == 1 || _nums.size() == 1) { | 96 | 484 | return _nums.back(); | 97 | 484 | } | 98 | | | 99 | 368 | double u = (_nums.size() - 1) * quantile; | 100 | 368 | auto index = static_cast<uint32_t>(u); | 101 | 368 | return _nums[index] + | 102 | 368 | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); | 103 | 852 | } else { | 104 | 108 | DCHECK(_nums.empty()); | 105 | 108 | size_t rows = 0; | 106 | 216 | for (const auto& i : _sorted_nums_vec) { | 107 | 216 | rows += i.size(); | 108 | 216 | } | 109 | 108 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 108 | double u = (rows - 1) * quantile; | 111 | 108 | auto index = static_cast<uint32_t>(u); | 112 | | // if reverse, the step of target should start 0 like not reverse | 113 | | // so here rows need to minus index + 2 | 114 | | // eg: rows = 10, index = 5 | 115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 116 | | // if reverse, so the second number is 3, the first number is 4 | 117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 119 | 108 | size_t target = reverse ? rows - index - 2 : index; | 120 | 108 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 108 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 108 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 108 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); | 128 | 108 | } | 129 | 960 | } |
_ZN5doris6CountsIlE9terminateEd Line | Count | Source | 79 | 233 | double terminate(double quantile) { | 80 | 233 | if (_sorted_nums_vec.size() <= 1) { | 81 | 196 | if (_sorted_nums_vec.size() == 1) { | 82 | 84 | _nums = std::move(_sorted_nums_vec[0]); | 83 | 84 | } | 84 | | | 85 | 196 | if (_nums.empty()) { | 86 | | // Although set null here, but the value is 0.0 and the call method just | 87 | | // get val in aggregate_function_percentile_approx.h | 88 | 0 | return 0.0; | 89 | 0 | } | 90 | | | 91 | 196 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 92 | 1 | pdqsort(_nums.begin(), _nums.end()); | 93 | 1 | } | 94 | | | 95 | 196 | if (quantile == 1 || _nums.size() == 1) { | 96 | 120 | return _nums.back(); | 97 | 120 | } | 98 | | | 99 | 76 | double u = (_nums.size() - 1) * quantile; | 100 | 76 | auto index = static_cast<uint32_t>(u); | 101 | 76 | return _nums[index] + | 102 | 76 | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); | 103 | 196 | } else { | 104 | 37 | DCHECK(_nums.empty()); | 105 | 37 | size_t rows = 0; | 106 | 146 | for (const auto& i : _sorted_nums_vec) { | 107 | 146 | rows += i.size(); | 108 | 146 | } | 109 | 37 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 37 | double u = (rows - 1) * quantile; | 111 | 37 | auto index = static_cast<uint32_t>(u); | 112 | | // if reverse, the step of target should start 0 like not reverse | 113 | | // so here rows need to minus index + 2 | 114 | | // eg: rows = 10, index = 5 | 115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 116 | | // if reverse, so the second number is 3, the first number is 4 | 117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 119 | 37 | size_t target = reverse ? rows - index - 2 : index; | 120 | 37 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 37 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 37 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 37 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); | 128 | 37 | } | 129 | 233 | } |
_ZN5doris6CountsInE9terminateEd Line | Count | Source | 79 | 60 | double terminate(double quantile) { | 80 | 60 | if (_sorted_nums_vec.size() <= 1) { | 81 | 60 | if (_sorted_nums_vec.size() == 1) { | 82 | 0 | _nums = std::move(_sorted_nums_vec[0]); | 83 | 0 | } | 84 | | | 85 | 60 | if (_nums.empty()) { | 86 | | // Although set null here, but the value is 0.0 and the call method just | 87 | | // get val in aggregate_function_percentile_approx.h | 88 | 0 | return 0.0; | 89 | 0 | } | 90 | | | 91 | 60 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 92 | 0 | pdqsort(_nums.begin(), _nums.end()); | 93 | 0 | } | 94 | | | 95 | 60 | if (quantile == 1 || _nums.size() == 1) { | 96 | 48 | return _nums.back(); | 97 | 48 | } | 98 | | | 99 | 12 | double u = (_nums.size() - 1) * quantile; | 100 | 12 | auto index = static_cast<uint32_t>(u); | 101 | 12 | return _nums[index] + | 102 | 12 | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); | 103 | 60 | } else { | 104 | 0 | DCHECK(_nums.empty()); | 105 | 0 | size_t rows = 0; | 106 | 0 | for (const auto& i : _sorted_nums_vec) { | 107 | 0 | rows += i.size(); | 108 | 0 | } | 109 | 0 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 0 | double u = (rows - 1) * quantile; | 111 | 0 | auto index = static_cast<uint32_t>(u); | 112 | | // if reverse, the step of target should start 0 like not reverse | 113 | | // so here rows need to minus index + 2 | 114 | | // eg: rows = 10, index = 5 | 115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 116 | | // if reverse, so the second number is 3, the first number is 4 | 117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 119 | 0 | size_t target = reverse ? rows - index - 2 : index; | 120 | 0 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 0 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 0 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 0 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); | 128 | 0 | } | 129 | 60 | } |
Unexecuted instantiation: _ZN5doris6CountsIfE9terminateEd _ZN5doris6CountsIdE9terminateEd Line | Count | Source | 79 | 266 | double terminate(double quantile) { | 80 | 266 | if (_sorted_nums_vec.size() <= 1) { | 81 | 230 | if (_sorted_nums_vec.size() == 1) { | 82 | 64 | _nums = std::move(_sorted_nums_vec[0]); | 83 | 64 | } | 84 | | | 85 | 230 | if (_nums.empty()) { | 86 | | // Although set null here, but the value is 0.0 and the call method just | 87 | | // get val in aggregate_function_percentile_approx.h | 88 | 0 | return 0.0; | 89 | 0 | } | 90 | | | 91 | 230 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 92 | 0 | pdqsort(_nums.begin(), _nums.end()); | 93 | 0 | } | 94 | | | 95 | 230 | if (quantile == 1 || _nums.size() == 1) { | 96 | 60 | return _nums.back(); | 97 | 60 | } | 98 | | | 99 | 170 | double u = (_nums.size() - 1) * quantile; | 100 | 170 | auto index = static_cast<uint32_t>(u); | 101 | 170 | return _nums[index] + | 102 | 170 | (u - static_cast<double>(index)) * (_nums[index + 1] - _nums[index]); | 103 | 230 | } else { | 104 | 36 | DCHECK(_nums.empty()); | 105 | 36 | size_t rows = 0; | 106 | 96 | for (const auto& i : _sorted_nums_vec) { | 107 | 96 | rows += i.size(); | 108 | 96 | } | 109 | 36 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 36 | double u = (rows - 1) * quantile; | 111 | 36 | auto index = static_cast<uint32_t>(u); | 112 | | // if reverse, the step of target should start 0 like not reverse | 113 | | // so here rows need to minus index + 2 | 114 | | // eg: rows = 10, index = 5 | 115 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 116 | | // if reverse, so the second number is 3, the first number is 4 | 117 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 118 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 119 | 36 | size_t target = reverse ? rows - index - 2 : index; | 120 | 36 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 36 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 36 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 36 | return first_number + (u - static_cast<double>(index)) * (second_number - first_number); | 128 | 36 | } | 129 | 266 | } |
|
130 | | |
131 | | private: |
132 | | struct Node { |
133 | | Ty value; |
134 | | int array_index; |
135 | | int64_t element_index; |
136 | | |
137 | 2.01k | auto operator<=>(const Node& other) const { return value <=> other.value; } Unexecuted instantiation: _ZNK5doris6CountsIhE4NodessERKS2_ Unexecuted instantiation: _ZNK5doris6CountsIaE4NodessERKS2_ _ZNK5doris6CountsIsE4NodessERKS2_ Line | Count | Source | 137 | 136 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIiE4NodessERKS2_ Line | Count | Source | 137 | 962 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIlE4NodessERKS2_ Line | Count | Source | 137 | 809 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
Unexecuted instantiation: _ZNK5doris6CountsInE4NodessERKS2_ Unexecuted instantiation: _ZNK5doris6CountsIfE4NodessERKS2_ _ZNK5doris6CountsIdE4NodessERKS2_ Line | Count | Source | 137 | 110 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
|
138 | | }; |
139 | | |
140 | 712 | void _convert_sorted_num_vec_to_nums() { |
141 | 712 | size_t rows = 0; |
142 | 1.26k | for (const auto& i : _sorted_nums_vec) { |
143 | 1.26k | rows += i.size(); |
144 | 1.26k | } |
145 | 712 | _nums.resize(rows); |
146 | 712 | size_t count = 0; |
147 | | |
148 | 712 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; |
149 | 1.97k | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
150 | 1.26k | if (!_sorted_nums_vec[i].empty()) { |
151 | 1.26k | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); |
152 | 1.26k | } |
153 | 1.26k | } |
154 | | |
155 | 2.16k | while (!min_heap.empty()) { |
156 | 1.45k | Node node = min_heap.top(); |
157 | 1.45k | min_heap.pop(); |
158 | 1.45k | _nums[count++] = node.value; |
159 | 1.45k | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { |
160 | 192 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
161 | 192 | min_heap.push(node); |
162 | 192 | } |
163 | 1.45k | } |
164 | 712 | _sorted_nums_vec.clear(); |
165 | 712 | } Unexecuted instantiation: _ZN5doris6CountsIhE31_convert_sorted_num_vec_to_numsEv Unexecuted instantiation: _ZN5doris6CountsIaE31_convert_sorted_num_vec_to_numsEv Unexecuted instantiation: _ZN5doris6CountsIsE31_convert_sorted_num_vec_to_numsEv _ZN5doris6CountsIiE31_convert_sorted_num_vec_to_numsEv Line | Count | Source | 140 | 390 | void _convert_sorted_num_vec_to_nums() { | 141 | 390 | size_t rows = 0; | 142 | 756 | for (const auto& i : _sorted_nums_vec) { | 143 | 756 | rows += i.size(); | 144 | 756 | } | 145 | 390 | _nums.resize(rows); | 146 | 390 | size_t count = 0; | 147 | | | 148 | 390 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 149 | 1.14k | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 150 | 756 | if (!_sorted_nums_vec[i].empty()) { | 151 | 756 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 152 | 756 | } | 153 | 756 | } | 154 | | | 155 | 1.29k | while (!min_heap.empty()) { | 156 | 900 | Node node = min_heap.top(); | 157 | 900 | min_heap.pop(); | 158 | 900 | _nums[count++] = node.value; | 159 | 900 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 160 | 144 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 161 | 144 | min_heap.push(node); | 162 | 144 | } | 163 | 900 | } | 164 | 390 | _sorted_nums_vec.clear(); | 165 | 390 | } |
_ZN5doris6CountsIlE31_convert_sorted_num_vec_to_numsEv Line | Count | Source | 140 | 322 | void _convert_sorted_num_vec_to_nums() { | 141 | 322 | size_t rows = 0; | 142 | 508 | for (const auto& i : _sorted_nums_vec) { | 143 | 508 | rows += i.size(); | 144 | 508 | } | 145 | 322 | _nums.resize(rows); | 146 | 322 | size_t count = 0; | 147 | | | 148 | 322 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 149 | 830 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 150 | 508 | if (!_sorted_nums_vec[i].empty()) { | 151 | 508 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 152 | 508 | } | 153 | 508 | } | 154 | | | 155 | 878 | while (!min_heap.empty()) { | 156 | 556 | Node node = min_heap.top(); | 157 | 556 | min_heap.pop(); | 158 | 556 | _nums[count++] = node.value; | 159 | 556 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 160 | 48 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 161 | 48 | min_heap.push(node); | 162 | 48 | } | 163 | 556 | } | 164 | 322 | _sorted_nums_vec.clear(); | 165 | 322 | } |
Unexecuted instantiation: _ZN5doris6CountsInE31_convert_sorted_num_vec_to_numsEv Unexecuted instantiation: _ZN5doris6CountsIfE31_convert_sorted_num_vec_to_numsEv Unexecuted instantiation: _ZN5doris6CountsIdE31_convert_sorted_num_vec_to_numsEv |
166 | | |
167 | 187 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { |
168 | 187 | Ty first_number = 0, second_number = 0; |
169 | 187 | size_t count = 0; |
170 | 187 | if (reverse) { |
171 | 54 | std::priority_queue<Node> max_heap; |
172 | 242 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
173 | 188 | if (!_sorted_nums_vec[i].empty()) { |
174 | 188 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, |
175 | 188 | _sorted_nums_vec[i].size() - 1); |
176 | 188 | } |
177 | 188 | } |
178 | | |
179 | 242 | while (!max_heap.empty()) { |
180 | 242 | Node node = max_heap.top(); |
181 | 242 | max_heap.pop(); |
182 | 242 | if (count == target) { |
183 | 54 | second_number = node.value; |
184 | 188 | } else if (count == target + 1) { |
185 | 54 | first_number = node.value; |
186 | 54 | break; |
187 | 54 | } |
188 | 188 | ++count; |
189 | 188 | if (--node.element_index >= 0) { |
190 | 146 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
191 | 146 | max_heap.push(node); |
192 | 146 | } |
193 | 188 | } |
194 | | |
195 | 133 | } else { |
196 | 133 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; |
197 | 427 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
198 | 294 | if (!_sorted_nums_vec[i].empty()) { |
199 | 294 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); |
200 | 294 | } |
201 | 294 | } |
202 | | |
203 | 443 | while (!min_heap.empty()) { |
204 | 443 | Node node = min_heap.top(); |
205 | 443 | min_heap.pop(); |
206 | 443 | if (count == target) { |
207 | 133 | first_number = node.value; |
208 | 310 | } else if (count == target + 1) { |
209 | 133 | second_number = node.value; |
210 | 133 | break; |
211 | 133 | } |
212 | 310 | ++count; |
213 | 310 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { |
214 | 272 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
215 | 272 | min_heap.push(node); |
216 | 272 | } |
217 | 310 | } |
218 | 133 | } |
219 | | |
220 | 187 | return {first_number, second_number}; |
221 | 187 | } Unexecuted instantiation: _ZN5doris6CountsIhE27_merge_sort_and_get_numbersElb Unexecuted instantiation: _ZN5doris6CountsIaE27_merge_sort_and_get_numbersElb _ZN5doris6CountsIsE27_merge_sort_and_get_numbersElb Line | Count | Source | 167 | 6 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 168 | 6 | Ty first_number = 0, second_number = 0; | 169 | 6 | size_t count = 0; | 170 | 6 | if (reverse) { | 171 | 2 | std::priority_queue<Node> max_heap; | 172 | 10 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 173 | 8 | if (!_sorted_nums_vec[i].empty()) { | 174 | 8 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 175 | 8 | _sorted_nums_vec[i].size() - 1); | 176 | 8 | } | 177 | 8 | } | 178 | | | 179 | 12 | while (!max_heap.empty()) { | 180 | 12 | Node node = max_heap.top(); | 181 | 12 | max_heap.pop(); | 182 | 12 | if (count == target) { | 183 | 2 | second_number = node.value; | 184 | 10 | } else if (count == target + 1) { | 185 | 2 | first_number = node.value; | 186 | 2 | break; | 187 | 2 | } | 188 | 10 | ++count; | 189 | 10 | if (--node.element_index >= 0) { | 190 | 6 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 191 | 6 | max_heap.push(node); | 192 | 6 | } | 193 | 10 | } | 194 | | | 195 | 4 | } else { | 196 | 4 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 197 | 20 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 198 | 16 | if (!_sorted_nums_vec[i].empty()) { | 199 | 16 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 200 | 16 | } | 201 | 16 | } | 202 | | | 203 | 26 | while (!min_heap.empty()) { | 204 | 26 | Node node = min_heap.top(); | 205 | 26 | min_heap.pop(); | 206 | 26 | if (count == target) { | 207 | 4 | first_number = node.value; | 208 | 22 | } else if (count == target + 1) { | 209 | 4 | second_number = node.value; | 210 | 4 | break; | 211 | 4 | } | 212 | 22 | ++count; | 213 | 22 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 214 | 22 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 215 | 22 | min_heap.push(node); | 216 | 22 | } | 217 | 22 | } | 218 | 4 | } | 219 | | | 220 | 6 | return {first_number, second_number}; | 221 | 6 | } |
_ZN5doris6CountsIiE27_merge_sort_and_get_numbersElb Line | Count | Source | 167 | 108 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 168 | 108 | Ty first_number = 0, second_number = 0; | 169 | 108 | size_t count = 0; | 170 | 108 | if (reverse) { | 171 | 16 | std::priority_queue<Node> max_heap; | 172 | 48 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 173 | 32 | if (!_sorted_nums_vec[i].empty()) { | 174 | 32 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 175 | 32 | _sorted_nums_vec[i].size() - 1); | 176 | 32 | } | 177 | 32 | } | 178 | | | 179 | 70 | while (!max_heap.empty()) { | 180 | 70 | Node node = max_heap.top(); | 181 | 70 | max_heap.pop(); | 182 | 70 | if (count == target) { | 183 | 16 | second_number = node.value; | 184 | 54 | } else if (count == target + 1) { | 185 | 16 | first_number = node.value; | 186 | 16 | break; | 187 | 16 | } | 188 | 54 | ++count; | 189 | 54 | if (--node.element_index >= 0) { | 190 | 46 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 191 | 46 | max_heap.push(node); | 192 | 46 | } | 193 | 54 | } | 194 | | | 195 | 92 | } else { | 196 | 92 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 197 | 276 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 198 | 184 | if (!_sorted_nums_vec[i].empty()) { | 199 | 184 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 200 | 184 | } | 201 | 184 | } | 202 | | | 203 | 320 | while (!min_heap.empty()) { | 204 | 320 | Node node = min_heap.top(); | 205 | 320 | min_heap.pop(); | 206 | 320 | if (count == target) { | 207 | 92 | first_number = node.value; | 208 | 228 | } else if (count == target + 1) { | 209 | 92 | second_number = node.value; | 210 | 92 | break; | 211 | 92 | } | 212 | 228 | ++count; | 213 | 228 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 214 | 226 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 215 | 226 | min_heap.push(node); | 216 | 226 | } | 217 | 228 | } | 218 | 92 | } | 219 | | | 220 | 108 | return {first_number, second_number}; | 221 | 108 | } |
_ZN5doris6CountsIlE27_merge_sort_and_get_numbersElb Line | Count | Source | 167 | 37 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 168 | 37 | Ty first_number = 0, second_number = 0; | 169 | 37 | size_t count = 0; | 170 | 37 | if (reverse) { | 171 | 32 | std::priority_queue<Node> max_heap; | 172 | 168 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 173 | 136 | if (!_sorted_nums_vec[i].empty()) { | 174 | 136 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 175 | 136 | _sorted_nums_vec[i].size() - 1); | 176 | 136 | } | 177 | 136 | } | 178 | | | 179 | 150 | while (!max_heap.empty()) { | 180 | 150 | Node node = max_heap.top(); | 181 | 150 | max_heap.pop(); | 182 | 150 | if (count == target) { | 183 | 32 | second_number = node.value; | 184 | 118 | } else if (count == target + 1) { | 185 | 32 | first_number = node.value; | 186 | 32 | break; | 187 | 32 | } | 188 | 118 | ++count; | 189 | 118 | if (--node.element_index >= 0) { | 190 | 92 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 191 | 92 | max_heap.push(node); | 192 | 92 | } | 193 | 118 | } | 194 | | | 195 | 32 | } else { | 196 | 5 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 197 | 15 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 198 | 10 | if (!_sorted_nums_vec[i].empty()) { | 199 | 10 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 200 | 10 | } | 201 | 10 | } | 202 | | | 203 | 17 | while (!min_heap.empty()) { | 204 | 17 | Node node = min_heap.top(); | 205 | 17 | min_heap.pop(); | 206 | 17 | if (count == target) { | 207 | 5 | first_number = node.value; | 208 | 12 | } else if (count == target + 1) { | 209 | 5 | second_number = node.value; | 210 | 5 | break; | 211 | 5 | } | 212 | 12 | ++count; | 213 | 12 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 214 | 12 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 215 | 12 | min_heap.push(node); | 216 | 12 | } | 217 | 12 | } | 218 | 5 | } | 219 | | | 220 | 37 | return {first_number, second_number}; | 221 | 37 | } |
Unexecuted instantiation: _ZN5doris6CountsInE27_merge_sort_and_get_numbersElb Unexecuted instantiation: _ZN5doris6CountsIfE27_merge_sort_and_get_numbersElb _ZN5doris6CountsIdE27_merge_sort_and_get_numbersElb Line | Count | Source | 167 | 36 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 168 | 36 | Ty first_number = 0, second_number = 0; | 169 | 36 | size_t count = 0; | 170 | 36 | if (reverse) { | 171 | 4 | std::priority_queue<Node> max_heap; | 172 | 16 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 173 | 12 | if (!_sorted_nums_vec[i].empty()) { | 174 | 12 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 175 | 12 | _sorted_nums_vec[i].size() - 1); | 176 | 12 | } | 177 | 12 | } | 178 | | | 179 | 10 | while (!max_heap.empty()) { | 180 | 10 | Node node = max_heap.top(); | 181 | 10 | max_heap.pop(); | 182 | 10 | if (count == target) { | 183 | 4 | second_number = node.value; | 184 | 6 | } else if (count == target + 1) { | 185 | 4 | first_number = node.value; | 186 | 4 | break; | 187 | 4 | } | 188 | 6 | ++count; | 189 | 6 | if (--node.element_index >= 0) { | 190 | 2 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 191 | 2 | max_heap.push(node); | 192 | 2 | } | 193 | 6 | } | 194 | | | 195 | 32 | } else { | 196 | 32 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 197 | 116 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 198 | 84 | if (!_sorted_nums_vec[i].empty()) { | 199 | 84 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 200 | 84 | } | 201 | 84 | } | 202 | | | 203 | 80 | while (!min_heap.empty()) { | 204 | 80 | Node node = min_heap.top(); | 205 | 80 | min_heap.pop(); | 206 | 80 | if (count == target) { | 207 | 32 | first_number = node.value; | 208 | 48 | } else if (count == target + 1) { | 209 | 32 | second_number = node.value; | 210 | 32 | break; | 211 | 32 | } | 212 | 48 | ++count; | 213 | 48 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 214 | 12 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 215 | 12 | min_heap.push(node); | 216 | 12 | } | 217 | 48 | } | 218 | 32 | } | 219 | | | 220 | 36 | return {first_number, second_number}; | 221 | 36 | } |
|
222 | | |
223 | | vectorized::PODArray<Ty> _nums; |
224 | | std::vector<vectorized::PODArray<Ty>> _sorted_nums_vec; |
225 | | }; |
226 | | |
227 | | } // namespace doris |