/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 "core/pod_array.h" |
27 | | #include "core/string_buffer.hpp" |
28 | | |
29 | | namespace doris { |
30 | | |
31 | | template <typename Ty> |
32 | | class Counts { |
33 | | public: |
34 | 3.46k | Counts() = default; Line | Count | Source | 34 | 47 | Counts() = default; |
Line | Count | Source | 34 | 205 | Counts() = default; |
Line | Count | Source | 34 | 2.12k | Counts() = default; |
Line | Count | Source | 34 | 782 | Counts() = default; |
Line | Count | Source | 34 | 43 | Counts() = default; |
Line | Count | Source | 34 | 13 | Counts() = default; |
Line | Count | Source | 34 | 246 | Counts() = default; |
|
35 | | |
36 | 1.20k | void merge(Counts* other) { |
37 | 1.20k | if (other != nullptr && !other->_nums.empty()) { |
38 | 1.20k | _sorted_nums_vec.emplace_back(std::move(other->_nums)); |
39 | 1.20k | } |
40 | 1.20k | } _ZN5doris6CountsIaE5mergeEPS1_ Line | Count | Source | 36 | 5 | void merge(Counts* other) { | 37 | 5 | if (other != nullptr && !other->_nums.empty()) { | 38 | 5 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 5 | } | 40 | 5 | } |
_ZN5doris6CountsIsE5mergeEPS1_ Line | Count | Source | 36 | 11 | void merge(Counts* other) { | 37 | 11 | if (other != nullptr && !other->_nums.empty()) { | 38 | 11 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 11 | } | 40 | 11 | } |
_ZN5doris6CountsIiE5mergeEPS1_ Line | Count | Source | 36 | 783 | void merge(Counts* other) { | 37 | 783 | if (other != nullptr && !other->_nums.empty()) { | 38 | 783 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 783 | } | 40 | 783 | } |
_ZN5doris6CountsIlE5mergeEPS1_ Line | Count | Source | 36 | 316 | void merge(Counts* other) { | 37 | 316 | if (other != nullptr && !other->_nums.empty()) { | 38 | 316 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 316 | } | 40 | 316 | } |
_ZN5doris6CountsInE5mergeEPS1_ Line | Count | Source | 36 | 5 | void merge(Counts* other) { | 37 | 5 | if (other != nullptr && !other->_nums.empty()) { | 38 | 5 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 5 | } | 40 | 5 | } |
_ZN5doris6CountsIfE5mergeEPS1_ Line | Count | Source | 36 | 5 | void merge(Counts* other) { | 37 | 5 | if (other != nullptr && !other->_nums.empty()) { | 38 | 5 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 5 | } | 40 | 5 | } |
_ZN5doris6CountsIdE5mergeEPS1_ Line | Count | Source | 36 | 79 | void merge(Counts* other) { | 37 | 79 | if (other != nullptr && !other->_nums.empty()) { | 38 | 79 | _sorted_nums_vec.emplace_back(std::move(other->_nums)); | 39 | 79 | } | 40 | 79 | } |
|
41 | | |
42 | | void increment(Ty key, uint32_t i) { |
43 | | auto old_size = _nums.size(); |
44 | | _nums.resize(_nums.size() + i); |
45 | | for (uint32_t j = 0; j < i; ++j) { |
46 | | _nums[old_size + j] = key; |
47 | | } |
48 | | } |
49 | | |
50 | 2.92k | void increment(Ty key) { _nums.push_back(key); }_ZN5doris6CountsIaE9incrementEa Line | Count | Source | 50 | 73 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIsE9incrementEs Line | Count | Source | 50 | 552 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIiE9incrementEi Line | Count | Source | 50 | 1.59k | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIlE9incrementEl Line | Count | Source | 50 | 401 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsInE9incrementEn Line | Count | Source | 50 | 44 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIfE9incrementEf Line | Count | Source | 50 | 9 | void increment(Ty key) { _nums.push_back(key); } |
_ZN5doris6CountsIdE9incrementEd Line | Count | Source | 50 | 259 | void increment(Ty key) { _nums.push_back(key); } |
|
51 | | |
52 | 5 | void increment_batch(const PaddedPODArray<Ty>& keys) { _nums.insert(keys.begin(), keys.end()); }Unexecuted instantiation: _ZN5doris6CountsIaE15increment_batchERKNS_8PODArrayIaLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIsE15increment_batchERKNS_8PODArrayIsLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIiE15increment_batchERKNS_8PODArrayIiLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE _ZN5doris6CountsIlE15increment_batchERKNS_8PODArrayIlLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE Line | Count | Source | 52 | 5 | void increment_batch(const PaddedPODArray<Ty>& keys) { _nums.insert(keys.begin(), keys.end()); } |
Unexecuted instantiation: _ZN5doris6CountsInE15increment_batchERKNS_8PODArrayInLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIfE15increment_batchERKNS_8PODArrayIfLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE Unexecuted instantiation: _ZN5doris6CountsIdE15increment_batchERKNS_8PODArrayIdLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEE |
53 | | |
54 | 1.62k | void serialize(BufferWritable& buf) { |
55 | 1.62k | if (!_nums.empty()) { |
56 | 1.33k | pdqsort(_nums.begin(), _nums.end()); |
57 | 1.33k | size_t size = _nums.size(); |
58 | 1.33k | buf.write_binary(size); |
59 | 1.33k | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); |
60 | 1.33k | } else { |
61 | | // convert _sorted_nums_vec to _nums and do seiralize again |
62 | 288 | _convert_sorted_num_vec_to_nums(); |
63 | 288 | serialize(buf); |
64 | 288 | } |
65 | 1.62k | } _ZN5doris6CountsIaE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 5 | void serialize(BufferWritable& buf) { | 55 | 5 | if (!_nums.empty()) { | 56 | 5 | pdqsort(_nums.begin(), _nums.end()); | 57 | 5 | size_t size = _nums.size(); | 58 | 5 | buf.write_binary(size); | 59 | 5 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 5 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 0 | _convert_sorted_num_vec_to_nums(); | 63 | 0 | serialize(buf); | 64 | 0 | } | 65 | 5 | } |
_ZN5doris6CountsIsE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 11 | void serialize(BufferWritable& buf) { | 55 | 11 | if (!_nums.empty()) { | 56 | 11 | pdqsort(_nums.begin(), _nums.end()); | 57 | 11 | size_t size = _nums.size(); | 58 | 11 | buf.write_binary(size); | 59 | 11 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 11 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 0 | _convert_sorted_num_vec_to_nums(); | 63 | 0 | serialize(buf); | 64 | 0 | } | 65 | 11 | } |
_ZN5doris6CountsIiE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 1.05k | void serialize(BufferWritable& buf) { | 55 | 1.05k | if (!_nums.empty()) { | 56 | 900 | pdqsort(_nums.begin(), _nums.end()); | 57 | 900 | size_t size = _nums.size(); | 58 | 900 | buf.write_binary(size); | 59 | 900 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 900 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 156 | _convert_sorted_num_vec_to_nums(); | 63 | 156 | serialize(buf); | 64 | 156 | } | 65 | 1.05k | } |
_ZN5doris6CountsIlE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 463 | void serialize(BufferWritable& buf) { | 55 | 463 | if (!_nums.empty()) { | 56 | 331 | pdqsort(_nums.begin(), _nums.end()); | 57 | 331 | size_t size = _nums.size(); | 58 | 331 | buf.write_binary(size); | 59 | 331 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 331 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 132 | _convert_sorted_num_vec_to_nums(); | 63 | 132 | serialize(buf); | 64 | 132 | } | 65 | 463 | } |
_ZN5doris6CountsInE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 5 | void serialize(BufferWritable& buf) { | 55 | 5 | if (!_nums.empty()) { | 56 | 5 | pdqsort(_nums.begin(), _nums.end()); | 57 | 5 | size_t size = _nums.size(); | 58 | 5 | buf.write_binary(size); | 59 | 5 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 5 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 0 | _convert_sorted_num_vec_to_nums(); | 63 | 0 | serialize(buf); | 64 | 0 | } | 65 | 5 | } |
_ZN5doris6CountsIfE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 5 | void serialize(BufferWritable& buf) { | 55 | 5 | if (!_nums.empty()) { | 56 | 5 | pdqsort(_nums.begin(), _nums.end()); | 57 | 5 | size_t size = _nums.size(); | 58 | 5 | buf.write_binary(size); | 59 | 5 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 5 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 0 | _convert_sorted_num_vec_to_nums(); | 63 | 0 | serialize(buf); | 64 | 0 | } | 65 | 5 | } |
_ZN5doris6CountsIdE9serializeERNS_14BufferWritableE Line | Count | Source | 54 | 79 | void serialize(BufferWritable& buf) { | 55 | 79 | if (!_nums.empty()) { | 56 | 79 | pdqsort(_nums.begin(), _nums.end()); | 57 | 79 | size_t size = _nums.size(); | 58 | 79 | buf.write_binary(size); | 59 | 79 | buf.write(reinterpret_cast<const char*>(_nums.data()), sizeof(Ty) * size); | 60 | 79 | } else { | 61 | | // convert _sorted_nums_vec to _nums and do seiralize again | 62 | 0 | _convert_sorted_num_vec_to_nums(); | 63 | 0 | serialize(buf); | 64 | 0 | } | 65 | 79 | } |
|
66 | | |
67 | 1.20k | void unserialize(BufferReadable& buf) { |
68 | 1.20k | size_t size; |
69 | 1.20k | buf.read_binary(size); |
70 | 1.20k | _nums.resize(size); |
71 | 1.20k | auto buff = buf.read(sizeof(Ty) * size); |
72 | 1.20k | memcpy(_nums.data(), buff.data, buff.size); |
73 | 1.20k | } _ZN5doris6CountsIaE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 5 | void unserialize(BufferReadable& buf) { | 68 | 5 | size_t size; | 69 | 5 | buf.read_binary(size); | 70 | 5 | _nums.resize(size); | 71 | 5 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 5 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 5 | } |
_ZN5doris6CountsIsE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 11 | void unserialize(BufferReadable& buf) { | 68 | 11 | size_t size; | 69 | 11 | buf.read_binary(size); | 70 | 11 | _nums.resize(size); | 71 | 11 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 11 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 11 | } |
_ZN5doris6CountsIiE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 783 | void unserialize(BufferReadable& buf) { | 68 | 783 | size_t size; | 69 | 783 | buf.read_binary(size); | 70 | 783 | _nums.resize(size); | 71 | 783 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 783 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 783 | } |
_ZN5doris6CountsIlE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 316 | void unserialize(BufferReadable& buf) { | 68 | 316 | size_t size; | 69 | 316 | buf.read_binary(size); | 70 | 316 | _nums.resize(size); | 71 | 316 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 316 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 316 | } |
_ZN5doris6CountsInE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 5 | void unserialize(BufferReadable& buf) { | 68 | 5 | size_t size; | 69 | 5 | buf.read_binary(size); | 70 | 5 | _nums.resize(size); | 71 | 5 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 5 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 5 | } |
_ZN5doris6CountsIfE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 5 | void unserialize(BufferReadable& buf) { | 68 | 5 | size_t size; | 69 | 5 | buf.read_binary(size); | 70 | 5 | _nums.resize(size); | 71 | 5 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 5 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 5 | } |
_ZN5doris6CountsIdE11unserializeERNS_14BufferReadableE Line | Count | Source | 67 | 79 | void unserialize(BufferReadable& buf) { | 68 | 79 | size_t size; | 69 | 79 | buf.read_binary(size); | 70 | 79 | _nums.resize(size); | 71 | 79 | auto buff = buf.read(sizeof(Ty) * size); | 72 | 79 | memcpy(_nums.data(), buff.data, buff.size); | 73 | 79 | } |
|
74 | | |
75 | 1.10k | double terminate(double quantile) { |
76 | 1.10k | if (_sorted_nums_vec.size() <= 1) { |
77 | 964 | if (_sorted_nums_vec.size() == 1) { |
78 | 311 | _nums = std::move(_sorted_nums_vec[0]); |
79 | 311 | } |
80 | | |
81 | 964 | if (_nums.empty()) { |
82 | | // Although set null here, but the value is 0.0 and the call method just |
83 | | // get val in aggregate_function_percentile_approx.h |
84 | 0 | return 0.0; |
85 | 0 | } |
86 | | |
87 | 964 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { |
88 | 180 | pdqsort(_nums.begin(), _nums.end()); |
89 | 180 | } |
90 | | |
91 | 964 | if (quantile == 1 || _nums.size() == 1) { |
92 | 473 | return _nums.back(); |
93 | 473 | } |
94 | | |
95 | 491 | double u = (_nums.size() - 1) * quantile; |
96 | 491 | auto index = static_cast<uint32_t>(u); |
97 | 491 | return _nums[index] + |
98 | 491 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - |
99 | 491 | static_cast<double>(_nums[index])); |
100 | 964 | } else { |
101 | 141 | DCHECK(_nums.empty()); |
102 | 141 | size_t rows = 0; |
103 | 322 | for (const auto& i : _sorted_nums_vec) { |
104 | 322 | rows += i.size(); |
105 | 322 | } |
106 | 141 | const bool reverse = quantile > 0.5 && rows > 2; |
107 | 141 | double u = (rows - 1) * quantile; |
108 | 141 | auto index = static_cast<uint32_t>(u); |
109 | | // if reverse, the step of target should start 0 like not reverse |
110 | | // so here rows need to minus index + 2 |
111 | | // eg: rows = 10, index = 5 |
112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 |
113 | | // if reverse, so the second number is 3, the first number is 4 |
114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. |
115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 |
116 | 141 | size_t target = reverse ? rows - index - 2 : index; |
117 | 141 | if (quantile == 1) { |
118 | 0 | target = 0; |
119 | 0 | } |
120 | 141 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); |
121 | 141 | if (quantile == 1) { |
122 | 0 | return second_number; |
123 | 0 | } |
124 | 141 | return first_number + |
125 | 141 | (u - static_cast<double>(index)) * |
126 | 141 | (static_cast<double>(second_number) - static_cast<double>(first_number)); |
127 | 141 | } |
128 | 1.10k | } _ZN5doris6CountsIaE9terminateEd Line | Count | Source | 75 | 61 | double terminate(double quantile) { | 76 | 61 | if (_sorted_nums_vec.size() <= 1) { | 77 | 59 | if (_sorted_nums_vec.size() == 1) { | 78 | 1 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 1 | } | 80 | | | 81 | 59 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 59 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 24 | pdqsort(_nums.begin(), _nums.end()); | 89 | 24 | } | 90 | | | 91 | 59 | if (quantile == 1 || _nums.size() == 1) { | 92 | 34 | return _nums.back(); | 93 | 34 | } | 94 | | | 95 | 25 | double u = (_nums.size() - 1) * quantile; | 96 | 25 | auto index = static_cast<uint32_t>(u); | 97 | 25 | return _nums[index] + | 98 | 25 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 25 | static_cast<double>(_nums[index])); | 100 | 59 | } else { | 101 | 2 | DCHECK(_nums.empty()); | 102 | 2 | size_t rows = 0; | 103 | 4 | for (const auto& i : _sorted_nums_vec) { | 104 | 4 | rows += i.size(); | 105 | 4 | } | 106 | 2 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 2 | double u = (rows - 1) * quantile; | 108 | 2 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 2 | size_t target = reverse ? rows - index - 2 : index; | 117 | 2 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 2 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 2 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 2 | return first_number + | 125 | 2 | (u - static_cast<double>(index)) * | 126 | 2 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 2 | } | 128 | 61 | } |
_ZN5doris6CountsIsE9terminateEd Line | Count | Source | 75 | 300 | double terminate(double quantile) { | 76 | 300 | if (_sorted_nums_vec.size() <= 1) { | 77 | 295 | if (_sorted_nums_vec.size() == 1) { | 78 | 1 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 1 | } | 80 | | | 81 | 295 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 295 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 144 | pdqsort(_nums.begin(), _nums.end()); | 89 | 144 | } | 90 | | | 91 | 295 | if (quantile == 1 || _nums.size() == 1) { | 92 | 87 | return _nums.back(); | 93 | 87 | } | 94 | | | 95 | 208 | double u = (_nums.size() - 1) * quantile; | 96 | 208 | auto index = static_cast<uint32_t>(u); | 97 | 208 | return _nums[index] + | 98 | 208 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 208 | static_cast<double>(_nums[index])); | 100 | 295 | } else { | 101 | 5 | DCHECK(_nums.empty()); | 102 | 5 | size_t rows = 0; | 103 | 10 | for (const auto& i : _sorted_nums_vec) { | 104 | 10 | rows += i.size(); | 105 | 10 | } | 106 | 5 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 5 | double u = (rows - 1) * quantile; | 108 | 5 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 5 | size_t target = reverse ? rows - index - 2 : index; | 117 | 5 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 5 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 5 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 5 | return first_number + | 125 | 5 | (u - static_cast<double>(index)) * | 126 | 5 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 5 | } | 128 | 300 | } |
_ZN5doris6CountsIiE9terminateEd Line | Count | Source | 75 | 444 | double terminate(double quantile) { | 76 | 444 | if (_sorted_nums_vec.size() <= 1) { | 77 | 356 | if (_sorted_nums_vec.size() == 1) { | 78 | 238 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 238 | } | 80 | | | 81 | 356 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 356 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 11 | pdqsort(_nums.begin(), _nums.end()); | 89 | 11 | } | 90 | | | 91 | 356 | if (quantile == 1 || _nums.size() == 1) { | 92 | 239 | return _nums.back(); | 93 | 239 | } | 94 | | | 95 | 117 | double u = (_nums.size() - 1) * quantile; | 96 | 117 | auto index = static_cast<uint32_t>(u); | 97 | 117 | return _nums[index] + | 98 | 117 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 117 | static_cast<double>(_nums[index])); | 100 | 356 | } else { | 101 | 88 | DCHECK(_nums.empty()); | 102 | 88 | size_t rows = 0; | 103 | 206 | for (const auto& i : _sorted_nums_vec) { | 104 | 206 | rows += i.size(); | 105 | 206 | } | 106 | 88 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 88 | double u = (rows - 1) * quantile; | 108 | 88 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 88 | size_t target = reverse ? rows - index - 2 : index; | 117 | 88 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 88 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 88 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 88 | return first_number + | 125 | 88 | (u - static_cast<double>(index)) * | 126 | 88 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 88 | } | 128 | 444 | } |
_ZN5doris6CountsIlE9terminateEd Line | Count | Source | 75 | 128 | double terminate(double quantile) { | 76 | 128 | if (_sorted_nums_vec.size() <= 1) { | 77 | 112 | if (_sorted_nums_vec.size() == 1) { | 78 | 42 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 42 | } | 80 | | | 81 | 112 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 112 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 1 | pdqsort(_nums.begin(), _nums.end()); | 89 | 1 | } | 90 | | | 91 | 112 | if (quantile == 1 || _nums.size() == 1) { | 92 | 59 | return _nums.back(); | 93 | 59 | } | 94 | | | 95 | 53 | double u = (_nums.size() - 1) * quantile; | 96 | 53 | auto index = static_cast<uint32_t>(u); | 97 | 53 | return _nums[index] + | 98 | 53 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 53 | static_cast<double>(_nums[index])); | 100 | 112 | } else { | 101 | 16 | DCHECK(_nums.empty()); | 102 | 16 | size_t rows = 0; | 103 | 42 | for (const auto& i : _sorted_nums_vec) { | 104 | 42 | rows += i.size(); | 105 | 42 | } | 106 | 16 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 16 | double u = (rows - 1) * quantile; | 108 | 16 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 16 | size_t target = reverse ? rows - index - 2 : index; | 117 | 16 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 16 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 16 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 16 | return first_number + | 125 | 16 | (u - static_cast<double>(index)) * | 126 | 16 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 16 | } | 128 | 128 | } |
_ZN5doris6CountsInE9terminateEd Line | Count | Source | 75 | 33 | double terminate(double quantile) { | 76 | 33 | if (_sorted_nums_vec.size() <= 1) { | 77 | 31 | if (_sorted_nums_vec.size() == 1) { | 78 | 1 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 1 | } | 80 | | | 81 | 31 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 31 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 0 | pdqsort(_nums.begin(), _nums.end()); | 89 | 0 | } | 90 | | | 91 | 31 | if (quantile == 1 || _nums.size() == 1) { | 92 | 24 | return _nums.back(); | 93 | 24 | } | 94 | | | 95 | 7 | double u = (_nums.size() - 1) * quantile; | 96 | 7 | auto index = static_cast<uint32_t>(u); | 97 | 7 | return _nums[index] + | 98 | 7 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 7 | static_cast<double>(_nums[index])); | 100 | 31 | } else { | 101 | 2 | DCHECK(_nums.empty()); | 102 | 2 | size_t rows = 0; | 103 | 4 | for (const auto& i : _sorted_nums_vec) { | 104 | 4 | rows += i.size(); | 105 | 4 | } | 106 | 2 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 2 | double u = (rows - 1) * quantile; | 108 | 2 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 2 | size_t target = reverse ? rows - index - 2 : index; | 117 | 2 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 2 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 2 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 2 | return first_number + | 125 | 2 | (u - static_cast<double>(index)) * | 126 | 2 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 2 | } | 128 | 33 | } |
_ZN5doris6CountsIfE9terminateEd Line | Count | Source | 75 | 3 | double terminate(double quantile) { | 76 | 3 | if (_sorted_nums_vec.size() <= 1) { | 77 | 1 | if (_sorted_nums_vec.size() == 1) { | 78 | 1 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 1 | } | 80 | | | 81 | 1 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 1 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 0 | pdqsort(_nums.begin(), _nums.end()); | 89 | 0 | } | 90 | | | 91 | 1 | if (quantile == 1 || _nums.size() == 1) { | 92 | 0 | return _nums.back(); | 93 | 0 | } | 94 | | | 95 | 1 | double u = (_nums.size() - 1) * quantile; | 96 | 1 | auto index = static_cast<uint32_t>(u); | 97 | 1 | return _nums[index] + | 98 | 1 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 1 | static_cast<double>(_nums[index])); | 100 | 2 | } else { | 101 | 2 | DCHECK(_nums.empty()); | 102 | 2 | size_t rows = 0; | 103 | 4 | for (const auto& i : _sorted_nums_vec) { | 104 | 4 | rows += i.size(); | 105 | 4 | } | 106 | 2 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 2 | double u = (rows - 1) * quantile; | 108 | 2 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 2 | size_t target = reverse ? rows - index - 2 : index; | 117 | 2 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 2 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 2 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 2 | return first_number + | 125 | 2 | (u - static_cast<double>(index)) * | 126 | 2 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 2 | } | 128 | 3 | } |
_ZN5doris6CountsIdE9terminateEd Line | Count | Source | 75 | 136 | double terminate(double quantile) { | 76 | 136 | if (_sorted_nums_vec.size() <= 1) { | 77 | 110 | if (_sorted_nums_vec.size() == 1) { | 78 | 27 | _nums = std::move(_sorted_nums_vec[0]); | 79 | 27 | } | 80 | | | 81 | 110 | if (_nums.empty()) { | 82 | | // Although set null here, but the value is 0.0 and the call method just | 83 | | // get val in aggregate_function_percentile_approx.h | 84 | 0 | return 0.0; | 85 | 0 | } | 86 | | | 87 | 110 | if (UNLIKELY(!std::is_sorted(_nums.begin(), _nums.end()))) { | 88 | 0 | pdqsort(_nums.begin(), _nums.end()); | 89 | 0 | } | 90 | | | 91 | 110 | if (quantile == 1 || _nums.size() == 1) { | 92 | 30 | return _nums.back(); | 93 | 30 | } | 94 | | | 95 | 80 | double u = (_nums.size() - 1) * quantile; | 96 | 80 | auto index = static_cast<uint32_t>(u); | 97 | 80 | return _nums[index] + | 98 | 80 | (u - static_cast<double>(index)) * (static_cast<double>(_nums[index + 1]) - | 99 | 80 | static_cast<double>(_nums[index])); | 100 | 110 | } else { | 101 | 26 | DCHECK(_nums.empty()); | 102 | 26 | size_t rows = 0; | 103 | 52 | for (const auto& i : _sorted_nums_vec) { | 104 | 52 | rows += i.size(); | 105 | 52 | } | 106 | 26 | const bool reverse = quantile > 0.5 && rows > 2; | 107 | 26 | double u = (rows - 1) * quantile; | 108 | 26 | auto index = static_cast<uint32_t>(u); | 109 | | // if reverse, the step of target should start 0 like not reverse | 110 | | // so here rows need to minus index + 2 | 111 | | // eg: rows = 10, index = 5 | 112 | | // if not reverse, so the first number loc is 5, the second number loc is 6 | 113 | | // if reverse, so the second number is 3, the first number is 4 | 114 | | // 5 + 4 = 3 + 6 = 9 = rows - 1. | 115 | | // the rows must GE 2 beacuse `_sorted_nums_vec` size GE 2 | 116 | 26 | size_t target = reverse ? rows - index - 2 : index; | 117 | 26 | if (quantile == 1) { | 118 | 0 | target = 0; | 119 | 0 | } | 120 | 26 | auto [first_number, second_number] = _merge_sort_and_get_numbers(target, reverse); | 121 | 26 | if (quantile == 1) { | 122 | 0 | return second_number; | 123 | 0 | } | 124 | 26 | return first_number + | 125 | 26 | (u - static_cast<double>(index)) * | 126 | 26 | (static_cast<double>(second_number) - static_cast<double>(first_number)); | 127 | 26 | } | 128 | 136 | } |
|
129 | | |
130 | | private: |
131 | | struct Node { |
132 | | Ty value; |
133 | | int array_index; |
134 | | int64_t element_index; |
135 | | |
136 | 1.00k | auto operator<=>(const Node& other) const { return value <=> other.value; }_ZNK5doris6CountsIaE4NodessERKS2_ Line | Count | Source | 136 | 4 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIsE4NodessERKS2_ Line | Count | Source | 136 | 23 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIiE4NodessERKS2_ Line | Count | Source | 136 | 650 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIlE4NodessERKS2_ Line | Count | Source | 136 | 284 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsInE4NodessERKS2_ Line | Count | Source | 136 | 4 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIfE4NodessERKS2_ Line | Count | Source | 136 | 4 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
_ZNK5doris6CountsIdE4NodessERKS2_ Line | Count | Source | 136 | 40 | auto operator<=>(const Node& other) const { return value <=> other.value; } |
|
137 | | }; |
138 | | |
139 | 288 | void _convert_sorted_num_vec_to_nums() { |
140 | 288 | size_t rows = 0; |
141 | 571 | for (const auto& i : _sorted_nums_vec) { |
142 | 571 | rows += i.size(); |
143 | 571 | } |
144 | 288 | _nums.resize(rows); |
145 | 288 | size_t count = 0; |
146 | | |
147 | 288 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; |
148 | 859 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
149 | 571 | if (!_sorted_nums_vec[i].empty()) { |
150 | 571 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); |
151 | 571 | } |
152 | 571 | } |
153 | | |
154 | 1.02k | while (!min_heap.empty()) { |
155 | 737 | Node node = min_heap.top(); |
156 | 737 | min_heap.pop(); |
157 | 737 | _nums[count++] = node.value; |
158 | 737 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { |
159 | 166 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
160 | 166 | min_heap.push(node); |
161 | 166 | } |
162 | 737 | } |
163 | 288 | _sorted_nums_vec.clear(); |
164 | 288 | } 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 | 139 | 156 | void _convert_sorted_num_vec_to_nums() { | 140 | 156 | size_t rows = 0; | 141 | 339 | for (const auto& i : _sorted_nums_vec) { | 142 | 339 | rows += i.size(); | 143 | 339 | } | 144 | 156 | _nums.resize(rows); | 145 | 156 | size_t count = 0; | 146 | | | 147 | 156 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 148 | 495 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 149 | 339 | if (!_sorted_nums_vec[i].empty()) { | 150 | 339 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 151 | 339 | } | 152 | 339 | } | 153 | | | 154 | 531 | while (!min_heap.empty()) { | 155 | 375 | Node node = min_heap.top(); | 156 | 375 | min_heap.pop(); | 157 | 375 | _nums[count++] = node.value; | 158 | 375 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 159 | 36 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 160 | 36 | min_heap.push(node); | 161 | 36 | } | 162 | 375 | } | 163 | 156 | _sorted_nums_vec.clear(); | 164 | 156 | } |
_ZN5doris6CountsIlE31_convert_sorted_num_vec_to_numsEv Line | Count | Source | 139 | 132 | void _convert_sorted_num_vec_to_nums() { | 140 | 132 | size_t rows = 0; | 141 | 232 | for (const auto& i : _sorted_nums_vec) { | 142 | 232 | rows += i.size(); | 143 | 232 | } | 144 | 132 | _nums.resize(rows); | 145 | 132 | size_t count = 0; | 146 | | | 147 | 132 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 148 | 364 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 149 | 232 | if (!_sorted_nums_vec[i].empty()) { | 150 | 232 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 151 | 232 | } | 152 | 232 | } | 153 | | | 154 | 494 | while (!min_heap.empty()) { | 155 | 362 | Node node = min_heap.top(); | 156 | 362 | min_heap.pop(); | 157 | 362 | _nums[count++] = node.value; | 158 | 362 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 159 | 130 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 160 | 130 | min_heap.push(node); | 161 | 130 | } | 162 | 362 | } | 163 | 132 | _sorted_nums_vec.clear(); | 164 | 132 | } |
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 |
165 | | |
166 | 141 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { |
167 | 141 | Ty first_number = 0, second_number = 0; |
168 | 141 | size_t count = 0; |
169 | 141 | if (reverse) { |
170 | 24 | std::priority_queue<Node> max_heap; |
171 | 85 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
172 | 61 | if (!_sorted_nums_vec[i].empty()) { |
173 | 61 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, |
174 | 61 | _sorted_nums_vec[i].size() - 1); |
175 | 61 | } |
176 | 61 | } |
177 | | |
178 | 90 | while (!max_heap.empty()) { |
179 | 90 | Node node = max_heap.top(); |
180 | 90 | max_heap.pop(); |
181 | 90 | if (count == target) { |
182 | 24 | second_number = node.value; |
183 | 66 | } else if (count == target + 1) { |
184 | 24 | first_number = node.value; |
185 | 24 | break; |
186 | 24 | } |
187 | 66 | ++count; |
188 | 66 | if (--node.element_index >= 0) { |
189 | 63 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
190 | 63 | max_heap.push(node); |
191 | 63 | } |
192 | 66 | } |
193 | | |
194 | 117 | } else { |
195 | 117 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; |
196 | 378 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { |
197 | 261 | if (!_sorted_nums_vec[i].empty()) { |
198 | 261 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); |
199 | 261 | } |
200 | 261 | } |
201 | | |
202 | 334 | while (!min_heap.empty()) { |
203 | 334 | Node node = min_heap.top(); |
204 | 334 | min_heap.pop(); |
205 | 334 | if (count == target) { |
206 | 117 | first_number = node.value; |
207 | 217 | } else if (count == target + 1) { |
208 | 117 | second_number = node.value; |
209 | 117 | break; |
210 | 117 | } |
211 | 217 | ++count; |
212 | 217 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { |
213 | 136 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; |
214 | 136 | min_heap.push(node); |
215 | 136 | } |
216 | 217 | } |
217 | 117 | } |
218 | | |
219 | 141 | return {first_number, second_number}; |
220 | 141 | } _ZN5doris6CountsIaE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 2 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 2 | Ty first_number = 0, second_number = 0; | 168 | 2 | size_t count = 0; | 169 | 2 | if (reverse) { | 170 | 1 | std::priority_queue<Node> max_heap; | 171 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 2 | if (!_sorted_nums_vec[i].empty()) { | 173 | 2 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 2 | _sorted_nums_vec[i].size() - 1); | 175 | 2 | } | 176 | 2 | } | 177 | | | 178 | 2 | while (!max_heap.empty()) { | 179 | 2 | Node node = max_heap.top(); | 180 | 2 | max_heap.pop(); | 181 | 2 | if (count == target) { | 182 | 1 | second_number = node.value; | 183 | 1 | } else if (count == target + 1) { | 184 | 1 | first_number = node.value; | 185 | 1 | break; | 186 | 1 | } | 187 | 1 | ++count; | 188 | 1 | if (--node.element_index >= 0) { | 189 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 1 | max_heap.push(node); | 191 | 1 | } | 192 | 1 | } | 193 | | | 194 | 1 | } else { | 195 | 1 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 2 | if (!_sorted_nums_vec[i].empty()) { | 198 | 2 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 2 | } | 200 | 2 | } | 201 | | | 202 | 3 | while (!min_heap.empty()) { | 203 | 3 | Node node = min_heap.top(); | 204 | 3 | min_heap.pop(); | 205 | 3 | if (count == target) { | 206 | 1 | first_number = node.value; | 207 | 2 | } else if (count == target + 1) { | 208 | 1 | second_number = node.value; | 209 | 1 | break; | 210 | 1 | } | 211 | 2 | ++count; | 212 | 2 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 1 | min_heap.push(node); | 215 | 1 | } | 216 | 2 | } | 217 | 1 | } | 218 | | | 219 | 2 | return {first_number, second_number}; | 220 | 2 | } |
_ZN5doris6CountsIsE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 5 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 5 | Ty first_number = 0, second_number = 0; | 168 | 5 | size_t count = 0; | 169 | 5 | if (reverse) { | 170 | 2 | std::priority_queue<Node> max_heap; | 171 | 6 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 4 | if (!_sorted_nums_vec[i].empty()) { | 173 | 4 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 4 | _sorted_nums_vec[i].size() - 1); | 175 | 4 | } | 176 | 4 | } | 177 | | | 178 | 8 | while (!max_heap.empty()) { | 179 | 8 | Node node = max_heap.top(); | 180 | 8 | max_heap.pop(); | 181 | 8 | if (count == target) { | 182 | 2 | second_number = node.value; | 183 | 6 | } else if (count == target + 1) { | 184 | 2 | first_number = node.value; | 185 | 2 | break; | 186 | 2 | } | 187 | 6 | ++count; | 188 | 6 | if (--node.element_index >= 0) { | 189 | 6 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 6 | max_heap.push(node); | 191 | 6 | } | 192 | 6 | } | 193 | | | 194 | 3 | } else { | 195 | 3 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 9 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 6 | if (!_sorted_nums_vec[i].empty()) { | 198 | 6 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 6 | } | 200 | 6 | } | 201 | | | 202 | 16 | while (!min_heap.empty()) { | 203 | 16 | Node node = min_heap.top(); | 204 | 16 | min_heap.pop(); | 205 | 16 | if (count == target) { | 206 | 3 | first_number = node.value; | 207 | 13 | } else if (count == target + 1) { | 208 | 3 | second_number = node.value; | 209 | 3 | break; | 210 | 3 | } | 211 | 13 | ++count; | 212 | 13 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 12 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 12 | min_heap.push(node); | 215 | 12 | } | 216 | 13 | } | 217 | 3 | } | 218 | | | 219 | 5 | return {first_number, second_number}; | 220 | 5 | } |
_ZN5doris6CountsIiE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 88 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 88 | Ty first_number = 0, second_number = 0; | 168 | 88 | size_t count = 0; | 169 | 88 | if (reverse) { | 170 | 7 | std::priority_queue<Node> max_heap; | 171 | 25 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 18 | if (!_sorted_nums_vec[i].empty()) { | 173 | 18 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 18 | _sorted_nums_vec[i].size() - 1); | 175 | 18 | } | 176 | 18 | } | 177 | | | 178 | 33 | while (!max_heap.empty()) { | 179 | 33 | Node node = max_heap.top(); | 180 | 33 | max_heap.pop(); | 181 | 33 | if (count == target) { | 182 | 7 | second_number = node.value; | 183 | 26 | } else if (count == target + 1) { | 184 | 7 | first_number = node.value; | 185 | 7 | break; | 186 | 7 | } | 187 | 26 | ++count; | 188 | 26 | if (--node.element_index >= 0) { | 189 | 26 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 26 | max_heap.push(node); | 191 | 26 | } | 192 | 26 | } | 193 | | | 194 | 81 | } else { | 195 | 81 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 269 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 188 | if (!_sorted_nums_vec[i].empty()) { | 198 | 188 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 188 | } | 200 | 188 | } | 201 | | | 202 | 231 | while (!min_heap.empty()) { | 203 | 231 | Node node = min_heap.top(); | 204 | 231 | min_heap.pop(); | 205 | 231 | if (count == target) { | 206 | 81 | first_number = node.value; | 207 | 150 | } else if (count == target + 1) { | 208 | 81 | second_number = node.value; | 209 | 81 | break; | 210 | 81 | } | 211 | 150 | ++count; | 212 | 150 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 94 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 94 | min_heap.push(node); | 215 | 94 | } | 216 | 150 | } | 217 | 81 | } | 218 | | | 219 | 88 | return {first_number, second_number}; | 220 | 88 | } |
_ZN5doris6CountsIlE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 16 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 16 | Ty first_number = 0, second_number = 0; | 168 | 16 | size_t count = 0; | 169 | 16 | if (reverse) { | 170 | 9 | std::priority_queue<Node> max_heap; | 171 | 36 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 27 | if (!_sorted_nums_vec[i].empty()) { | 173 | 27 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 27 | _sorted_nums_vec[i].size() - 1); | 175 | 27 | } | 176 | 27 | } | 177 | | | 178 | 36 | while (!max_heap.empty()) { | 179 | 36 | Node node = max_heap.top(); | 180 | 36 | max_heap.pop(); | 181 | 36 | if (count == target) { | 182 | 9 | second_number = node.value; | 183 | 27 | } else if (count == target + 1) { | 184 | 9 | first_number = node.value; | 185 | 9 | break; | 186 | 9 | } | 187 | 27 | ++count; | 188 | 27 | if (--node.element_index >= 0) { | 189 | 25 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 25 | max_heap.push(node); | 191 | 25 | } | 192 | 27 | } | 193 | | | 194 | 9 | } else { | 195 | 7 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 22 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 15 | if (!_sorted_nums_vec[i].empty()) { | 198 | 15 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 15 | } | 200 | 15 | } | 201 | | | 202 | 23 | while (!min_heap.empty()) { | 203 | 23 | Node node = min_heap.top(); | 204 | 23 | min_heap.pop(); | 205 | 23 | if (count == target) { | 206 | 7 | first_number = node.value; | 207 | 16 | } else if (count == target + 1) { | 208 | 7 | second_number = node.value; | 209 | 7 | break; | 210 | 7 | } | 211 | 16 | ++count; | 212 | 16 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 14 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 14 | min_heap.push(node); | 215 | 14 | } | 216 | 16 | } | 217 | 7 | } | 218 | | | 219 | 16 | return {first_number, second_number}; | 220 | 16 | } |
_ZN5doris6CountsInE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 2 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 2 | Ty first_number = 0, second_number = 0; | 168 | 2 | size_t count = 0; | 169 | 2 | if (reverse) { | 170 | 1 | std::priority_queue<Node> max_heap; | 171 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 2 | if (!_sorted_nums_vec[i].empty()) { | 173 | 2 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 2 | _sorted_nums_vec[i].size() - 1); | 175 | 2 | } | 176 | 2 | } | 177 | | | 178 | 2 | while (!max_heap.empty()) { | 179 | 2 | Node node = max_heap.top(); | 180 | 2 | max_heap.pop(); | 181 | 2 | if (count == target) { | 182 | 1 | second_number = node.value; | 183 | 1 | } else if (count == target + 1) { | 184 | 1 | first_number = node.value; | 185 | 1 | break; | 186 | 1 | } | 187 | 1 | ++count; | 188 | 1 | if (--node.element_index >= 0) { | 189 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 1 | max_heap.push(node); | 191 | 1 | } | 192 | 1 | } | 193 | | | 194 | 1 | } else { | 195 | 1 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 2 | if (!_sorted_nums_vec[i].empty()) { | 198 | 2 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 2 | } | 200 | 2 | } | 201 | | | 202 | 3 | while (!min_heap.empty()) { | 203 | 3 | Node node = min_heap.top(); | 204 | 3 | min_heap.pop(); | 205 | 3 | if (count == target) { | 206 | 1 | first_number = node.value; | 207 | 2 | } else if (count == target + 1) { | 208 | 1 | second_number = node.value; | 209 | 1 | break; | 210 | 1 | } | 211 | 2 | ++count; | 212 | 2 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 1 | min_heap.push(node); | 215 | 1 | } | 216 | 2 | } | 217 | 1 | } | 218 | | | 219 | 2 | return {first_number, second_number}; | 220 | 2 | } |
_ZN5doris6CountsIfE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 2 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 2 | Ty first_number = 0, second_number = 0; | 168 | 2 | size_t count = 0; | 169 | 2 | if (reverse) { | 170 | 1 | std::priority_queue<Node> max_heap; | 171 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 2 | if (!_sorted_nums_vec[i].empty()) { | 173 | 2 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 2 | _sorted_nums_vec[i].size() - 1); | 175 | 2 | } | 176 | 2 | } | 177 | | | 178 | 2 | while (!max_heap.empty()) { | 179 | 2 | Node node = max_heap.top(); | 180 | 2 | max_heap.pop(); | 181 | 2 | if (count == target) { | 182 | 1 | second_number = node.value; | 183 | 1 | } else if (count == target + 1) { | 184 | 1 | first_number = node.value; | 185 | 1 | break; | 186 | 1 | } | 187 | 1 | ++count; | 188 | 1 | if (--node.element_index >= 0) { | 189 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 1 | max_heap.push(node); | 191 | 1 | } | 192 | 1 | } | 193 | | | 194 | 1 | } else { | 195 | 1 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 3 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 2 | if (!_sorted_nums_vec[i].empty()) { | 198 | 2 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 2 | } | 200 | 2 | } | 201 | | | 202 | 3 | while (!min_heap.empty()) { | 203 | 3 | Node node = min_heap.top(); | 204 | 3 | min_heap.pop(); | 205 | 3 | if (count == target) { | 206 | 1 | first_number = node.value; | 207 | 2 | } else if (count == target + 1) { | 208 | 1 | second_number = node.value; | 209 | 1 | break; | 210 | 1 | } | 211 | 2 | ++count; | 212 | 2 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 1 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 1 | min_heap.push(node); | 215 | 1 | } | 216 | 2 | } | 217 | 1 | } | 218 | | | 219 | 2 | return {first_number, second_number}; | 220 | 2 | } |
_ZN5doris6CountsIdE27_merge_sort_and_get_numbersElb Line | Count | Source | 166 | 26 | std::pair<Ty, Ty> _merge_sort_and_get_numbers(int64_t target, bool reverse) { | 167 | 26 | Ty first_number = 0, second_number = 0; | 168 | 26 | size_t count = 0; | 169 | 26 | if (reverse) { | 170 | 3 | std::priority_queue<Node> max_heap; | 171 | 9 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 172 | 6 | if (!_sorted_nums_vec[i].empty()) { | 173 | 6 | max_heap.emplace(_sorted_nums_vec[i][_sorted_nums_vec[i].size() - 1], i, | 174 | 6 | _sorted_nums_vec[i].size() - 1); | 175 | 6 | } | 176 | 6 | } | 177 | | | 178 | 7 | while (!max_heap.empty()) { | 179 | 7 | Node node = max_heap.top(); | 180 | 7 | max_heap.pop(); | 181 | 7 | if (count == target) { | 182 | 3 | second_number = node.value; | 183 | 4 | } else if (count == target + 1) { | 184 | 3 | first_number = node.value; | 185 | 3 | break; | 186 | 3 | } | 187 | 4 | ++count; | 188 | 4 | if (--node.element_index >= 0) { | 189 | 3 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 190 | 3 | max_heap.push(node); | 191 | 3 | } | 192 | 4 | } | 193 | | | 194 | 23 | } else { | 195 | 23 | std::priority_queue<Node, std::vector<Node>, std::greater<Node>> min_heap; | 196 | 69 | for (int i = 0; i < _sorted_nums_vec.size(); ++i) { | 197 | 46 | if (!_sorted_nums_vec[i].empty()) { | 198 | 46 | min_heap.emplace(_sorted_nums_vec[i][0], i, 0); | 199 | 46 | } | 200 | 46 | } | 201 | | | 202 | 55 | while (!min_heap.empty()) { | 203 | 55 | Node node = min_heap.top(); | 204 | 55 | min_heap.pop(); | 205 | 55 | if (count == target) { | 206 | 23 | first_number = node.value; | 207 | 32 | } else if (count == target + 1) { | 208 | 23 | second_number = node.value; | 209 | 23 | break; | 210 | 23 | } | 211 | 32 | ++count; | 212 | 32 | if (++node.element_index < _sorted_nums_vec[node.array_index].size()) { | 213 | 13 | node.value = _sorted_nums_vec[node.array_index][node.element_index]; | 214 | 13 | min_heap.push(node); | 215 | 13 | } | 216 | 32 | } | 217 | 23 | } | 218 | | | 219 | 26 | return {first_number, second_number}; | 220 | 26 | } |
|
221 | | |
222 | | PODArray<Ty> _nums; |
223 | | std::vector<PODArray<Ty>> _sorted_nums_vec; |
224 | | }; |
225 | | |
226 | | } // namespace doris |