/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 "vec/common/pod_array.h" |
27 | | #include "vec/common/string_buffer.hpp" |
28 | | #include "vec/io/io_helper.h" |
29 | | |
30 | | namespace doris { |
31 | | |
32 | | template <typename Ty> |
33 | | class Counts { |
34 | | public: |
35 | 3.58k | Counts() = default; Line | Count | Source | 35 | 45 | Counts() = default; |
Line | Count | Source | 35 | 215 | Counts() = default; |
Line | Count | Source | 35 | 2.22k | Counts() = default; |
Line | Count | Source | 35 | 758 | Counts() = default; |
Line | Count | Source | 35 | 41 | Counts() = default; |
Line | Count | Source | 35 | 11 | Counts() = default; |
Line | Count | Source | 35 | 292 | Counts() = default; |
|
36 | | |
37 | 1.26k | void merge(Counts* other) { |
38 | 1.26k | if (other != nullptr && !other->_nums.empty()) { |
39 | 1.26k | _sorted_nums_vec.emplace_back(std::move(other->_nums)); |
40 | 1.26k | } |
41 | 1.26k | } _ZN5doris6CountsIaE5mergeEPS1_ Line | Count | Source | 37 | 4 | void merge(Counts* other) { | 38 | 4 | if (other != nullptr && !other->_nums.empty()) { | 39 | 4 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 4 | } | 41 | 4 | } |
_ZN5doris6CountsIsE5mergeEPS1_ Line | Count | Source | 37 | 16 | void merge(Counts* other) { | 38 | 16 | if (other != nullptr && !other->_nums.empty()) { | 39 | 16 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 16 | } | 41 | 16 | } |
_ZN5doris6CountsIiE5mergeEPS1_ Line | Count | Source | 37 | 832 | void merge(Counts* other) { | 38 | 832 | if (other != nullptr && !other->_nums.empty()) { | 39 | 832 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 832 | } | 41 | 832 | } |
_ZN5doris6CountsIlE5mergeEPS1_ Line | Count | Source | 37 | 304 | void merge(Counts* other) { | 38 | 304 | if (other != nullptr && !other->_nums.empty()) { | 39 | 304 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 304 | } | 41 | 304 | } |
_ZN5doris6CountsInE5mergeEPS1_ Line | Count | Source | 37 | 4 | void merge(Counts* other) { | 38 | 4 | if (other != nullptr && !other->_nums.empty()) { | 39 | 4 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 4 | } | 41 | 4 | } |
_ZN5doris6CountsIfE5mergeEPS1_ Line | Count | Source | 37 | 4 | void merge(Counts* other) { | 38 | 4 | if (other != nullptr && !other->_nums.empty()) { | 39 | 4 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 4 | } | 41 | 4 | } |
_ZN5doris6CountsIdE5mergeEPS1_ Line | Count | Source | 37 | 102 | void merge(Counts* other) { | 38 | 102 | if (other != nullptr && !other->_nums.empty()) { | 39 | 102 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 40 | 102 | } | 41 | 102 | } |
|
42 | | |
43 | | void increment(Ty key, uint32_t i) { |
44 | | auto old_size = _nums.size(); |
45 | | _nums.resize(_nums.size() + i); |
46 | | for (uint32_t j = 0; j < i; ++j) { |
47 | | _nums[old_size + j] = key; |
48 | | } |
49 | | } |
50 | | |
51 | 2.93k | void increment(Ty key) { _nums.push_back(key); }_ZN5doris6CountsIaE9incrementEa Line | Count | Source | 51 | 73 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIsE9incrementEs Line | Count | Source | 51 | 552 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIiE9incrementEi Line | Count | Source | 51 | 1.59k | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIlE9incrementEl Line | Count | Source | 51 | 401 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsInE9incrementEn Line | Count | Source | 51 | 45 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIfE9incrementEf Line | Count | Source | 51 | 9 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIdE9incrementEd Line | Count | Source | 51 | 259 | void increment(Ty key) { _nums.push_back(key); } |
|
52 | | |
53 | 5 | void increment_batch(const vectorized::PaddedPODArray<Ty>& keys) { |
54 | 5 | _nums.insert(keys.begin(), keys.end()); |
55 | 5 | } 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 | 53 | 5 | void increment_batch(const vectorized::PaddedPODArray<Ty>& keys) { | 54 | 5 | _nums.insert(keys.begin(), keys.end()); | 55 | 5 | } |
Unexecuted instantiation: _ZN5doris6CountsInE15increment_batchERKNS_10vectorized8PODArrayInLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIfE15increment_batchERKNS_10vectorized8PODArrayIfLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIdE15increment_batchERKNS_10vectorized8PODArrayIdLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEE |
56 | | |
57 | 1.61k | void serialize(vectorized::BufferWritable& buf) { |
58 | 1.61k | if (!_nums.empty()) { |
59 | 1.35k | pdqsort(_nums.begin(), _nums.end()); |
60 | 1.35k | size_t size = _nums.size(); |
61 | 1.35k | buf.write_binary(size); |
62 | 1.35k | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); |
63 | 1.35k | } else { |
64 | | // convert _sorted_nums_vec to _nums and do seiralize again |
65 | 257 | _convert_sorted_num_vec_to_nums(); |
66 | 257 | serialize(buf); |
67 | 257 | } |
68 | 1.61k | } _ZN5doris6CountsIaE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 4 | void serialize(vectorized::BufferWritable& buf) { | 58 | 4 | if (!_nums.empty()) { | 59 | 4 | pdqsort(_nums.begin(), _nums.end()); | 60 | 4 | size_t size = _nums.size(); | 61 | 4 | buf.write_binary(size); | 62 | 4 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 4 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 0 | _convert_sorted_num_vec_to_nums(); | 66 | 0 | serialize(buf); | 67 | 0 | } | 68 | 4 | } |
_ZN5doris6CountsIsE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 16 | void serialize(vectorized::BufferWritable& buf) { | 58 | 16 | if (!_nums.empty()) { | 59 | 16 | pdqsort(_nums.begin(), _nums.end()); | 60 | 16 | size_t size = _nums.size(); | 61 | 16 | buf.write_binary(size); | 62 | 16 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 16 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 0 | _convert_sorted_num_vec_to_nums(); | 66 | 0 | serialize(buf); | 67 | 0 | } | 68 | 16 | } |
_ZN5doris6CountsIiE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 1.06k | void serialize(vectorized::BufferWritable& buf) { | 58 | 1.06k | if (!_nums.empty()) { | 59 | 910 | pdqsort(_nums.begin(), _nums.end()); | 60 | 910 | size_t size = _nums.size(); | 61 | 910 | buf.write_binary(size); | 62 | 910 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 910 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 156 | _convert_sorted_num_vec_to_nums(); | 66 | 156 | serialize(buf); | 67 | 156 | } | 68 | 1.06k | } |
_ZN5doris6CountsIlE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 420 | void serialize(vectorized::BufferWritable& buf) { | 58 | 420 | if (!_nums.empty()) { | 59 | 319 | pdqsort(_nums.begin(), _nums.end()); | 60 | 319 | size_t size = _nums.size(); | 61 | 319 | buf.write_binary(size); | 62 | 319 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 319 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 101 | _convert_sorted_num_vec_to_nums(); | 66 | 101 | serialize(buf); | 67 | 101 | } | 68 | 420 | } |
_ZN5doris6CountsInE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 4 | void serialize(vectorized::BufferWritable& buf) { | 58 | 4 | if (!_nums.empty()) { | 59 | 4 | pdqsort(_nums.begin(), _nums.end()); | 60 | 4 | size_t size = _nums.size(); | 61 | 4 | buf.write_binary(size); | 62 | 4 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 4 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 0 | _convert_sorted_num_vec_to_nums(); | 66 | 0 | serialize(buf); | 67 | 0 | } | 68 | 4 | } |
_ZN5doris6CountsIfE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 4 | void serialize(vectorized::BufferWritable& buf) { | 58 | 4 | if (!_nums.empty()) { | 59 | 4 | pdqsort(_nums.begin(), _nums.end()); | 60 | 4 | size_t size = _nums.size(); | 61 | 4 | buf.write_binary(size); | 62 | 4 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 4 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 0 | _convert_sorted_num_vec_to_nums(); | 66 | 0 | serialize(buf); | 67 | 0 | } | 68 | 4 | } |
_ZN5doris6CountsIdE9serializeERNS_10vectorized14BufferWritableE Line | Count | Source | 57 | 102 | void serialize(vectorized::BufferWritable& buf) { | 58 | 102 | if (!_nums.empty()) { | 59 | 102 | pdqsort(_nums.begin(), _nums.end()); | 60 | 102 | size_t size = _nums.size(); | 61 | 102 | buf.write_binary(size); | 62 | 102 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 63 | 102 | } else { | 64 | | // convert _sorted_nums_vec to _nums and do seiralize again | 65 | 0 | _convert_sorted_num_vec_to_nums(); | 66 | 0 | serialize(buf); | 67 | 0 | } | 68 | 102 | } |
|
69 | | |
70 | 1.26k | void unserialize(vectorized::BufferReadable& buf) { |
71 | 1.26k | size_t size; |
72 | 1.26k | buf.read_binary(size); |
73 | 1.26k | _nums.resize(size); |
74 | 1.26k | auto buff = buf.read(sizeof(Ty) * size); |
75 | 1.26k | memcpy(_nums.data(), buff.data, buff.size); |
76 | 1.26k | } _ZN5doris6CountsIaE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 4 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 4 | size_t size; | 72 | 4 | buf.read_binary(size); | 73 | 4 | _nums.resize(size); | 74 | 4 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 4 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 4 | } |
_ZN5doris6CountsIsE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 16 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 16 | size_t size; | 72 | 16 | buf.read_binary(size); | 73 | 16 | _nums.resize(size); | 74 | 16 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 16 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 16 | } |
_ZN5doris6CountsIiE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 832 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 832 | size_t size; | 72 | 832 | buf.read_binary(size); | 73 | 832 | _nums.resize(size); | 74 | 832 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 832 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 832 | } |
_ZN5doris6CountsIlE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 304 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 304 | size_t size; | 72 | 304 | buf.read_binary(size); | 73 | 304 | _nums.resize(size); | 74 | 304 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 304 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 304 | } |
_ZN5doris6CountsInE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 4 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 4 | size_t size; | 72 | 4 | buf.read_binary(size); | 73 | 4 | _nums.resize(size); | 74 | 4 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 4 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 4 | } |
_ZN5doris6CountsIfE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 4 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 4 | size_t size; | 72 | 4 | buf.read_binary(size); | 73 | 4 | _nums.resize(size); | 74 | 4 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 4 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 4 | } |
_ZN5doris6CountsIdE11unserializeERNS_10vectorized14BufferReadableE Line | Count | Source | 70 | 102 | void unserialize(vectorized::BufferReadable& buf) { | 71 | 102 | size_t size; | 72 | 102 | buf.read_binary(size); | 73 | 102 | _nums.resize(size); | 74 | 102 | auto buff = buf.read(sizeof(Ty) * size); | 75 | 102 | memcpy(_nums.data(), buff.data, buff.size); | 76 | 102 | } |
|
77 | | |
78 | 1.14k | double terminate(double quantile) { |
79 | 1.14k | if (_sorted_nums_vec.size() <= 1) { |
80 | 994 | if (_sorted_nums_vec.size() == 1) { |
81 | 341 | _nums = std::move(_sorted_nums_vec[0]); |
82 | 341 | } |
83 | | |
84 | 994 | if (_nums.empty()) { |
85 | | // Although set null here, but the value is 0.0 and the call method just |
86 | | // get val in aggregate_function_percentile_approx.h |
87 | 0 | return 0.0; |
88 | 0 | } |
89 | | |
90 | 994 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { |
91 | 180 | pdqsort(_nums.begin(), _nums.end()); |
92 | 180 | } |
93 | | |
94 | 994 | if (quantile == 1 || _nums.size() == 1) { |
95 | 476 | return _nums.back(); |
96 | 476 | } |
97 | | |
98 | 518 | double u = (_nums.size() - 1) * quantile; |
99 | 518 | auto index = static_cast<uint32_t>(u); |
100 | 518 | return _nums[index] + |
101 | 518 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - |
102 | 518 | static_cast<double>(_nums[index])); |
103 | 994 | } else { |
104 | 150 | DCHECK(_nums.empty()); |
105 | 150 | size_t rows = 0; |
106 | 383 | for (const auto& i : _sorted_nums_vec) { |
107 | 383 | rows += i.size(); |
108 | 383 | } |
109 | 150 | const bool reverse = quantile > 0.5 && rows > 2; |
110 | 150 | double u = (rows - 1) * quantile; |
111 | 150 | 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 | 150 | size_t target = reverse ? rows - index - 2 : index; |
120 | 150 | if (quantile == 1) { |
121 | 0 | target = 0; |
122 | 0 | } |
123 | 150 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); |
124 | 150 | if (quantile == 1) { |
125 | 0 | return second_number; |
126 | 0 | } |
127 | 150 | return first_number + |
128 | 150 | (u - static_cast<double>(index)) * |
129 | 150 | (static_cast<double>(second_number) - static_cast<double>(first_number)); |
130 | 150 | } |
131 | 1.14k | } _ZN5doris6CountsIaE9terminateEd Line | Count | Source | 78 | 61 | double terminate(double quantile) { | 79 | 61 | if (_sorted_nums_vec.size() <= 1) { | 80 | 60 | if (_sorted_nums_vec.size() == 1) { | 81 | 2 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 2 | } | 83 | | | 84 | 60 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 60 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 24 | pdqsort(_nums.begin(), _nums.end()); | 92 | 24 | } | 93 | | | 94 | 60 | if (quantile == 1 || _nums.size() == 1) { | 95 | 34 | return _nums.back(); | 96 | 34 | } | 97 | | | 98 | 26 | double u = (_nums.size() - 1) * quantile; | 99 | 26 | auto index = static_cast<uint32_t>(u); | 100 | 26 | return _nums[index] + | 101 | 26 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 26 | static_cast<double>(_nums[index])); | 103 | 60 | } else { | 104 | 1 | DCHECK(_nums.empty()); | 105 | 1 | size_t rows = 0; | 106 | 2 | for (const auto& i : _sorted_nums_vec) { | 107 | 2 | rows += i.size(); | 108 | 2 | } | 109 | 1 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 1 | double u = (rows - 1) * quantile; | 111 | 1 | 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 | 1 | size_t target = reverse ? rows - index - 2 : index; | 120 | 1 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 1 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 1 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 1 | return first_number + | 128 | 1 | (u - static_cast<double>(index)) * | 129 | 1 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 1 | } | 131 | 61 | } |
_ZN5doris6CountsIsE9terminateEd Line | Count | Source | 78 | 300 | double terminate(double quantile) { | 79 | 300 | if (_sorted_nums_vec.size() <= 1) { | 80 | 296 | if (_sorted_nums_vec.size() == 1) { | 81 | 2 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 2 | } | 83 | | | 84 | 296 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 296 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 144 | pdqsort(_nums.begin(), _nums.end()); | 92 | 144 | } | 93 | | | 94 | 296 | if (quantile == 1 || _nums.size() == 1) { | 95 | 87 | return _nums.back(); | 96 | 87 | } | 97 | | | 98 | 209 | double u = (_nums.size() - 1) * quantile; | 99 | 209 | auto index = static_cast<uint32_t>(u); | 100 | 209 | return _nums[index] + | 101 | 209 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 209 | static_cast<double>(_nums[index])); | 103 | 296 | } else { | 104 | 4 | DCHECK(_nums.empty()); | 105 | 4 | size_t rows = 0; | 106 | 14 | for (const auto& i : _sorted_nums_vec) { | 107 | 14 | rows += i.size(); | 108 | 14 | } | 109 | 4 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 4 | double u = (rows - 1) * quantile; | 111 | 4 | 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 | 4 | size_t target = reverse ? rows - index - 2 : index; | 120 | 4 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 4 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 4 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 4 | return first_number + | 128 | 4 | (u - static_cast<double>(index)) * | 129 | 4 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 4 | } | 131 | 300 | } |
_ZN5doris6CountsIiE9terminateEd Line | Count | Source | 78 | 483 | double terminate(double quantile) { | 79 | 483 | if (_sorted_nums_vec.size() <= 1) { | 80 | 385 | if (_sorted_nums_vec.size() == 1) { | 81 | 267 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 267 | } | 83 | | | 84 | 385 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 385 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 11 | pdqsort(_nums.begin(), _nums.end()); | 92 | 11 | } | 93 | | | 94 | 385 | if (quantile == 1 || _nums.size() == 1) { | 95 | 242 | return _nums.back(); | 96 | 242 | } | 97 | | | 98 | 143 | double u = (_nums.size() - 1) * quantile; | 99 | 143 | auto index = static_cast<uint32_t>(u); | 100 | 143 | return _nums[index] + | 101 | 143 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 143 | static_cast<double>(_nums[index])); | 103 | 385 | } else { | 104 | 98 | DCHECK(_nums.empty()); | 105 | 98 | size_t rows = 0; | 106 | 226 | for (const auto& i : _sorted_nums_vec) { | 107 | 226 | rows += i.size(); | 108 | 226 | } | 109 | 98 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 98 | double u = (rows - 1) * quantile; | 111 | 98 | 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 | 98 | size_t target = reverse ? rows - index - 2 : index; | 120 | 98 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 98 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 98 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 98 | return first_number + | 128 | 98 | (u - static_cast<double>(index)) * | 129 | 98 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 98 | } | 131 | 483 | } |
_ZN5doris6CountsIlE9terminateEd Line | Count | Source | 78 | 128 | double terminate(double quantile) { | 79 | 128 | if (_sorted_nums_vec.size() <= 1) { | 80 | 108 | if (_sorted_nums_vec.size() == 1) { | 81 | 38 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 38 | } | 83 | | | 84 | 108 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 108 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 1 | pdqsort(_nums.begin(), _nums.end()); | 92 | 1 | } | 93 | | | 94 | 108 | if (quantile == 1 || _nums.size() == 1) { | 95 | 59 | return _nums.back(); | 96 | 59 | } | 97 | | | 98 | 49 | double u = (_nums.size() - 1) * quantile; | 99 | 49 | auto index = static_cast<uint32_t>(u); | 100 | 49 | return _nums[index] + | 101 | 49 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 49 | static_cast<double>(_nums[index])); | 103 | 108 | } else { | 104 | 20 | DCHECK(_nums.empty()); | 105 | 20 | size_t rows = 0; | 106 | 63 | for (const auto& i : _sorted_nums_vec) { | 107 | 63 | rows += i.size(); | 108 | 63 | } | 109 | 20 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 20 | double u = (rows - 1) * quantile; | 111 | 20 | 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 | 20 | size_t target = reverse ? rows - index - 2 : index; | 120 | 20 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 20 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 20 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 20 | return first_number + | 128 | 20 | (u - static_cast<double>(index)) * | 129 | 20 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 20 | } | 131 | 128 | } |
_ZN5doris6CountsInE9terminateEd Line | Count | Source | 78 | 33 | double terminate(double quantile) { | 79 | 33 | if (_sorted_nums_vec.size() <= 1) { | 80 | 32 | if (_sorted_nums_vec.size() == 1) { | 81 | 2 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 2 | } | 83 | | | 84 | 32 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 32 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 0 | pdqsort(_nums.begin(), _nums.end()); | 92 | 0 | } | 93 | | | 94 | 32 | if (quantile == 1 || _nums.size() == 1) { | 95 | 24 | return _nums.back(); | 96 | 24 | } | 97 | | | 98 | 8 | double u = (_nums.size() - 1) * quantile; | 99 | 8 | auto index = static_cast<uint32_t>(u); | 100 | 8 | return _nums[index] + | 101 | 8 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 8 | static_cast<double>(_nums[index])); | 103 | 32 | } else { | 104 | 1 | DCHECK(_nums.empty()); | 105 | 1 | size_t rows = 0; | 106 | 2 | for (const auto& i : _sorted_nums_vec) { | 107 | 2 | rows += i.size(); | 108 | 2 | } | 109 | 1 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 1 | double u = (rows - 1) * quantile; | 111 | 1 | 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 | 1 | size_t target = reverse ? rows - index - 2 : index; | 120 | 1 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 1 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 1 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 1 | return first_number + | 128 | 1 | (u - static_cast<double>(index)) * | 129 | 1 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 1 | } | 131 | 33 | } |
_ZN5doris6CountsIfE9terminateEd Line | Count | Source | 78 | 3 | double terminate(double quantile) { | 79 | 3 | if (_sorted_nums_vec.size() <= 1) { | 80 | 2 | if (_sorted_nums_vec.size() == 1) { | 81 | 2 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 2 | } | 83 | | | 84 | 2 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 2 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 0 | pdqsort(_nums.begin(), _nums.end()); | 92 | 0 | } | 93 | | | 94 | 2 | if (quantile == 1 || _nums.size() == 1) { | 95 | 0 | return _nums.back(); | 96 | 0 | } | 97 | | | 98 | 2 | double u = (_nums.size() - 1) * quantile; | 99 | 2 | auto index = static_cast<uint32_t>(u); | 100 | 2 | return _nums[index] + | 101 | 2 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 2 | static_cast<double>(_nums[index])); | 103 | 2 | } else { | 104 | 1 | DCHECK(_nums.empty()); | 105 | 1 | size_t rows = 0; | 106 | 2 | for (const auto& i : _sorted_nums_vec) { | 107 | 2 | rows += i.size(); | 108 | 2 | } | 109 | 1 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 1 | double u = (rows - 1) * quantile; | 111 | 1 | 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 | 1 | size_t target = reverse ? rows - index - 2 : index; | 120 | 1 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 1 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 1 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 1 | return first_number + | 128 | 1 | (u - static_cast<double>(index)) * | 129 | 1 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 1 | } | 131 | 3 | } |
_ZN5doris6CountsIdE9terminateEd Line | Count | Source | 78 | 136 | double terminate(double quantile) { | 79 | 136 | if (_sorted_nums_vec.size() <= 1) { | 80 | 111 | if (_sorted_nums_vec.size() == 1) { | 81 | 28 | _nums = std::move(_sorted_nums_vec[0]); | 82 | 28 | } | 83 | | | 84 | 111 | if (_nums.empty()) { | 85 | | // Although set null here, but the value is 0.0 and the call method just | 86 | | // get val in aggregate_function_percentile_approx.h | 87 | 0 | return 0.0; | 88 | 0 | } | 89 | | | 90 | 111 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 91 | 0 | pdqsort(_nums.begin(), _nums.end()); | 92 | 0 | } | 93 | | | 94 | 111 | if (quantile == 1 || _nums.size() == 1) { | 95 | 30 | return _nums.back(); | 96 | 30 | } | 97 | | | 98 | 81 | double u = (_nums.size() - 1) * quantile; | 99 | 81 | auto index = static_cast<uint32_t>(u); | 100 | 81 | return _nums[index] + | 101 | 81 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 102 | 81 | static_cast<double>(_nums[index])); | 103 | 111 | } else { | 104 | 25 | DCHECK(_nums.empty()); | 105 | 25 | size_t rows = 0; | 106 | 74 | for (const auto& i : _sorted_nums_vec) { | 107 | 74 | rows += i.size(); | 108 | 74 | } | 109 | 25 | const bool reverse = quantile > 0.5 && rows > 2; | 110 | 25 | double u = (rows - 1) * quantile; | 111 | 25 | 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 | 25 | size_t target = reverse ? rows - index - 2 : index; | 120 | 25 | if (quantile == 1) { | 121 | 0 | target = 0; | 122 | 0 | } | 123 | 25 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 124 | 25 | if (quantile == 1) { | 125 | 0 | return second_number; | 126 | 0 | } | 127 | 25 | return first_number + | 128 | 25 | (u - static_cast<double>(index)) * | 129 | 25 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 130 | 25 | } | 131 | 136 | } |
|
132 | | |
133 | | private: |
134 | | struct Node { |
135 | | Ty value; |
136 | | int array_index; |
137 | | int64_t element_index; |
138 | | |
139 | 1.23k | auto operator<=>(const Node& other) const { return value <=> other.value; }_ZNK5doris6CountsIaE4NodessERKS2_ Line | Count | Source | 139 | 2 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIsE4NodessERKS2_ Line | Count | Source | 139 | 70 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIiE4NodessERKS2_ Line | Count | Source | 139 | 680 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIlE4NodessERKS2_ Line | Count | Source | 139 | 390 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsInE4NodessERKS2_ Line | Count | Source | 139 | 2 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIfE4NodessERKS2_ Line | Count | Source | 139 | 2 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIdE4NodessERKS2_ Line | Count | Source | 139 | 93 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
|
140 | | }; |
141 | | |
142 | 257 | void _convert_sorted_num_vec_to_nums() { |
143 | 257 | size_t rows = 0; |
144 | 542 | for (const auto& i : _sorted_nums_vec) { |
145 | 542 | rows += i.size(); |
146 | 542 | } |
147 | 257 | _nums.resize(rows); |
148 | 257 | size_t count = 0; |
149 | | |
150 | 257 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; |
151 | 799 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
152 | 542 | if (!_sorted_nums_vec[i].empty()) { |
153 | 542 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); |
154 | 542 | } |
155 | 542 | } |
156 | | |
157 | 931 | while (!min_heap.empty()) { |
158 | 674 | Node node = min_heap.top(); |
159 | 674 | min_heap.pop(); |
160 | 674 | _nums[count++] = node.value; |
161 | 674 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { |
162 | 132 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
163 | 132 | min_heap.push(node); |
164 | 132 | } |
165 | 674 | } |
166 | 257 | _sorted_nums_vec.clear(); |
167 | 257 | } 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 | 142 | 156 | void _convert_sorted_num_vec_to_nums() { | 143 | 156 | size_t rows = 0; | 144 | 339 | for (const auto& i : _sorted_nums_vec) { | 145 | 339 | rows += i.size(); | 146 | 339 | } | 147 | 156 | _nums.resize(rows); | 148 | 156 | size_t count = 0; | 149 | | | 150 | 156 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 151 | 495 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 152 | 339 | if (!_sorted_nums_vec[i].empty()) { | 153 | 339 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 154 | 339 | } | 155 | 339 | } | 156 | | | 157 | 531 | while (!min_heap.empty()) { | 158 | 375 | Node node = min_heap.top(); | 159 | 375 | min_heap.pop(); | 160 | 375 | _nums[count++] = node.value; | 161 | 375 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 162 | 36 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 163 | 36 | min_heap.push(node); | 164 | 36 | } | 165 | 375 | } | 166 | 156 | _sorted_nums_vec.clear(); | 167 | 156 | } |
_ZN5doris6CountsIlE31_convert_sorted_num_vec_to_numsEv Line | Count | Source | 142 | 101 | void _convert_sorted_num_vec_to_nums() { | 143 | 101 | size_t rows = 0; | 144 | 203 | for (const auto& i : _sorted_nums_vec) { | 145 | 203 | rows += i.size(); | 146 | 203 | } | 147 | 101 | _nums.resize(rows); | 148 | 101 | size_t count = 0; | 149 | | | 150 | 101 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 151 | 304 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 152 | 203 | if (!_sorted_nums_vec[i].empty()) { | 153 | 203 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 154 | 203 | } | 155 | 203 | } | 156 | | | 157 | 400 | while (!min_heap.empty()) { | 158 | 299 | Node node = min_heap.top(); | 159 | 299 | min_heap.pop(); | 160 | 299 | _nums[count++] = node.value; | 161 | 299 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 162 | 96 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 163 | 96 | min_heap.push(node); | 164 | 96 | } | 165 | 299 | } | 166 | 101 | _sorted_nums_vec.clear(); | 167 | 101 | } |
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 |
168 | | |
169 | 150 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { |
170 | 150 | Ty first_number = 0, second_number = 0; |
171 | 150 | size_t count = 0; |
172 | 150 | if (reverse) { |
173 | 27 | std::priority_queue<Node> max_heap; |
174 | 113 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
175 | 86 | if (!_sorted_nums_vec[i].empty()) { |
176 | 86 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, |
177 | 86 | _sorted_nums_vec[i].size() - 1); |
178 | 86 | } |
179 | 86 | } |
180 | | |
181 | 111 | while (!max_heap.empty()) { |
182 | 111 | Node node = max_heap.top(); |
183 | 111 | max_heap.pop(); |
184 | 111 | if (count == target) { |
185 | 27 | second_number = node.value; |
186 | 84 | } else if (count == target + 1) { |
187 | 27 | first_number = node.value; |
188 | 27 | break; |
189 | 27 | } |
190 | 84 | ++count; |
191 | 84 | if (--node.element_index >= 0) { |
192 | 65 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
193 | 65 | max_heap.push(node); |
194 | 65 | } |
195 | 84 | } |
196 | | |
197 | 123 | } else { |
198 | 123 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; |
199 | 420 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
200 | 297 | if (!_sorted_nums_vec[i].empty()) { |
201 | 297 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); |
202 | 297 | } |
203 | 297 | } |
204 | | |
205 | 346 | while (!min_heap.empty()) { |
206 | 346 | Node node = min_heap.top(); |
207 | 346 | min_heap.pop(); |
208 | 346 | if (count == target) { |
209 | 123 | first_number = node.value; |
210 | 223 | } else if (count == target + 1) { |
211 | 123 | second_number = node.value; |
212 | 123 | break; |
213 | 123 | } |
214 | 223 | ++count; |
215 | 223 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { |
216 | 148 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
217 | 148 | min_heap.push(node); |
218 | 148 | } |
219 | 223 | } |
220 | 123 | } |
221 | | |
222 | 150 | return {first_number, second_number}; |
223 | 150 | } _ZN5doris6CountsIaE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 1 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 1 | Ty first_number = 0, second_number = 0; | 171 | 1 | size_t count = 0; | 172 | 1 | if (reverse) { | 173 | 0 | std::priority_queue<Node> max_heap; | 174 | 0 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 0 | if (!_sorted_nums_vec[i].empty()) { | 176 | 0 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 0 | _sorted_nums_vec[i].size() - 1); | 178 | 0 | } | 179 | 0 | } | 180 | |
| 181 | 0 | while (!max_heap.empty()) { | 182 | 0 | Node node = max_heap.top(); | 183 | 0 | max_heap.pop(); | 184 | 0 | if (count == target) { | 185 | 0 | second_number = node.value; | 186 | 0 | } else if (count == target + 1) { | 187 | 0 | first_number = node.value; | 188 | 0 | break; | 189 | 0 | } | 190 | 0 | ++count; | 191 | 0 | if (--node.element_index >= 0) { | 192 | 0 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 0 | max_heap.push(node); | 194 | 0 | } | 195 | 0 | } | 196 | |
| 197 | 1 | } else { | 198 | 1 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 2 | if (!_sorted_nums_vec[i].empty()) { | 201 | 2 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 2 | } | 203 | 2 | } | 204 | | | 205 | 3 | while (!min_heap.empty()) { | 206 | 3 | Node node = min_heap.top(); | 207 | 3 | min_heap.pop(); | 208 | 3 | if (count == target) { | 209 | 1 | first_number = node.value; | 210 | 2 | } else if (count == target + 1) { | 211 | 1 | second_number = node.value; | 212 | 1 | break; | 213 | 1 | } | 214 | 2 | ++count; | 215 | 2 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 1 | min_heap.push(node); | 218 | 1 | } | 219 | 2 | } | 220 | 1 | } | 221 | | | 222 | 1 | return {first_number, second_number}; | 223 | 1 | } |
_ZN5doris6CountsIsE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 4 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 4 | Ty first_number = 0, second_number = 0; | 171 | 4 | size_t count = 0; | 172 | 4 | if (reverse) { | 173 | 1 | std::priority_queue<Node> max_heap; | 174 | 5 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 4 | if (!_sorted_nums_vec[i].empty()) { | 176 | 4 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 4 | _sorted_nums_vec[i].size() - 1); | 178 | 4 | } | 179 | 4 | } | 180 | | | 181 | 6 | while (!max_heap.empty()) { | 182 | 6 | Node node = max_heap.top(); | 183 | 6 | max_heap.pop(); | 184 | 6 | if (count == target) { | 185 | 1 | second_number = node.value; | 186 | 5 | } else if (count == target + 1) { | 187 | 1 | first_number = node.value; | 188 | 1 | break; | 189 | 1 | } | 190 | 5 | ++count; | 191 | 5 | if (--node.element_index >= 0) { | 192 | 3 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 3 | max_heap.push(node); | 194 | 3 | } | 195 | 5 | } | 196 | | | 197 | 3 | } else { | 198 | 3 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 13 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 10 | if (!_sorted_nums_vec[i].empty()) { | 201 | 10 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 10 | } | 203 | 10 | } | 204 | | | 205 | 16 | while (!min_heap.empty()) { | 206 | 16 | Node node = min_heap.top(); | 207 | 16 | min_heap.pop(); | 208 | 16 | if (count == target) { | 209 | 3 | first_number = node.value; | 210 | 13 | } else if (count == target + 1) { | 211 | 3 | second_number = node.value; | 212 | 3 | break; | 213 | 3 | } | 214 | 13 | ++count; | 215 | 13 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 12 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 12 | min_heap.push(node); | 218 | 12 | } | 219 | 13 | } | 220 | 3 | } | 221 | | | 222 | 4 | return {first_number, second_number}; | 223 | 4 | } |
_ZN5doris6CountsIiE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 98 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 98 | Ty first_number = 0, second_number = 0; | 171 | 98 | size_t count = 0; | 172 | 98 | if (reverse) { | 173 | 10 | std::priority_queue<Node> max_heap; | 174 | 34 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 24 | if (!_sorted_nums_vec[i].empty()) { | 176 | 24 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 24 | _sorted_nums_vec[i].size() - 1); | 178 | 24 | } | 179 | 24 | } | 180 | | | 181 | 39 | while (!max_heap.empty()) { | 182 | 39 | Node node = max_heap.top(); | 183 | 39 | max_heap.pop(); | 184 | 39 | if (count == target) { | 185 | 10 | second_number = node.value; | 186 | 29 | } else if (count == target + 1) { | 187 | 10 | first_number = node.value; | 188 | 10 | break; | 189 | 10 | } | 190 | 29 | ++count; | 191 | 29 | if (--node.element_index >= 0) { | 192 | 22 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 22 | max_heap.push(node); | 194 | 22 | } | 195 | 29 | } | 196 | | | 197 | 88 | } else { | 198 | 88 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 290 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 202 | if (!_sorted_nums_vec[i].empty()) { | 201 | 202 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 202 | } | 203 | 202 | } | 204 | | | 205 | 247 | while (!min_heap.empty()) { | 206 | 247 | Node node = min_heap.top(); | 207 | 247 | min_heap.pop(); | 208 | 247 | if (count == target) { | 209 | 88 | first_number = node.value; | 210 | 159 | } else if (count == target + 1) { | 211 | 88 | second_number = node.value; | 212 | 88 | break; | 213 | 88 | } | 214 | 159 | ++count; | 215 | 159 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 117 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 117 | min_heap.push(node); | 218 | 117 | } | 219 | 159 | } | 220 | 88 | } | 221 | | | 222 | 98 | return {first_number, second_number}; | 223 | 98 | } |
_ZN5doris6CountsIlE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 20 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 20 | Ty first_number = 0, second_number = 0; | 171 | 20 | size_t count = 0; | 172 | 20 | if (reverse) { | 173 | 14 | std::priority_queue<Node> max_heap; | 174 | 64 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 50 | if (!_sorted_nums_vec[i].empty()) { | 176 | 50 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 50 | _sorted_nums_vec[i].size() - 1); | 178 | 50 | } | 179 | 50 | } | 180 | | | 181 | 61 | while (!max_heap.empty()) { | 182 | 61 | Node node = max_heap.top(); | 183 | 61 | max_heap.pop(); | 184 | 61 | if (count == target) { | 185 | 14 | second_number = node.value; | 186 | 47 | } else if (count == target + 1) { | 187 | 14 | first_number = node.value; | 188 | 14 | break; | 189 | 14 | } | 190 | 47 | ++count; | 191 | 47 | if (--node.element_index >= 0) { | 192 | 40 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 40 | max_heap.push(node); | 194 | 40 | } | 195 | 47 | } | 196 | | | 197 | 14 | } else { | 198 | 6 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 19 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 13 | if (!_sorted_nums_vec[i].empty()) { | 201 | 13 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 13 | } | 203 | 13 | } | 204 | | | 205 | 19 | while (!min_heap.empty()) { | 206 | 19 | Node node = min_heap.top(); | 207 | 19 | min_heap.pop(); | 208 | 19 | if (count == target) { | 209 | 6 | first_number = node.value; | 210 | 13 | } else if (count == target + 1) { | 211 | 6 | second_number = node.value; | 212 | 6 | break; | 213 | 6 | } | 214 | 13 | ++count; | 215 | 13 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 11 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 11 | min_heap.push(node); | 218 | 11 | } | 219 | 13 | } | 220 | 6 | } | 221 | | | 222 | 20 | return {first_number, second_number}; | 223 | 20 | } |
_ZN5doris6CountsInE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 1 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 1 | Ty first_number = 0, second_number = 0; | 171 | 1 | size_t count = 0; | 172 | 1 | if (reverse) { | 173 | 0 | std::priority_queue<Node> max_heap; | 174 | 0 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 0 | if (!_sorted_nums_vec[i].empty()) { | 176 | 0 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 0 | _sorted_nums_vec[i].size() - 1); | 178 | 0 | } | 179 | 0 | } | 180 | |
| 181 | 0 | while (!max_heap.empty()) { | 182 | 0 | Node node = max_heap.top(); | 183 | 0 | max_heap.pop(); | 184 | 0 | if (count == target) { | 185 | 0 | second_number = node.value; | 186 | 0 | } else if (count == target + 1) { | 187 | 0 | first_number = node.value; | 188 | 0 | break; | 189 | 0 | } | 190 | 0 | ++count; | 191 | 0 | if (--node.element_index >= 0) { | 192 | 0 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 0 | max_heap.push(node); | 194 | 0 | } | 195 | 0 | } | 196 | |
| 197 | 1 | } else { | 198 | 1 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 2 | if (!_sorted_nums_vec[i].empty()) { | 201 | 2 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 2 | } | 203 | 2 | } | 204 | | | 205 | 3 | while (!min_heap.empty()) { | 206 | 3 | Node node = min_heap.top(); | 207 | 3 | min_heap.pop(); | 208 | 3 | if (count == target) { | 209 | 1 | first_number = node.value; | 210 | 2 | } else if (count == target + 1) { | 211 | 1 | second_number = node.value; | 212 | 1 | break; | 213 | 1 | } | 214 | 2 | ++count; | 215 | 2 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 1 | min_heap.push(node); | 218 | 1 | } | 219 | 2 | } | 220 | 1 | } | 221 | | | 222 | 1 | return {first_number, second_number}; | 223 | 1 | } |
_ZN5doris6CountsIfE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 1 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 1 | Ty first_number = 0, second_number = 0; | 171 | 1 | size_t count = 0; | 172 | 1 | if (reverse) { | 173 | 0 | std::priority_queue<Node> max_heap; | 174 | 0 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 0 | if (!_sorted_nums_vec[i].empty()) { | 176 | 0 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 0 | _sorted_nums_vec[i].size() - 1); | 178 | 0 | } | 179 | 0 | } | 180 | |
| 181 | 0 | while (!max_heap.empty()) { | 182 | 0 | Node node = max_heap.top(); | 183 | 0 | max_heap.pop(); | 184 | 0 | if (count == target) { | 185 | 0 | second_number = node.value; | 186 | 0 | } else if (count == target + 1) { | 187 | 0 | first_number = node.value; | 188 | 0 | break; | 189 | 0 | } | 190 | 0 | ++count; | 191 | 0 | if (--node.element_index >= 0) { | 192 | 0 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 0 | max_heap.push(node); | 194 | 0 | } | 195 | 0 | } | 196 | |
| 197 | 1 | } else { | 198 | 1 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 2 | if (!_sorted_nums_vec[i].empty()) { | 201 | 2 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 2 | } | 203 | 2 | } | 204 | | | 205 | 3 | while (!min_heap.empty()) { | 206 | 3 | Node node = min_heap.top(); | 207 | 3 | min_heap.pop(); | 208 | 3 | if (count == target) { | 209 | 1 | first_number = node.value; | 210 | 2 | } else if (count == target + 1) { | 211 | 1 | second_number = node.value; | 212 | 1 | break; | 213 | 1 | } | 214 | 2 | ++count; | 215 | 2 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 1 | min_heap.push(node); | 218 | 1 | } | 219 | 2 | } | 220 | 1 | } | 221 | | | 222 | 1 | return {first_number, second_number}; | 223 | 1 | } |
_ZN5doris6CountsIdE27_merge_sort_and_get_numbersElb Line | Count | Source | 169 | 25 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 170 | 25 | Ty first_number = 0, second_number = 0; | 171 | 25 | size_t count = 0; | 172 | 25 | if (reverse) { | 173 | 2 | std::priority_queue<Node> max_heap; | 174 | 10 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 175 | 8 | if (!_sorted_nums_vec[i].empty()) { | 176 | 8 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 177 | 8 | _sorted_nums_vec[i].size() - 1); | 178 | 8 | } | 179 | 8 | } | 180 | | | 181 | 5 | while (!max_heap.empty()) { | 182 | 5 | Node node = max_heap.top(); | 183 | 5 | max_heap.pop(); | 184 | 5 | if (count == target) { | 185 | 2 | second_number = node.value; | 186 | 3 | } else if (count == target + 1) { | 187 | 2 | first_number = node.value; | 188 | 2 | break; | 189 | 2 | } | 190 | 3 | ++count; | 191 | 3 | if (--node.element_index >= 0) { | 192 | 0 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 193 | 0 | max_heap.push(node); | 194 | 0 | } | 195 | 3 | } | 196 | | | 197 | 23 | } else { | 198 | 23 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 199 | 89 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 200 | 66 | if (!_sorted_nums_vec[i].empty()) { | 201 | 66 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 202 | 66 | } | 203 | 66 | } | 204 | | | 205 | 55 | while (!min_heap.empty()) { | 206 | 55 | Node node = min_heap.top(); | 207 | 55 | min_heap.pop(); | 208 | 55 | if (count == target) { | 209 | 23 | first_number = node.value; | 210 | 32 | } else if (count == target + 1) { | 211 | 23 | second_number = node.value; | 212 | 23 | break; | 213 | 23 | } | 214 | 32 | ++count; | 215 | 32 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 216 | 5 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 217 | 5 | min_heap.push(node); | 218 | 5 | } | 219 | 32 | } | 220 | 23 | } | 221 | | | 222 | 25 | return {first_number, second_number}; | 223 | 25 | } |
|
224 | | |
225 | | vectorized::PODArray<Ty> _nums; |
226 | | std::vector<vectorized::PODArray<Ty>> _sorted_nums_vec; |
227 | | }; |
228 | | |
229 | | } // namespace doris |