be/src/exec/common/histogram_helpers.hpp
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 <rapidjson/document.h> |
21 | | #include <rapidjson/prettywriter.h> |
22 | | #include <rapidjson/stringbuffer.h> |
23 | | |
24 | | #include <boost/dynamic_bitset.hpp> |
25 | | |
26 | | #include "common/cast_set.h" |
27 | | #include "core/data_type/data_type_decimal.h" |
28 | | |
29 | | namespace doris { |
30 | | template <typename T> |
31 | | struct Bucket { |
32 | | public: |
33 | | Bucket() = default; |
34 | | Bucket(T lower, T upper, size_t ndv, size_t count, size_t pre_sum) |
35 | 468 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {}_ZN5doris6BucketINS_7DecimalIiEEEC2ES2_S2_mmm Line | Count | Source | 35 | 25 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
Unexecuted instantiation: _ZN5doris6BucketINS_7DecimalIlEEEC2ES2_S2_mmm Unexecuted instantiation: _ZN5doris6BucketINS_12Decimal128V3EEC2ES1_S1_mmm Unexecuted instantiation: _ZN5doris6BucketINS_7DecimalIN4wide7integerILm256EiEEEEEC2ES5_S5_mmm _ZN5doris6BucketINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2ES6_S6_mmm Line | Count | Source | 35 | 60 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketINS_11DateV2ValueINS_15DateV2ValueTypeEEEEC2ES3_S3_mmm Line | Count | Source | 35 | 40 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEEEC2ES3_S3_mmm Line | Count | Source | 35 | 39 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
Unexecuted instantiation: _ZN5doris6BucketINS_16TimeStampNsValueEEC2ES1_S1_mmm Unexecuted instantiation: _ZN5doris6BucketINS_16TimestampTzValueEEC2ES1_S1_mmm _ZN5doris6BucketIhEC2Ehhmmm Line | Count | Source | 35 | 2 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIaEC2Eaammm Line | Count | Source | 35 | 21 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIsEC2Essmmm Line | Count | Source | 35 | 24 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIiEC2Eiimmm Line | Count | Source | 35 | 60 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIlEC2Ellmmm Line | Count | Source | 35 | 104 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketInEC2Ennmmm Line | Count | Source | 35 | 33 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIfEC2Effmmm Line | Count | Source | 35 | 20 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIdEC2Eddmmm Line | Count | Source | 35 | 20 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
_ZN5doris6BucketIoEC2Eoommm Line | Count | Source | 35 | 20 | : lower(lower), upper(upper), ndv(ndv), count(count), pre_sum(pre_sum) {} |
|
36 | | |
37 | | T lower; |
38 | | T upper; |
39 | | size_t ndv; |
40 | | size_t count; |
41 | | size_t pre_sum; |
42 | | }; |
43 | | |
44 | | /** |
45 | | * Checks if it is possible to assign the provided value_map to the given |
46 | | * number of buckets such that no bucket has a size larger than max_bucket_size. |
47 | | * |
48 | | * @param value_map A mapping of values to their counts. |
49 | | * @param max_bucket_size The maximum size that any bucket is allowed to have. |
50 | | * @param num_buckets The number of buckets that we want to assign values to. |
51 | | * |
52 | | * @return true if the values can be assigned to the buckets, false otherwise. |
53 | | */ |
54 | | template <typename T> |
55 | | bool can_assign_into_buckets(const std::map<T, size_t>& value_map, const size_t max_bucket_size, |
56 | 519 | const size_t num_buckets) { |
57 | 519 | if (value_map.empty()) { |
58 | 1 | return false; |
59 | 518 | }; |
60 | | |
61 | 518 | size_t used_buckets = 1; |
62 | 518 | size_t current_bucket_size = 0; |
63 | | |
64 | 30.1k | for (const auto& [value, count] : value_map) { |
65 | 30.1k | current_bucket_size += count; |
66 | | |
67 | | // If adding the current value to the current bucket would exceed max_bucket_size, |
68 | | // then we start a new bucket. |
69 | 30.1k | if (current_bucket_size > max_bucket_size) { |
70 | 1.15k | ++used_buckets; |
71 | 1.15k | current_bucket_size = count; |
72 | 1.15k | } |
73 | | |
74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. |
75 | 30.1k | if (used_buckets > num_buckets) { |
76 | 222 | return false; |
77 | 222 | } |
78 | 30.1k | } |
79 | | |
80 | 296 | return true; |
81 | 518 | } Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsIhEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm _ZN5doris23can_assign_into_bucketsIaEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 27 | const size_t num_buckets) { | 57 | 27 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 27 | }; | 60 | | | 61 | 27 | size_t used_buckets = 1; | 62 | 27 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.24k | for (const auto& [value, count] : value_map) { | 65 | 1.24k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.24k | if (current_bucket_size > max_bucket_size) { | 70 | 70 | ++used_buckets; | 71 | 70 | current_bucket_size = count; | 72 | 70 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.24k | if (used_buckets > num_buckets) { | 76 | 11 | return false; | 77 | 11 | } | 78 | 1.24k | } | 79 | | | 80 | 16 | return true; | 81 | 27 | } |
_ZN5doris23can_assign_into_bucketsIsEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 40 | const size_t num_buckets) { | 57 | 40 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 40 | }; | 60 | | | 61 | 40 | size_t used_buckets = 1; | 62 | 40 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.34k | for (const auto& [value, count] : value_map) { | 65 | 1.34k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.34k | if (current_bucket_size > max_bucket_size) { | 70 | 88 | ++used_buckets; | 71 | 88 | current_bucket_size = count; | 72 | 88 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.34k | if (used_buckets > num_buckets) { | 76 | 18 | return false; | 77 | 18 | } | 78 | 1.34k | } | 79 | | | 80 | 22 | return true; | 81 | 40 | } |
_ZN5doris23can_assign_into_bucketsIiEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 83 | const size_t num_buckets) { | 57 | 83 | if (value_map.empty()) { | 58 | 1 | return false; | 59 | 82 | }; | 60 | | | 61 | 82 | size_t used_buckets = 1; | 62 | 82 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.42k | for (const auto& [value, count] : value_map) { | 65 | 1.42k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.42k | if (current_bucket_size > max_bucket_size) { | 70 | 171 | ++used_buckets; | 71 | 171 | current_bucket_size = count; | 72 | 171 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.42k | if (used_buckets > num_buckets) { | 76 | 30 | return false; | 77 | 30 | } | 78 | 1.42k | } | 79 | | | 80 | 52 | return true; | 81 | 82 | } |
_ZN5doris23can_assign_into_bucketsIlEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 34 | const size_t num_buckets) { | 57 | 34 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 34 | }; | 60 | | | 61 | 34 | size_t used_buckets = 1; | 62 | 34 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.29k | for (const auto& [value, count] : value_map) { | 65 | 1.29k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.29k | if (current_bucket_size > max_bucket_size) { | 70 | 90 | ++used_buckets; | 71 | 90 | current_bucket_size = count; | 72 | 90 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.29k | if (used_buckets > num_buckets) { | 76 | 17 | return false; | 77 | 17 | } | 78 | 1.29k | } | 79 | | | 80 | 17 | return true; | 81 | 34 | } |
_ZN5doris23can_assign_into_bucketsInEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 32 | const size_t num_buckets) { | 57 | 32 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 32 | }; | 60 | | | 61 | 32 | size_t used_buckets = 1; | 62 | 32 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.28k | for (const auto& [value, count] : value_map) { | 65 | 1.28k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.28k | if (current_bucket_size > max_bucket_size) { | 70 | 96 | ++used_buckets; | 71 | 96 | current_bucket_size = count; | 72 | 96 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.28k | if (used_buckets > num_buckets) { | 76 | 15 | return false; | 77 | 15 | } | 78 | 1.28k | } | 79 | | | 80 | 17 | return true; | 81 | 32 | } |
_ZN5doris23can_assign_into_bucketsIfEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 31 | const size_t num_buckets) { | 57 | 31 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 31 | }; | 60 | | | 61 | 31 | size_t used_buckets = 1; | 62 | 31 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.25k | for (const auto& [value, count] : value_map) { | 65 | 1.25k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.25k | if (current_bucket_size > max_bucket_size) { | 70 | 78 | ++used_buckets; | 71 | 78 | current_bucket_size = count; | 72 | 78 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.25k | if (used_buckets > num_buckets) { | 76 | 15 | return false; | 77 | 15 | } | 78 | 1.25k | } | 79 | | | 80 | 16 | return true; | 81 | 31 | } |
_ZN5doris23can_assign_into_bucketsIdEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm Line | Count | Source | 56 | 31 | const size_t num_buckets) { | 57 | 31 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 31 | }; | 60 | | | 61 | 31 | size_t used_buckets = 1; | 62 | 31 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.25k | for (const auto& [value, count] : value_map) { | 65 | 1.25k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.25k | if (current_bucket_size > max_bucket_size) { | 70 | 78 | ++used_buckets; | 71 | 78 | current_bucket_size = count; | 72 | 78 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.25k | if (used_buckets > num_buckets) { | 76 | 15 | return false; | 77 | 15 | } | 78 | 1.25k | } | 79 | | | 80 | 16 | return true; | 81 | 31 | } |
_ZN5doris23can_assign_into_bucketsINS_7DecimalIiEEEEbRKSt3mapIT_mSt4lessIS4_ESaISt4pairIKS4_mEEEmm Line | Count | Source | 56 | 39 | const size_t num_buckets) { | 57 | 39 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 39 | }; | 60 | | | 61 | 39 | size_t used_buckets = 1; | 62 | 39 | size_t current_bucket_size = 0; | 63 | | | 64 | 161 | for (const auto& [value, count] : value_map) { | 65 | 161 | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 161 | if (current_bucket_size > max_bucket_size) { | 70 | 54 | ++used_buckets; | 71 | 54 | current_bucket_size = count; | 72 | 54 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 161 | if (used_buckets > num_buckets) { | 76 | 17 | return false; | 77 | 17 | } | 78 | 161 | } | 79 | | | 80 | 22 | return true; | 81 | 39 | } |
Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsINS_7DecimalIlEEEEbRKSt3mapIT_mSt4lessIS4_ESaISt4pairIKS4_mEEEmm Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsINS_12Decimal128V3EEEbRKSt3mapIT_mSt4lessIS3_ESaISt4pairIKS3_mEEEmm Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsINS_7DecimalIN4wide7integerILm256EiEEEEEEbRKSt3mapIT_mSt4lessIS7_ESaISt4pairIKS7_mEEEmm _ZN5doris23can_assign_into_bucketsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKSt3mapIT_mSt4lessIS8_ESaISt4pairIKS8_mEEEmm Line | Count | Source | 56 | 100 | const size_t num_buckets) { | 57 | 100 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 100 | }; | 60 | | | 61 | 100 | size_t used_buckets = 1; | 62 | 100 | size_t current_bucket_size = 0; | 63 | | | 64 | 18.3k | for (const auto& [value, count] : value_map) { | 65 | 18.3k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 18.3k | if (current_bucket_size > max_bucket_size) { | 70 | 197 | ++used_buckets; | 71 | 197 | current_bucket_size = count; | 72 | 197 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 18.3k | if (used_buckets > num_buckets) { | 76 | 38 | return false; | 77 | 38 | } | 78 | 18.3k | } | 79 | | | 80 | 62 | return true; | 81 | 100 | } |
_ZN5doris23can_assign_into_bucketsINS_11DateV2ValueINS_15DateV2ValueTypeEEEEEbRKSt3mapIT_mSt4lessIS5_ESaISt4pairIKS5_mEEEmm Line | Count | Source | 56 | 51 | const size_t num_buckets) { | 57 | 51 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 51 | }; | 60 | | | 61 | 51 | size_t used_buckets = 1; | 62 | 51 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.31k | for (const auto& [value, count] : value_map) { | 65 | 1.31k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.31k | if (current_bucket_size > max_bucket_size) { | 70 | 114 | ++used_buckets; | 71 | 114 | current_bucket_size = count; | 72 | 114 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.31k | if (used_buckets > num_buckets) { | 76 | 23 | return false; | 77 | 23 | } | 78 | 1.31k | } | 79 | | | 80 | 28 | return true; | 81 | 51 | } |
_ZN5doris23can_assign_into_bucketsINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEEEEbRKSt3mapIT_mSt4lessIS5_ESaISt4pairIKS5_mEEEmm Line | Count | Source | 56 | 51 | const size_t num_buckets) { | 57 | 51 | if (value_map.empty()) { | 58 | 0 | return false; | 59 | 51 | }; | 60 | | | 61 | 51 | size_t used_buckets = 1; | 62 | 51 | size_t current_bucket_size = 0; | 63 | | | 64 | 1.31k | for (const auto& [value, count] : value_map) { | 65 | 1.31k | current_bucket_size += count; | 66 | | | 67 | | // If adding the current value to the current bucket would exceed max_bucket_size, | 68 | | // then we start a new bucket. | 69 | 1.31k | if (current_bucket_size > max_bucket_size) { | 70 | 115 | ++used_buckets; | 71 | 115 | current_bucket_size = count; | 72 | 115 | } | 73 | | | 74 | | // If we have used more buckets than num_buckets, we cannot assign the values to buckets. | 75 | 1.31k | if (used_buckets > num_buckets) { | 76 | 23 | return false; | 77 | 23 | } | 78 | 1.31k | } | 79 | | | 80 | 28 | return true; | 81 | 51 | } |
Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsINS_16TimeStampNsValueEEEbRKSt3mapIT_mSt4lessIS3_ESaISt4pairIKS3_mEEEmm Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsINS_16TimestampTzValueEEEbRKSt3mapIT_mSt4lessIS3_ESaISt4pairIKS3_mEEEmm Unexecuted instantiation: _ZN5doris23can_assign_into_bucketsIoEEbRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEmm |
82 | | |
83 | | /** |
84 | | * Calculates the maximum number of values that can fit into each bucket given a set of values |
85 | | * and the desired number of buckets. |
86 | | * |
87 | | * @tparam T the type of the values in the value map |
88 | | * @param value_map the map of values and their counts |
89 | | * @param num_buckets the desired number of buckets |
90 | | * @return the maximum number of values that can fit into each bucket |
91 | | */ |
92 | | template <typename T> |
93 | 178 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { |
94 | | // Ensure that the value map is not empty |
95 | 178 | assert(!value_map.empty()); |
96 | | |
97 | | // Calculate the total number of values in the map using std::accumulate() |
98 | 178 | size_t total_values = 0; |
99 | 4.37k | for (const auto& [value, count] : value_map) { |
100 | 4.37k | total_values += count; |
101 | 4.37k | } |
102 | | |
103 | | // If there is only one bucket, then all values will be assigned to that bucket |
104 | 178 | if (num_buckets == 1) { |
105 | 18 | return total_values; |
106 | 18 | } |
107 | | |
108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper |
109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed |
110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search |
111 | | // algorithm will approach the actual maximum value count. |
112 | 160 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; |
113 | | |
114 | | // Initialize the lower bound to 0 |
115 | 160 | size_t lower_bucket_values = 0; |
116 | | |
117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket |
118 | 160 | int search_step = 0; |
119 | 160 | const int max_search_steps = |
120 | 160 | 10; // Limit the number of search steps to avoid excessive iteration |
121 | | |
122 | 665 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { |
123 | | // Calculate the midpoint of the upper and lower bounds |
124 | 505 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; |
125 | | |
126 | | // Check if the given number of values can be assigned to the desired number of buckets |
127 | 505 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { |
128 | | // If it can, then set the upper bound to the midpoint |
129 | 289 | upper_bucket_values = bucket_values; |
130 | 289 | } else { |
131 | | // If it can't, then set the lower bound to the midpoint |
132 | 216 | lower_bucket_values = bucket_values; |
133 | 216 | } |
134 | | // Increment the search step counter |
135 | 505 | ++search_step; |
136 | 505 | } |
137 | | |
138 | 160 | return upper_bucket_values; |
139 | 178 | } _ZN5doris27calculate_bucket_max_valuesIhEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 1 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 1 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 1 | size_t total_values = 0; | 99 | 2 | for (const auto& [value, count] : value_map) { | 100 | 2 | total_values += count; | 101 | 2 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 1 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 1 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 1 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 1 | int search_step = 0; | 119 | 1 | const int max_search_steps = | 120 | 1 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 1 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 0 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 0 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 0 | upper_bucket_values = bucket_values; | 130 | 0 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 0 | lower_bucket_values = bucket_values; | 133 | 0 | } | 134 | | // Increment the search step counter | 135 | 0 | ++search_step; | 136 | 0 | } | 137 | | | 138 | 1 | return upper_bucket_values; | 139 | 1 | } |
_ZN5doris27calculate_bucket_max_valuesIaEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 8 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 8 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 8 | size_t total_values = 0; | 99 | 232 | for (const auto& [value, count] : value_map) { | 100 | 232 | total_values += count; | 101 | 232 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 8 | if (num_buckets == 1) { | 105 | 1 | return total_values; | 106 | 1 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 7 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 7 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 7 | int search_step = 0; | 119 | 7 | const int max_search_steps = | 120 | 7 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 34 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 27 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 27 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 16 | upper_bucket_values = bucket_values; | 130 | 16 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 11 | lower_bucket_values = bucket_values; | 133 | 11 | } | 134 | | // Increment the search step counter | 135 | 27 | ++search_step; | 136 | 27 | } | 137 | | | 138 | 7 | return upper_bucket_values; | 139 | 8 | } |
_ZN5doris27calculate_bucket_max_valuesIsEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 9 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 9 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 9 | size_t total_values = 0; | 99 | 241 | for (const auto& [value, count] : value_map) { | 100 | 241 | total_values += count; | 101 | 241 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 9 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 9 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 9 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 9 | int search_step = 0; | 119 | 9 | const int max_search_steps = | 120 | 9 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 49 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 40 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 40 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 22 | upper_bucket_values = bucket_values; | 130 | 22 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 18 | lower_bucket_values = bucket_values; | 133 | 18 | } | 134 | | // Increment the search step counter | 135 | 40 | ++search_step; | 136 | 40 | } | 137 | | | 138 | 9 | return upper_bucket_values; | 139 | 9 | } |
_ZN5doris27calculate_bucket_max_valuesIiEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 46 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 46 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 46 | size_t total_values = 0; | 99 | 272 | for (const auto& [value, count] : value_map) { | 100 | 272 | total_values += count; | 101 | 272 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 46 | if (num_buckets == 1) { | 105 | 17 | return total_values; | 106 | 17 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 29 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 29 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 29 | int search_step = 0; | 119 | 29 | const int max_search_steps = | 120 | 29 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 98 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 69 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 69 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 45 | upper_bucket_values = bucket_values; | 130 | 45 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 24 | lower_bucket_values = bucket_values; | 133 | 24 | } | 134 | | // Increment the search step counter | 135 | 69 | ++search_step; | 136 | 69 | } | 137 | | | 138 | 29 | return upper_bucket_values; | 139 | 46 | } |
_ZN5doris27calculate_bucket_max_valuesIlEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 25 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 25 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 25 | size_t total_values = 0; | 99 | 310 | for (const auto& [value, count] : value_map) { | 100 | 310 | total_values += count; | 101 | 310 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 25 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 25 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 25 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 25 | int search_step = 0; | 119 | 25 | const int max_search_steps = | 120 | 25 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 59 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 34 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 34 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 17 | upper_bucket_values = bucket_values; | 130 | 17 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 17 | lower_bucket_values = bucket_values; | 133 | 17 | } | 134 | | // Increment the search step counter | 135 | 34 | ++search_step; | 136 | 34 | } | 137 | | | 138 | 25 | return upper_bucket_values; | 139 | 25 | } |
_ZN5doris27calculate_bucket_max_valuesInEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 8 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 8 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 8 | size_t total_values = 0; | 99 | 235 | for (const auto& [value, count] : value_map) { | 100 | 235 | total_values += count; | 101 | 235 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 8 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 8 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 8 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 8 | int search_step = 0; | 119 | 8 | const int max_search_steps = | 120 | 8 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 40 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 32 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 32 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 17 | upper_bucket_values = bucket_values; | 130 | 17 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 15 | lower_bucket_values = bucket_values; | 133 | 15 | } | 134 | | // Increment the search step counter | 135 | 32 | ++search_step; | 136 | 32 | } | 137 | | | 138 | 8 | return upper_bucket_values; | 139 | 8 | } |
_ZN5doris27calculate_bucket_max_valuesIfEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 7 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 7 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 7 | size_t total_values = 0; | 99 | 220 | for (const auto& [value, count] : value_map) { | 100 | 220 | total_values += count; | 101 | 220 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 7 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 7 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 7 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 7 | int search_step = 0; | 119 | 7 | const int max_search_steps = | 120 | 7 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 38 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 31 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 31 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 16 | upper_bucket_values = bucket_values; | 130 | 16 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 15 | lower_bucket_values = bucket_values; | 133 | 15 | } | 134 | | // Increment the search step counter | 135 | 31 | ++search_step; | 136 | 31 | } | 137 | | | 138 | 7 | return upper_bucket_values; | 139 | 7 | } |
_ZN5doris27calculate_bucket_max_valuesIdEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 7 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 7 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 7 | size_t total_values = 0; | 99 | 220 | for (const auto& [value, count] : value_map) { | 100 | 220 | total_values += count; | 101 | 220 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 7 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 7 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 7 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 7 | int search_step = 0; | 119 | 7 | const int max_search_steps = | 120 | 7 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 38 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 31 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 31 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 16 | upper_bucket_values = bucket_values; | 130 | 16 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 15 | lower_bucket_values = bucket_values; | 133 | 15 | } | 134 | | // Increment the search step counter | 135 | 31 | ++search_step; | 136 | 31 | } | 137 | | | 138 | 7 | return upper_bucket_values; | 139 | 7 | } |
_ZN5doris27calculate_bucket_max_valuesINS_7DecimalIiEEEEmRKSt3mapIT_mSt4lessIS4_ESaISt4pairIKS4_mEEEm Line | Count | Source | 93 | 11 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 11 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 11 | size_t total_values = 0; | 99 | 53 | for (const auto& [value, count] : value_map) { | 100 | 53 | total_values += count; | 101 | 53 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 11 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 11 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 11 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 11 | int search_step = 0; | 119 | 11 | const int max_search_steps = | 120 | 11 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 50 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 39 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 39 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 22 | upper_bucket_values = bucket_values; | 130 | 22 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 17 | lower_bucket_values = bucket_values; | 133 | 17 | } | 134 | | // Increment the search step counter | 135 | 39 | ++search_step; | 136 | 39 | } | 137 | | | 138 | 11 | return upper_bucket_values; | 139 | 11 | } |
Unexecuted instantiation: _ZN5doris27calculate_bucket_max_valuesINS_7DecimalIlEEEEmRKSt3mapIT_mSt4lessIS4_ESaISt4pairIKS4_mEEEm Unexecuted instantiation: _ZN5doris27calculate_bucket_max_valuesINS_12Decimal128V3EEEmRKSt3mapIT_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Unexecuted instantiation: _ZN5doris27calculate_bucket_max_valuesINS_7DecimalIN4wide7integerILm256EiEEEEEEmRKSt3mapIT_mSt4lessIS7_ESaISt4pairIKS7_mEEEm _ZN5doris27calculate_bucket_max_valuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEmRKSt3mapIT_mSt4lessIS8_ESaISt4pairIKS8_mEEEm Line | Count | Source | 93 | 26 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 26 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 26 | size_t total_values = 0; | 99 | 2.08k | for (const auto& [value, count] : value_map) { | 100 | 2.08k | total_values += count; | 101 | 2.08k | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 26 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 26 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 26 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 26 | int search_step = 0; | 119 | 26 | const int max_search_steps = | 120 | 26 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 126 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 100 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 100 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 62 | upper_bucket_values = bucket_values; | 130 | 62 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 38 | lower_bucket_values = bucket_values; | 133 | 38 | } | 134 | | // Increment the search step counter | 135 | 100 | ++search_step; | 136 | 100 | } | 137 | | | 138 | 26 | return upper_bucket_values; | 139 | 26 | } |
_ZN5doris27calculate_bucket_max_valuesINS_11DateV2ValueINS_15DateV2ValueTypeEEEEEmRKSt3mapIT_mSt4lessIS5_ESaISt4pairIKS5_mEEEm Line | Count | Source | 93 | 13 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 13 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 13 | size_t total_values = 0; | 99 | 242 | for (const auto& [value, count] : value_map) { | 100 | 242 | total_values += count; | 101 | 242 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 13 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 13 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 13 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 13 | int search_step = 0; | 119 | 13 | const int max_search_steps = | 120 | 13 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 64 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 51 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 51 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 28 | upper_bucket_values = bucket_values; | 130 | 28 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 23 | lower_bucket_values = bucket_values; | 133 | 23 | } | 134 | | // Increment the search step counter | 135 | 51 | ++search_step; | 136 | 51 | } | 137 | | | 138 | 13 | return upper_bucket_values; | 139 | 13 | } |
_ZN5doris27calculate_bucket_max_valuesINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEEEEmRKSt3mapIT_mSt4lessIS5_ESaISt4pairIKS5_mEEEm Line | Count | Source | 93 | 13 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 13 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 13 | size_t total_values = 0; | 99 | 241 | for (const auto& [value, count] : value_map) { | 100 | 241 | total_values += count; | 101 | 241 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 13 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 13 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 13 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 13 | int search_step = 0; | 119 | 13 | const int max_search_steps = | 120 | 13 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 64 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 51 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 51 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 28 | upper_bucket_values = bucket_values; | 130 | 28 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 23 | lower_bucket_values = bucket_values; | 133 | 23 | } | 134 | | // Increment the search step counter | 135 | 51 | ++search_step; | 136 | 51 | } | 137 | | | 138 | 13 | return upper_bucket_values; | 139 | 13 | } |
Unexecuted instantiation: _ZN5doris27calculate_bucket_max_valuesINS_16TimeStampNsValueEEEmRKSt3mapIT_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Unexecuted instantiation: _ZN5doris27calculate_bucket_max_valuesINS_16TimestampTzValueEEEmRKSt3mapIT_mSt4lessIS3_ESaISt4pairIKS3_mEEEm _ZN5doris27calculate_bucket_max_valuesIoEEmRKSt3mapIT_mSt4lessIS2_ESaISt4pairIKS2_mEEEm Line | Count | Source | 93 | 4 | size_t calculate_bucket_max_values(const std::map<T, size_t>& value_map, const size_t num_buckets) { | 94 | | // Ensure that the value map is not empty | 95 | 4 | assert(!value_map.empty()); | 96 | | | 97 | | // Calculate the total number of values in the map using std::accumulate() | 98 | 4 | size_t total_values = 0; | 99 | 20 | for (const auto& [value, count] : value_map) { | 100 | 20 | total_values += count; | 101 | 20 | } | 102 | | | 103 | | // If there is only one bucket, then all values will be assigned to that bucket | 104 | 4 | if (num_buckets == 1) { | 105 | 0 | return total_values; | 106 | 0 | } | 107 | | | 108 | | // To calculate the maximum value count in each bucket, we first calculate a conservative upper | 109 | | // bound, which is equal to 2 * total_values / (max_buckets - 1) + 1. This upper bound may exceed | 110 | | // the actual maximum value count, but it does not underestimate it. The subsequent binary search | 111 | | // algorithm will approach the actual maximum value count. | 112 | 4 | size_t upper_bucket_values = 2 * total_values / (num_buckets - 1) + 1; | 113 | | | 114 | | // Initialize the lower bound to 0 | 115 | 4 | size_t lower_bucket_values = 0; | 116 | | | 117 | | // Perform a binary search to find the maximum number of values that can fit into each bucket | 118 | 4 | int search_step = 0; | 119 | 4 | const int max_search_steps = | 120 | 4 | 10; // Limit the number of search steps to avoid excessive iteration | 121 | | | 122 | 4 | while (upper_bucket_values > lower_bucket_values + 1 && search_step < max_search_steps) { | 123 | | // Calculate the midpoint of the upper and lower bounds | 124 | 0 | const size_t bucket_values = (upper_bucket_values + lower_bucket_values) / 2; | 125 | | | 126 | | // Check if the given number of values can be assigned to the desired number of buckets | 127 | 0 | if (can_assign_into_buckets(value_map, bucket_values, num_buckets)) { | 128 | | // If it can, then set the upper bound to the midpoint | 129 | 0 | upper_bucket_values = bucket_values; | 130 | 0 | } else { | 131 | | // If it can't, then set the lower bound to the midpoint | 132 | 0 | lower_bucket_values = bucket_values; | 133 | 0 | } | 134 | | // Increment the search step counter | 135 | 0 | ++search_step; | 136 | 0 | } | 137 | | | 138 | 4 | return upper_bucket_values; | 139 | 4 | } |
|
140 | | |
141 | | /** |
142 | | * Greedy equi-height histogram construction algorithm, inspired by the MySQL |
143 | | * equi_height implementation(https://dev.mysql.com/doc/dev/mysql-server/latest/equi__height_8h.html). |
144 | | * |
145 | | * Given an ordered collection of [value, count] pairs and a maximum bucket |
146 | | * size, construct a histogram by inserting values into a bucket while keeping |
147 | | * track of its size. If the insertion of a value into a non-empty bucket |
148 | | * causes the bucket to exceed the maximum size, create a new empty bucket and |
149 | | * continue. |
150 | | * |
151 | | * The algorithm guarantees a selectivity estimation error of at most ~2 * |
152 | | * #values / #buckets, often less. Values with a higher relative frequency are |
153 | | * guaranteed to be placed in singleton buckets. |
154 | | * |
155 | | * The minimum composite bucket size is used to minimize the worst case |
156 | | * selectivity estimation error. In general, the algorithm will adapt to the |
157 | | * data distribution to minimize the size of composite buckets. The heavy values |
158 | | * can be placed in singleton buckets and the remaining values will be evenly |
159 | | * spread across the remaining buckets, leading to a lower composite bucket size. |
160 | | * |
161 | | * Note: The term "value" refers to an entry in a column and the actual value |
162 | | * of an entry. The ordered_map is an ordered collection of [distinct value, |
163 | | * value count] pairs. For example, a Value_map<String> could contain the pairs ["a", 1], ["b", 2] |
164 | | * to represent one "a" value and two "b" values. |
165 | | * |
166 | | * @param buckets A vector of empty buckets that will be populated with data. |
167 | | * @param ordered_map An ordered map of distinct values and their counts. |
168 | | * @param max_num_buckets The maximum number of buckets that can be used. |
169 | | * |
170 | | * @return True if the buckets were successfully built, false otherwise. |
171 | | */ |
172 | | template <typename T> |
173 | | bool build_histogram(std::vector<Bucket<T>>& buckets, const std::map<T, size_t>& ordered_map, |
174 | 204 | const size_t max_num_buckets) { |
175 | | // If the input map is empty, there is nothing to build. |
176 | 204 | if (ordered_map.empty()) { |
177 | 32 | return false; |
178 | 32 | } |
179 | | |
180 | | // Calculate the maximum number of values that can be assigned to each bucket. |
181 | 172 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); |
182 | | |
183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional |
184 | | // allocations when inserting buckets. |
185 | 172 | buckets.clear(); |
186 | 172 | buckets.reserve(max_num_buckets); |
187 | | |
188 | | // Initialize bucket variables. |
189 | 172 | size_t distinct_values_count = 0; |
190 | 172 | size_t values_count = 0; |
191 | 172 | size_t cumulative_values = 0; |
192 | | |
193 | | // Record how many values still need to be assigned. |
194 | 172 | auto remaining_distinct_values = ordered_map.size(); |
195 | | |
196 | 172 | auto it = ordered_map.begin(); |
197 | | |
198 | | // Lower value of the current bucket. |
199 | 172 | const T* lower_value = &it->first; |
200 | | |
201 | | // Iterate over the ordered map of distinct values and their counts. |
202 | 4.53k | for (; it != ordered_map.end(); ++it) { |
203 | 4.36k | const auto count = it->second; |
204 | 4.36k | const auto current_value = it->first; |
205 | | |
206 | | // Update the bucket counts and track the number of distinct values assigned. |
207 | 4.36k | distinct_values_count++; |
208 | 4.36k | remaining_distinct_values--; |
209 | 4.36k | values_count += count; |
210 | 4.36k | cumulative_values += count; |
211 | | |
212 | | // Check whether the current value should be added to the current bucket. |
213 | 4.36k | auto next = std::next(it); |
214 | 4.36k | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; |
215 | | |
216 | 4.36k | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && |
217 | 4.36k | values_count + next->second <= bucket_max_values) { |
218 | | // If the current value is the last in the input map and there are more remaining |
219 | | // distinct values than empty buckets and adding the value does not cause the bucket |
220 | | // to exceed its max size, skip adding the value to the current bucket. |
221 | 3.89k | continue; |
222 | 3.89k | } |
223 | | |
224 | | // Finalize the current bucket and add it to our collection of buckets. |
225 | 466 | auto pre_sum = cumulative_values - values_count; |
226 | | |
227 | 466 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, |
228 | 466 | pre_sum); |
229 | 466 | buckets.push_back(new_bucket); |
230 | | |
231 | | // Reset variables for the next bucket. |
232 | 466 | if (next != ordered_map.end()) { |
233 | 294 | lower_value = &next->first; |
234 | 294 | } |
235 | 466 | values_count = 0; |
236 | 466 | distinct_values_count = 0; |
237 | 466 | } |
238 | | |
239 | 172 | return true; |
240 | 204 | } _ZN5doris15build_histogramIhEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 2 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 2 | if (ordered_map.empty()) { | 177 | 1 | return false; | 178 | 1 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 1 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 1 | buckets.clear(); | 186 | 1 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 1 | size_t distinct_values_count = 0; | 190 | 1 | size_t values_count = 0; | 191 | 1 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 1 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 1 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 1 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 3 | for (; it != ordered_map.end(); ++it) { | 203 | 2 | const auto count = it->second; | 204 | 2 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 2 | distinct_values_count++; | 208 | 2 | remaining_distinct_values--; | 209 | 2 | values_count += count; | 210 | 2 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 2 | auto next = std::next(it); | 214 | 2 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 2 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 2 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 0 | continue; | 222 | 0 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 2 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 2 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 2 | pre_sum); | 229 | 2 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 2 | if (next != ordered_map.end()) { | 233 | 1 | lower_value = &next->first; | 234 | 1 | } | 235 | 2 | values_count = 0; | 236 | 2 | distinct_values_count = 0; | 237 | 2 | } | 238 | | | 239 | 1 | return true; | 240 | 2 | } |
_ZN5doris15build_histogramIaEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 11 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 11 | if (ordered_map.empty()) { | 177 | 3 | return false; | 178 | 3 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 8 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 8 | buckets.clear(); | 186 | 8 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 8 | size_t distinct_values_count = 0; | 190 | 8 | size_t values_count = 0; | 191 | 8 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 8 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 8 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 8 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 240 | for (; it != ordered_map.end(); ++it) { | 203 | 232 | const auto count = it->second; | 204 | 232 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 232 | distinct_values_count++; | 208 | 232 | remaining_distinct_values--; | 209 | 232 | values_count += count; | 210 | 232 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 232 | auto next = std::next(it); | 214 | 232 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 232 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 232 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 211 | continue; | 222 | 211 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 21 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 21 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 21 | pre_sum); | 229 | 21 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 21 | if (next != ordered_map.end()) { | 233 | 13 | lower_value = &next->first; | 234 | 13 | } | 235 | 21 | values_count = 0; | 236 | 21 | distinct_values_count = 0; | 237 | 21 | } | 238 | | | 239 | 8 | return true; | 240 | 11 | } |
_ZN5doris15build_histogramIsEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 11 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 11 | if (ordered_map.empty()) { | 177 | 2 | return false; | 178 | 2 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 9 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 9 | buckets.clear(); | 186 | 9 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 9 | size_t distinct_values_count = 0; | 190 | 9 | size_t values_count = 0; | 191 | 9 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 9 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 9 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 9 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 250 | for (; it != ordered_map.end(); ++it) { | 203 | 241 | const auto count = it->second; | 204 | 241 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 241 | distinct_values_count++; | 208 | 241 | remaining_distinct_values--; | 209 | 241 | values_count += count; | 210 | 241 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 241 | auto next = std::next(it); | 214 | 241 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 241 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 241 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 217 | continue; | 222 | 217 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 24 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 24 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 24 | pre_sum); | 229 | 24 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 24 | if (next != ordered_map.end()) { | 233 | 15 | lower_value = &next->first; | 234 | 15 | } | 235 | 24 | values_count = 0; | 236 | 24 | distinct_values_count = 0; | 237 | 24 | } | 238 | | | 239 | 9 | return true; | 240 | 11 | } |
_ZN5doris15build_histogramIiEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 46 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 46 | if (ordered_map.empty()) { | 177 | 6 | return false; | 178 | 6 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 40 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 40 | buckets.clear(); | 186 | 40 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 40 | size_t distinct_values_count = 0; | 190 | 40 | size_t values_count = 0; | 191 | 40 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 40 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 40 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 40 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 300 | for (; it != ordered_map.end(); ++it) { | 203 | 260 | const auto count = it->second; | 204 | 260 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 260 | distinct_values_count++; | 208 | 260 | remaining_distinct_values--; | 209 | 260 | values_count += count; | 210 | 260 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 260 | auto next = std::next(it); | 214 | 260 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 260 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 260 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 202 | continue; | 222 | 202 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 58 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 58 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 58 | pre_sum); | 229 | 58 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 58 | if (next != ordered_map.end()) { | 233 | 18 | lower_value = &next->first; | 234 | 18 | } | 235 | 58 | values_count = 0; | 236 | 58 | distinct_values_count = 0; | 237 | 58 | } | 238 | | | 239 | 40 | return true; | 240 | 46 | } |
_ZN5doris15build_histogramIlEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 28 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 28 | if (ordered_map.empty()) { | 177 | 3 | return false; | 178 | 3 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 25 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 25 | buckets.clear(); | 186 | 25 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 25 | size_t distinct_values_count = 0; | 190 | 25 | size_t values_count = 0; | 191 | 25 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 25 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 25 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 25 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 335 | for (; it != ordered_map.end(); ++it) { | 203 | 310 | const auto count = it->second; | 204 | 310 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 310 | distinct_values_count++; | 208 | 310 | remaining_distinct_values--; | 209 | 310 | values_count += count; | 210 | 310 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 310 | auto next = std::next(it); | 214 | 310 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 310 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 310 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 206 | continue; | 222 | 206 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 104 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 104 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 104 | pre_sum); | 229 | 104 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 104 | if (next != ordered_map.end()) { | 233 | 79 | lower_value = &next->first; | 234 | 79 | } | 235 | 104 | values_count = 0; | 236 | 104 | distinct_values_count = 0; | 237 | 104 | } | 238 | | | 239 | 25 | return true; | 240 | 28 | } |
_ZN5doris15build_histogramInEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 11 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 11 | if (ordered_map.empty()) { | 177 | 3 | return false; | 178 | 3 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 8 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 8 | buckets.clear(); | 186 | 8 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 8 | size_t distinct_values_count = 0; | 190 | 8 | size_t values_count = 0; | 191 | 8 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 8 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 8 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 8 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 243 | for (; it != ordered_map.end(); ++it) { | 203 | 235 | const auto count = it->second; | 204 | 235 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 235 | distinct_values_count++; | 208 | 235 | remaining_distinct_values--; | 209 | 235 | values_count += count; | 210 | 235 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 235 | auto next = std::next(it); | 214 | 235 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 235 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 235 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 202 | continue; | 222 | 202 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 33 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 33 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 33 | pre_sum); | 229 | 33 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 33 | if (next != ordered_map.end()) { | 233 | 25 | lower_value = &next->first; | 234 | 25 | } | 235 | 33 | values_count = 0; | 236 | 33 | distinct_values_count = 0; | 237 | 33 | } | 238 | | | 239 | 8 | return true; | 240 | 11 | } |
_ZN5doris15build_histogramIfEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 9 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 9 | if (ordered_map.empty()) { | 177 | 2 | return false; | 178 | 2 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 7 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 7 | buckets.clear(); | 186 | 7 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 7 | size_t distinct_values_count = 0; | 190 | 7 | size_t values_count = 0; | 191 | 7 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 7 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 7 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 7 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 227 | for (; it != ordered_map.end(); ++it) { | 203 | 220 | const auto count = it->second; | 204 | 220 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 220 | distinct_values_count++; | 208 | 220 | remaining_distinct_values--; | 209 | 220 | values_count += count; | 210 | 220 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 220 | auto next = std::next(it); | 214 | 220 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 220 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 220 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 200 | continue; | 222 | 200 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 20 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 20 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 20 | pre_sum); | 229 | 20 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 20 | if (next != ordered_map.end()) { | 233 | 13 | lower_value = &next->first; | 234 | 13 | } | 235 | 20 | values_count = 0; | 236 | 20 | distinct_values_count = 0; | 237 | 20 | } | 238 | | | 239 | 7 | return true; | 240 | 9 | } |
_ZN5doris15build_histogramIdEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 9 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 9 | if (ordered_map.empty()) { | 177 | 2 | return false; | 178 | 2 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 7 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 7 | buckets.clear(); | 186 | 7 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 7 | size_t distinct_values_count = 0; | 190 | 7 | size_t values_count = 0; | 191 | 7 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 7 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 7 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 7 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 227 | for (; it != ordered_map.end(); ++it) { | 203 | 220 | const auto count = it->second; | 204 | 220 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 220 | distinct_values_count++; | 208 | 220 | remaining_distinct_values--; | 209 | 220 | values_count += count; | 210 | 220 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 220 | auto next = std::next(it); | 214 | 220 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 220 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 220 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 200 | continue; | 222 | 200 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 20 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 20 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 20 | pre_sum); | 229 | 20 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 20 | if (next != ordered_map.end()) { | 233 | 13 | lower_value = &next->first; | 234 | 13 | } | 235 | 20 | values_count = 0; | 236 | 20 | distinct_values_count = 0; | 237 | 20 | } | 238 | | | 239 | 7 | return true; | 240 | 9 | } |
_ZN5doris15build_histogramINS_7DecimalIiEEEEbRSt6vectorINS_6BucketIT_EESaIS6_EERKSt3mapIS5_mSt4lessIS5_ESaISt4pairIKS5_mEEEm Line | Count | Source | 174 | 12 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 12 | if (ordered_map.empty()) { | 177 | 1 | return false; | 178 | 1 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 11 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 11 | buckets.clear(); | 186 | 11 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 11 | size_t distinct_values_count = 0; | 190 | 11 | size_t values_count = 0; | 191 | 11 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 11 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 11 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 11 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 64 | for (; it != ordered_map.end(); ++it) { | 203 | 53 | const auto count = it->second; | 204 | 53 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 53 | distinct_values_count++; | 208 | 53 | remaining_distinct_values--; | 209 | 53 | values_count += count; | 210 | 53 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 53 | auto next = std::next(it); | 214 | 53 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 53 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 53 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 28 | continue; | 222 | 28 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 25 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 25 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 25 | pre_sum); | 229 | 25 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 25 | if (next != ordered_map.end()) { | 233 | 14 | lower_value = &next->first; | 234 | 14 | } | 235 | 25 | values_count = 0; | 236 | 25 | distinct_values_count = 0; | 237 | 25 | } | 238 | | | 239 | 11 | return true; | 240 | 12 | } |
Unexecuted instantiation: _ZN5doris15build_histogramINS_7DecimalIlEEEEbRSt6vectorINS_6BucketIT_EESaIS6_EERKSt3mapIS5_mSt4lessIS5_ESaISt4pairIKS5_mEEEm Unexecuted instantiation: _ZN5doris15build_histogramINS_12Decimal128V3EEEbRSt6vectorINS_6BucketIT_EESaIS5_EERKSt3mapIS4_mSt4lessIS4_ESaISt4pairIKS4_mEEEm Unexecuted instantiation: _ZN5doris15build_histogramINS_7DecimalIN4wide7integerILm256EiEEEEEEbRSt6vectorINS_6BucketIT_EESaIS9_EERKSt3mapIS8_mSt4lessIS8_ESaISt4pairIKS8_mEEEm _ZN5doris15build_histogramINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorINS_6BucketIT_EESaISA_EERKSt3mapIS9_mSt4lessIS9_ESaISt4pairIKS9_mEEEm Line | Count | Source | 174 | 31 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 31 | if (ordered_map.empty()) { | 177 | 5 | return false; | 178 | 5 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 26 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 26 | buckets.clear(); | 186 | 26 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 26 | size_t distinct_values_count = 0; | 190 | 26 | size_t values_count = 0; | 191 | 26 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 26 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 26 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 26 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 2.11k | for (; it != ordered_map.end(); ++it) { | 203 | 2.08k | const auto count = it->second; | 204 | 2.08k | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 2.08k | distinct_values_count++; | 208 | 2.08k | remaining_distinct_values--; | 209 | 2.08k | values_count += count; | 210 | 2.08k | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 2.08k | auto next = std::next(it); | 214 | 2.08k | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 2.08k | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 2.08k | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 2.02k | continue; | 222 | 2.02k | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 60 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 60 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 60 | pre_sum); | 229 | 60 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 60 | if (next != ordered_map.end()) { | 233 | 34 | lower_value = &next->first; | 234 | 34 | } | 235 | 60 | values_count = 0; | 236 | 60 | distinct_values_count = 0; | 237 | 60 | } | 238 | | | 239 | 26 | return true; | 240 | 31 | } |
_ZN5doris15build_histogramINS_11DateV2ValueINS_15DateV2ValueTypeEEEEEbRSt6vectorINS_6BucketIT_EESaIS7_EERKSt3mapIS6_mSt4lessIS6_ESaISt4pairIKS6_mEEEm Line | Count | Source | 174 | 14 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 14 | if (ordered_map.empty()) { | 177 | 1 | return false; | 178 | 1 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 13 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 13 | buckets.clear(); | 186 | 13 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 13 | size_t distinct_values_count = 0; | 190 | 13 | size_t values_count = 0; | 191 | 13 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 13 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 13 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 13 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 255 | for (; it != ordered_map.end(); ++it) { | 203 | 242 | const auto count = it->second; | 204 | 242 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 242 | distinct_values_count++; | 208 | 242 | remaining_distinct_values--; | 209 | 242 | values_count += count; | 210 | 242 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 242 | auto next = std::next(it); | 214 | 242 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 242 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 242 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 202 | continue; | 222 | 202 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 40 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 40 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 40 | pre_sum); | 229 | 40 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 40 | if (next != ordered_map.end()) { | 233 | 27 | lower_value = &next->first; | 234 | 27 | } | 235 | 40 | values_count = 0; | 236 | 40 | distinct_values_count = 0; | 237 | 40 | } | 238 | | | 239 | 13 | return true; | 240 | 14 | } |
_ZN5doris15build_histogramINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEEEEbRSt6vectorINS_6BucketIT_EESaIS7_EERKSt3mapIS6_mSt4lessIS6_ESaISt4pairIKS6_mEEEm Line | Count | Source | 174 | 14 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 14 | if (ordered_map.empty()) { | 177 | 1 | return false; | 178 | 1 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 13 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 13 | buckets.clear(); | 186 | 13 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 13 | size_t distinct_values_count = 0; | 190 | 13 | size_t values_count = 0; | 191 | 13 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 13 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 13 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 13 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 254 | for (; it != ordered_map.end(); ++it) { | 203 | 241 | const auto count = it->second; | 204 | 241 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 241 | distinct_values_count++; | 208 | 241 | remaining_distinct_values--; | 209 | 241 | values_count += count; | 210 | 241 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 241 | auto next = std::next(it); | 214 | 241 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 241 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 241 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 202 | continue; | 222 | 202 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 39 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 39 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 39 | pre_sum); | 229 | 39 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 39 | if (next != ordered_map.end()) { | 233 | 26 | lower_value = &next->first; | 234 | 26 | } | 235 | 39 | values_count = 0; | 236 | 39 | distinct_values_count = 0; | 237 | 39 | } | 238 | | | 239 | 13 | return true; | 240 | 14 | } |
Unexecuted instantiation: _ZN5doris15build_histogramINS_16TimeStampNsValueEEEbRSt6vectorINS_6BucketIT_EESaIS5_EERKSt3mapIS4_mSt4lessIS4_ESaISt4pairIKS4_mEEEm Unexecuted instantiation: _ZN5doris15build_histogramINS_16TimestampTzValueEEEbRSt6vectorINS_6BucketIT_EESaIS5_EERKSt3mapIS4_mSt4lessIS4_ESaISt4pairIKS4_mEEEm _ZN5doris15build_histogramIoEEbRSt6vectorINS_6BucketIT_EESaIS4_EERKSt3mapIS3_mSt4lessIS3_ESaISt4pairIKS3_mEEEm Line | Count | Source | 174 | 6 | const size_t max_num_buckets) { | 175 | | // If the input map is empty, there is nothing to build. | 176 | 6 | if (ordered_map.empty()) { | 177 | 2 | return false; | 178 | 2 | } | 179 | | | 180 | | // Calculate the maximum number of values that can be assigned to each bucket. | 181 | 4 | auto bucket_max_values = calculate_bucket_max_values(ordered_map, max_num_buckets); | 182 | | | 183 | | // Ensure that the capacity is at least max_num_buckets in order to avoid the overhead of additional | 184 | | // allocations when inserting buckets. | 185 | 4 | buckets.clear(); | 186 | 4 | buckets.reserve(max_num_buckets); | 187 | | | 188 | | // Initialize bucket variables. | 189 | 4 | size_t distinct_values_count = 0; | 190 | 4 | size_t values_count = 0; | 191 | 4 | size_t cumulative_values = 0; | 192 | | | 193 | | // Record how many values still need to be assigned. | 194 | 4 | auto remaining_distinct_values = ordered_map.size(); | 195 | | | 196 | 4 | auto it = ordered_map.begin(); | 197 | | | 198 | | // Lower value of the current bucket. | 199 | 4 | const T* lower_value = &it->first; | 200 | | | 201 | | // Iterate over the ordered map of distinct values and their counts. | 202 | 24 | for (; it != ordered_map.end(); ++it) { | 203 | 20 | const auto count = it->second; | 204 | 20 | const auto current_value = it->first; | 205 | | | 206 | | // Update the bucket counts and track the number of distinct values assigned. | 207 | 20 | distinct_values_count++; | 208 | 20 | remaining_distinct_values--; | 209 | 20 | values_count += count; | 210 | 20 | cumulative_values += count; | 211 | | | 212 | | // Check whether the current value should be added to the current bucket. | 213 | 20 | auto next = std::next(it); | 214 | 20 | size_t remaining_empty_buckets = max_num_buckets - buckets.size() - 1; | 215 | | | 216 | 20 | if (next != ordered_map.end() && remaining_distinct_values > remaining_empty_buckets && | 217 | 20 | values_count + next->second <= bucket_max_values) { | 218 | | // If the current value is the last in the input map and there are more remaining | 219 | | // distinct values than empty buckets and adding the value does not cause the bucket | 220 | | // to exceed its max size, skip adding the value to the current bucket. | 221 | 0 | continue; | 222 | 0 | } | 223 | | | 224 | | // Finalize the current bucket and add it to our collection of buckets. | 225 | 20 | auto pre_sum = cumulative_values - values_count; | 226 | | | 227 | 20 | Bucket<T> new_bucket(*lower_value, current_value, distinct_values_count, values_count, | 228 | 20 | pre_sum); | 229 | 20 | buckets.push_back(new_bucket); | 230 | | | 231 | | // Reset variables for the next bucket. | 232 | 20 | if (next != ordered_map.end()) { | 233 | 16 | lower_value = &next->first; | 234 | 16 | } | 235 | 20 | values_count = 0; | 236 | 20 | distinct_values_count = 0; | 237 | 20 | } | 238 | | | 239 | 4 | return true; | 240 | 6 | } |
|
241 | | |
242 | | template <typename T> |
243 | | bool histogram_to_json(rapidjson::StringBuffer& buffer, const std::vector<Bucket<T>>& buckets, |
244 | 199 | const DataTypePtr& data_type) { |
245 | 199 | rapidjson::Document doc; |
246 | 199 | doc.SetObject(); |
247 | 199 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); |
248 | | |
249 | 199 | int num_buckets = cast_set<int>(buckets.size()); |
250 | 199 | doc.AddMember("num_buckets", num_buckets, allocator); |
251 | | |
252 | 199 | rapidjson::Value bucket_arr(rapidjson::kArrayType); |
253 | 199 | bucket_arr.Reserve(num_buckets, allocator); |
254 | | |
255 | 199 | std::stringstream ss1; |
256 | 199 | std::stringstream ss2; |
257 | | |
258 | 199 | rapidjson::Value lower_val; |
259 | 199 | rapidjson::Value upper_val; |
260 | | |
261 | | // Convert bucket's lower and upper to 2 columns |
262 | 199 | MutableColumnPtr lower_column = data_type->create_column(); |
263 | 199 | MutableColumnPtr upper_column = data_type->create_column(); |
264 | 454 | for (const auto& bucket : buckets) { |
265 | | // String type is different, it has to pass in length |
266 | | // if it is string type , directly use string value |
267 | 454 | if constexpr (!std::is_same_v<T, std::string>) { |
268 | 394 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); |
269 | 394 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); |
270 | 394 | } |
271 | 454 | } |
272 | 199 | size_t row_num = 0; |
273 | | |
274 | 199 | auto format_options = DataTypeSerDe::get_default_format_options(); |
275 | 199 | auto time_zone = cctz::utc_time_zone(); |
276 | 199 | format_options.timezone = &time_zone; |
277 | | |
278 | 454 | for (const auto& bucket : buckets) { |
279 | 454 | if constexpr (std::is_same_v<T, std::string>) { |
280 | 60 | lower_val.SetString(bucket.lower.data(), |
281 | 60 | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); |
282 | 60 | upper_val.SetString(bucket.upper.data(), |
283 | 60 | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); |
284 | 394 | } else { |
285 | 394 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); |
286 | 394 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); |
287 | 394 | ++row_num; |
288 | 394 | lower_val.SetString(lower_str.data(), |
289 | 394 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); |
290 | 394 | upper_val.SetString(upper_str.data(), |
291 | 394 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); |
292 | 394 | } |
293 | 454 | rapidjson::Value bucket_json(rapidjson::kObjectType); |
294 | 454 | bucket_json.AddMember("lower", lower_val, allocator); |
295 | 454 | bucket_json.AddMember("upper", upper_val, allocator); |
296 | 454 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); |
297 | 454 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); |
298 | 454 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); |
299 | | |
300 | 454 | bucket_arr.PushBack(bucket_json, allocator); |
301 | 454 | } |
302 | | |
303 | 199 | doc.AddMember("buckets", bucket_arr, allocator); |
304 | 199 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); |
305 | 199 | doc.Accept(writer); |
306 | | |
307 | 199 | return !buckets.empty() && buffer.GetSize() > 0; |
308 | 199 | } _ZN5doris17histogram_to_jsonIhEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 2 | const DataTypePtr& data_type) { | 245 | 2 | rapidjson::Document doc; | 246 | 2 | doc.SetObject(); | 247 | 2 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 2 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 2 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 2 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 2 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 2 | std::stringstream ss1; | 256 | 2 | std::stringstream ss2; | 257 | | | 258 | 2 | rapidjson::Value lower_val; | 259 | 2 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 2 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 2 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 2 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 2 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 2 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 2 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 2 | } | 271 | 2 | } | 272 | 2 | size_t row_num = 0; | 273 | | | 274 | 2 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 2 | auto time_zone = cctz::utc_time_zone(); | 276 | 2 | format_options.timezone = &time_zone; | 277 | | | 278 | 2 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 2 | } else { | 285 | 2 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 2 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 2 | ++row_num; | 288 | 2 | lower_val.SetString(lower_str.data(), | 289 | 2 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 2 | upper_val.SetString(upper_str.data(), | 291 | 2 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 2 | } | 293 | 2 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 2 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 2 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 2 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 2 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 2 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 2 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 2 | } | 302 | | | 303 | 2 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 2 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 2 | doc.Accept(writer); | 306 | | | 307 | 2 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 2 | } |
_ZN5doris17histogram_to_jsonIaEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 11 | const DataTypePtr& data_type) { | 245 | 11 | rapidjson::Document doc; | 246 | 11 | doc.SetObject(); | 247 | 11 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 11 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 11 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 11 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 11 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 11 | std::stringstream ss1; | 256 | 11 | std::stringstream ss2; | 257 | | | 258 | 11 | rapidjson::Value lower_val; | 259 | 11 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 11 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 11 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 21 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 21 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 21 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 21 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 21 | } | 271 | 21 | } | 272 | 11 | size_t row_num = 0; | 273 | | | 274 | 11 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 11 | auto time_zone = cctz::utc_time_zone(); | 276 | 11 | format_options.timezone = &time_zone; | 277 | | | 278 | 21 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 21 | } else { | 285 | 21 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 21 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 21 | ++row_num; | 288 | 21 | lower_val.SetString(lower_str.data(), | 289 | 21 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 21 | upper_val.SetString(upper_str.data(), | 291 | 21 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 21 | } | 293 | 21 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 21 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 21 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 21 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 21 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 21 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 21 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 21 | } | 302 | | | 303 | 11 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 11 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 11 | doc.Accept(writer); | 306 | | | 307 | 11 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 11 | } |
_ZN5doris17histogram_to_jsonIsEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 11 | const DataTypePtr& data_type) { | 245 | 11 | rapidjson::Document doc; | 246 | 11 | doc.SetObject(); | 247 | 11 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 11 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 11 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 11 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 11 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 11 | std::stringstream ss1; | 256 | 11 | std::stringstream ss2; | 257 | | | 258 | 11 | rapidjson::Value lower_val; | 259 | 11 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 11 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 11 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 24 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 24 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 24 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 24 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 24 | } | 271 | 24 | } | 272 | 11 | size_t row_num = 0; | 273 | | | 274 | 11 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 11 | auto time_zone = cctz::utc_time_zone(); | 276 | 11 | format_options.timezone = &time_zone; | 277 | | | 278 | 24 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 24 | } else { | 285 | 24 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 24 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 24 | ++row_num; | 288 | 24 | lower_val.SetString(lower_str.data(), | 289 | 24 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 24 | upper_val.SetString(upper_str.data(), | 291 | 24 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 24 | } | 293 | 24 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 24 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 24 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 24 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 24 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 24 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 24 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 24 | } | 302 | | | 303 | 11 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 11 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 11 | doc.Accept(writer); | 306 | | | 307 | 11 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 11 | } |
_ZN5doris17histogram_to_jsonIiEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 41 | const DataTypePtr& data_type) { | 245 | 41 | rapidjson::Document doc; | 246 | 41 | doc.SetObject(); | 247 | 41 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 41 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 41 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 41 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 41 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 41 | std::stringstream ss1; | 256 | 41 | std::stringstream ss2; | 257 | | | 258 | 41 | rapidjson::Value lower_val; | 259 | 41 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 41 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 41 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 46 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 46 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 46 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 46 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 46 | } | 271 | 46 | } | 272 | 41 | size_t row_num = 0; | 273 | | | 274 | 41 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 41 | auto time_zone = cctz::utc_time_zone(); | 276 | 41 | format_options.timezone = &time_zone; | 277 | | | 278 | 46 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 46 | } else { | 285 | 46 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 46 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 46 | ++row_num; | 288 | 46 | lower_val.SetString(lower_str.data(), | 289 | 46 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 46 | upper_val.SetString(upper_str.data(), | 291 | 46 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 46 | } | 293 | 46 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 46 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 46 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 46 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 46 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 46 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 46 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 46 | } | 302 | | | 303 | 41 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 41 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 41 | doc.Accept(writer); | 306 | | | 307 | 41 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 41 | } |
_ZN5doris17histogram_to_jsonIlEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 28 | const DataTypePtr& data_type) { | 245 | 28 | rapidjson::Document doc; | 246 | 28 | doc.SetObject(); | 247 | 28 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 28 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 28 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 28 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 28 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 28 | std::stringstream ss1; | 256 | 28 | std::stringstream ss2; | 257 | | | 258 | 28 | rapidjson::Value lower_val; | 259 | 28 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 28 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 28 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 104 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 104 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 104 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 104 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 104 | } | 271 | 104 | } | 272 | 28 | size_t row_num = 0; | 273 | | | 274 | 28 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 28 | auto time_zone = cctz::utc_time_zone(); | 276 | 28 | format_options.timezone = &time_zone; | 277 | | | 278 | 104 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 104 | } else { | 285 | 104 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 104 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 104 | ++row_num; | 288 | 104 | lower_val.SetString(lower_str.data(), | 289 | 104 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 104 | upper_val.SetString(upper_str.data(), | 291 | 104 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 104 | } | 293 | 104 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 104 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 104 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 104 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 104 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 104 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 104 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 104 | } | 302 | | | 303 | 28 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 28 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 28 | doc.Accept(writer); | 306 | | | 307 | 28 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 28 | } |
_ZN5doris17histogram_to_jsonInEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 11 | const DataTypePtr& data_type) { | 245 | 11 | rapidjson::Document doc; | 246 | 11 | doc.SetObject(); | 247 | 11 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 11 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 11 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 11 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 11 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 11 | std::stringstream ss1; | 256 | 11 | std::stringstream ss2; | 257 | | | 258 | 11 | rapidjson::Value lower_val; | 259 | 11 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 11 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 11 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 33 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 33 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 33 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 33 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 33 | } | 271 | 33 | } | 272 | 11 | size_t row_num = 0; | 273 | | | 274 | 11 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 11 | auto time_zone = cctz::utc_time_zone(); | 276 | 11 | format_options.timezone = &time_zone; | 277 | | | 278 | 33 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 33 | } else { | 285 | 33 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 33 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 33 | ++row_num; | 288 | 33 | lower_val.SetString(lower_str.data(), | 289 | 33 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 33 | upper_val.SetString(upper_str.data(), | 291 | 33 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 33 | } | 293 | 33 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 33 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 33 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 33 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 33 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 33 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 33 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 33 | } | 302 | | | 303 | 11 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 11 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 11 | doc.Accept(writer); | 306 | | | 307 | 11 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 11 | } |
_ZN5doris17histogram_to_jsonIfEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 9 | const DataTypePtr& data_type) { | 245 | 9 | rapidjson::Document doc; | 246 | 9 | doc.SetObject(); | 247 | 9 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 9 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 9 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 9 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 9 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 9 | std::stringstream ss1; | 256 | 9 | std::stringstream ss2; | 257 | | | 258 | 9 | rapidjson::Value lower_val; | 259 | 9 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 9 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 9 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 20 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 20 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 20 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 20 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 20 | } | 271 | 20 | } | 272 | 9 | size_t row_num = 0; | 273 | | | 274 | 9 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 9 | auto time_zone = cctz::utc_time_zone(); | 276 | 9 | format_options.timezone = &time_zone; | 277 | | | 278 | 20 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 20 | } else { | 285 | 20 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 20 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 20 | ++row_num; | 288 | 20 | lower_val.SetString(lower_str.data(), | 289 | 20 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 20 | upper_val.SetString(upper_str.data(), | 291 | 20 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 20 | } | 293 | 20 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 20 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 20 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 20 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 20 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 20 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 20 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 20 | } | 302 | | | 303 | 9 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 9 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 9 | doc.Accept(writer); | 306 | | | 307 | 9 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 9 | } |
_ZN5doris17histogram_to_jsonIdEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 9 | const DataTypePtr& data_type) { | 245 | 9 | rapidjson::Document doc; | 246 | 9 | doc.SetObject(); | 247 | 9 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 9 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 9 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 9 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 9 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 9 | std::stringstream ss1; | 256 | 9 | std::stringstream ss2; | 257 | | | 258 | 9 | rapidjson::Value lower_val; | 259 | 9 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 9 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 9 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 20 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 20 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 20 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 20 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 20 | } | 271 | 20 | } | 272 | 9 | size_t row_num = 0; | 273 | | | 274 | 9 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 9 | auto time_zone = cctz::utc_time_zone(); | 276 | 9 | format_options.timezone = &time_zone; | 277 | | | 278 | 20 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 20 | } else { | 285 | 20 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 20 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 20 | ++row_num; | 288 | 20 | lower_val.SetString(lower_str.data(), | 289 | 20 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 20 | upper_val.SetString(upper_str.data(), | 291 | 20 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 20 | } | 293 | 20 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 20 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 20 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 20 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 20 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 20 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 20 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 20 | } | 302 | | | 303 | 9 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 9 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 9 | doc.Accept(writer); | 306 | | | 307 | 9 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 9 | } |
_ZN5doris17histogram_to_jsonINS_7DecimalIiEEEEbRN9rapidjson19GenericStringBufferINS3_4UTF8IcEENS3_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISD_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 12 | const DataTypePtr& data_type) { | 245 | 12 | rapidjson::Document doc; | 246 | 12 | doc.SetObject(); | 247 | 12 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 12 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 12 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 12 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 12 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 12 | std::stringstream ss1; | 256 | 12 | std::stringstream ss2; | 257 | | | 258 | 12 | rapidjson::Value lower_val; | 259 | 12 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 12 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 12 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 25 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 25 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 25 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 25 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 25 | } | 271 | 25 | } | 272 | 12 | size_t row_num = 0; | 273 | | | 274 | 12 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 12 | auto time_zone = cctz::utc_time_zone(); | 276 | 12 | format_options.timezone = &time_zone; | 277 | | | 278 | 25 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 25 | } else { | 285 | 25 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 25 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 25 | ++row_num; | 288 | 25 | lower_val.SetString(lower_str.data(), | 289 | 25 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 25 | upper_val.SetString(upper_str.data(), | 291 | 25 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 25 | } | 293 | 25 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 25 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 25 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 25 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 25 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 25 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 25 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 25 | } | 302 | | | 303 | 12 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 12 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 12 | doc.Accept(writer); | 306 | | | 307 | 12 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 12 | } |
Unexecuted instantiation: _ZN5doris17histogram_to_jsonINS_7DecimalIlEEEEbRN9rapidjson19GenericStringBufferINS3_4UTF8IcEENS3_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISD_EERKSt10shared_ptrIKNS_9IDataTypeEE Unexecuted instantiation: _ZN5doris17histogram_to_jsonINS_12Decimal128V3EEEbRN9rapidjson19GenericStringBufferINS2_4UTF8IcEENS2_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISC_EERKSt10shared_ptrIKNS_9IDataTypeEE Unexecuted instantiation: _ZN5doris17histogram_to_jsonINS_7DecimalIN4wide7integerILm256EiEEEEEEbRN9rapidjson19GenericStringBufferINS6_4UTF8IcEENS6_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISG_EERKSt10shared_ptrIKNS_9IDataTypeEE _ZN5doris17histogram_to_jsonINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRN9rapidjson19GenericStringBufferINS7_4UTF8IcEENS7_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISH_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 31 | const DataTypePtr& data_type) { | 245 | 31 | rapidjson::Document doc; | 246 | 31 | doc.SetObject(); | 247 | 31 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 31 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 31 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 31 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 31 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 31 | std::stringstream ss1; | 256 | 31 | std::stringstream ss2; | 257 | | | 258 | 31 | rapidjson::Value lower_val; | 259 | 31 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 31 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 31 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 60 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | | if constexpr (!std::is_same_v<T, std::string>) { | 268 | | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | | } | 271 | 60 | } | 272 | 31 | size_t row_num = 0; | 273 | | | 274 | 31 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 31 | auto time_zone = cctz::utc_time_zone(); | 276 | 31 | format_options.timezone = &time_zone; | 277 | | | 278 | 60 | for (const auto& bucket : buckets) { | 279 | 60 | if constexpr (std::is_same_v<T, std::string>) { | 280 | 60 | lower_val.SetString(bucket.lower.data(), | 281 | 60 | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | 60 | upper_val.SetString(bucket.upper.data(), | 283 | 60 | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | | } else { | 285 | | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | | ++row_num; | 288 | | lower_val.SetString(lower_str.data(), | 289 | | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | | upper_val.SetString(upper_str.data(), | 291 | | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | | } | 293 | 60 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 60 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 60 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 60 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 60 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 60 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 60 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 60 | } | 302 | | | 303 | 31 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 31 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 31 | doc.Accept(writer); | 306 | | | 307 | 31 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 31 | } |
_ZN5doris17histogram_to_jsonINS_11DateV2ValueINS_15DateV2ValueTypeEEEEEbRN9rapidjson19GenericStringBufferINS4_4UTF8IcEENS4_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISE_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 14 | const DataTypePtr& data_type) { | 245 | 14 | rapidjson::Document doc; | 246 | 14 | doc.SetObject(); | 247 | 14 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 14 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 14 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 14 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 14 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 14 | std::stringstream ss1; | 256 | 14 | std::stringstream ss2; | 257 | | | 258 | 14 | rapidjson::Value lower_val; | 259 | 14 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 14 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 14 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 40 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 40 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 40 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 40 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 40 | } | 271 | 40 | } | 272 | 14 | size_t row_num = 0; | 273 | | | 274 | 14 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 14 | auto time_zone = cctz::utc_time_zone(); | 276 | 14 | format_options.timezone = &time_zone; | 277 | | | 278 | 40 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 40 | } else { | 285 | 40 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 40 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 40 | ++row_num; | 288 | 40 | lower_val.SetString(lower_str.data(), | 289 | 40 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 40 | upper_val.SetString(upper_str.data(), | 291 | 40 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 40 | } | 293 | 40 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 40 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 40 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 40 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 40 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 40 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 40 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 40 | } | 302 | | | 303 | 14 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 14 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 14 | doc.Accept(writer); | 306 | | | 307 | 14 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 14 | } |
_ZN5doris17histogram_to_jsonINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEEEEbRN9rapidjson19GenericStringBufferINS4_4UTF8IcEENS4_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISE_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 14 | const DataTypePtr& data_type) { | 245 | 14 | rapidjson::Document doc; | 246 | 14 | doc.SetObject(); | 247 | 14 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 14 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 14 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 14 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 14 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 14 | std::stringstream ss1; | 256 | 14 | std::stringstream ss2; | 257 | | | 258 | 14 | rapidjson::Value lower_val; | 259 | 14 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 14 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 14 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 39 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 39 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 39 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 39 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 39 | } | 271 | 39 | } | 272 | 14 | size_t row_num = 0; | 273 | | | 274 | 14 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 14 | auto time_zone = cctz::utc_time_zone(); | 276 | 14 | format_options.timezone = &time_zone; | 277 | | | 278 | 39 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 39 | } else { | 285 | 39 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 39 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 39 | ++row_num; | 288 | 39 | lower_val.SetString(lower_str.data(), | 289 | 39 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 39 | upper_val.SetString(upper_str.data(), | 291 | 39 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 39 | } | 293 | 39 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 39 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 39 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 39 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 39 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 39 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 39 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 39 | } | 302 | | | 303 | 14 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 14 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 14 | doc.Accept(writer); | 306 | | | 307 | 14 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 14 | } |
Unexecuted instantiation: _ZN5doris17histogram_to_jsonINS_16TimeStampNsValueEEEbRN9rapidjson19GenericStringBufferINS2_4UTF8IcEENS2_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISC_EERKSt10shared_ptrIKNS_9IDataTypeEE Unexecuted instantiation: _ZN5doris17histogram_to_jsonINS_16TimestampTzValueEEEbRN9rapidjson19GenericStringBufferINS2_4UTF8IcEENS2_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISC_EERKSt10shared_ptrIKNS_9IDataTypeEE _ZN5doris17histogram_to_jsonIoEEbRN9rapidjson19GenericStringBufferINS1_4UTF8IcEENS1_12CrtAllocatorEEERKSt6vectorINS_6BucketIT_EESaISB_EERKSt10shared_ptrIKNS_9IDataTypeEE Line | Count | Source | 244 | 6 | const DataTypePtr& data_type) { | 245 | 6 | rapidjson::Document doc; | 246 | 6 | doc.SetObject(); | 247 | 6 | rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); | 248 | | | 249 | 6 | int num_buckets = cast_set<int>(buckets.size()); | 250 | 6 | doc.AddMember("num_buckets", num_buckets, allocator); | 251 | | | 252 | 6 | rapidjson::Value bucket_arr(rapidjson::kArrayType); | 253 | 6 | bucket_arr.Reserve(num_buckets, allocator); | 254 | | | 255 | 6 | std::stringstream ss1; | 256 | 6 | std::stringstream ss2; | 257 | | | 258 | 6 | rapidjson::Value lower_val; | 259 | 6 | rapidjson::Value upper_val; | 260 | | | 261 | | // Convert bucket's lower and upper to 2 columns | 262 | 6 | MutableColumnPtr lower_column = data_type->create_column(); | 263 | 6 | MutableColumnPtr upper_column = data_type->create_column(); | 264 | 20 | for (const auto& bucket : buckets) { | 265 | | // String type is different, it has to pass in length | 266 | | // if it is string type , directly use string value | 267 | 20 | if constexpr (!std::is_same_v<T, std::string>) { | 268 | 20 | lower_column->insert_data(reinterpret_cast<const char*>(&bucket.lower), 0); | 269 | 20 | upper_column->insert_data(reinterpret_cast<const char*>(&bucket.upper), 0); | 270 | 20 | } | 271 | 20 | } | 272 | 6 | size_t row_num = 0; | 273 | | | 274 | 6 | auto format_options = DataTypeSerDe::get_default_format_options(); | 275 | 6 | auto time_zone = cctz::utc_time_zone(); | 276 | 6 | format_options.timezone = &time_zone; | 277 | | | 278 | 20 | for (const auto& bucket : buckets) { | 279 | | if constexpr (std::is_same_v<T, std::string>) { | 280 | | lower_val.SetString(bucket.lower.data(), | 281 | | static_cast<rapidjson::SizeType>(bucket.lower.size()), allocator); | 282 | | upper_val.SetString(bucket.upper.data(), | 283 | | static_cast<rapidjson::SizeType>(bucket.upper.size()), allocator); | 284 | 20 | } else { | 285 | 20 | std::string lower_str = data_type->to_string(*lower_column, row_num, format_options); | 286 | 20 | std::string upper_str = data_type->to_string(*upper_column, row_num, format_options); | 287 | 20 | ++row_num; | 288 | 20 | lower_val.SetString(lower_str.data(), | 289 | 20 | static_cast<rapidjson::SizeType>(lower_str.size()), allocator); | 290 | 20 | upper_val.SetString(upper_str.data(), | 291 | 20 | static_cast<rapidjson::SizeType>(upper_str.size()), allocator); | 292 | 20 | } | 293 | 20 | rapidjson::Value bucket_json(rapidjson::kObjectType); | 294 | 20 | bucket_json.AddMember("lower", lower_val, allocator); | 295 | 20 | bucket_json.AddMember("upper", upper_val, allocator); | 296 | 20 | bucket_json.AddMember("ndv", static_cast<int64_t>(bucket.ndv), allocator); | 297 | 20 | bucket_json.AddMember("count", static_cast<int64_t>(bucket.count), allocator); | 298 | 20 | bucket_json.AddMember("pre_sum", static_cast<int64_t>(bucket.pre_sum), allocator); | 299 | | | 300 | 20 | bucket_arr.PushBack(bucket_json, allocator); | 301 | 20 | } | 302 | | | 303 | 6 | doc.AddMember("buckets", bucket_arr, allocator); | 304 | 6 | rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | 305 | 6 | doc.Accept(writer); | 306 | | | 307 | 6 | return !buckets.empty() && buffer.GetSize() > 0; | 308 | 6 | } |
|
309 | | } // namespace doris |