Coverage Report

Created: 2025-04-16 14:29

/root/doris/be/src/util/counts.h
Line
Count
Source (jump to first uncovered line)
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 <algorithm>
21
#include <cmath>
22
#include <unordered_map>
23
#include <vector>
24
25
#include "udf/udf.h"
26
27
namespace doris {
28
29
template <typename T>
30
class Counts {
31
public:
32
3
    Counts() = default;
_ZN5doris6CountsIlEC2Ev
Line
Count
Source
32
3
    Counts() = default;
Unexecuted instantiation: _ZN5doris6CountsIhEC2Ev
Unexecuted instantiation: _ZN5doris6CountsIaEC2Ev
Unexecuted instantiation: _ZN5doris6CountsIsEC2Ev
Unexecuted instantiation: _ZN5doris6CountsIiEC2Ev
Unexecuted instantiation: _ZN5doris6CountsInEC2Ev
Unexecuted instantiation: _ZN5doris6CountsIfEC2Ev
Unexecuted instantiation: _ZN5doris6CountsIdEC2Ev
33
34
1
    inline void merge(const Counts* other) {
35
1
        if (other == nullptr || other->_counts.empty()) {
36
0
            return;
37
0
        }
38
39
5
        for (auto& cell : other->_counts) {
40
5
            increment(cell.first, cell.second);
41
5
        }
42
1
    }
_ZN5doris6CountsIlE5mergeEPKS1_
Line
Count
Source
34
1
    inline void merge(const Counts* other) {
35
1
        if (other == nullptr || other->_counts.empty()) {
36
0
            return;
37
0
        }
38
39
5
        for (auto& cell : other->_counts) {
40
5
            increment(cell.first, cell.second);
41
5
        }
42
1
    }
Unexecuted instantiation: _ZN5doris6CountsIhE5mergeEPKS1_
Unexecuted instantiation: _ZN5doris6CountsIaE5mergeEPKS1_
Unexecuted instantiation: _ZN5doris6CountsIsE5mergeEPKS1_
Unexecuted instantiation: _ZN5doris6CountsIiE5mergeEPKS1_
Unexecuted instantiation: _ZN5doris6CountsInE5mergeEPKS1_
Unexecuted instantiation: _ZN5doris6CountsIfE5mergeEPKS1_
Unexecuted instantiation: _ZN5doris6CountsIdE5mergeEPKS1_
43
44
17
    void increment(T key, uint32_t i) {
45
17
        auto item = _counts.find(key);
46
17
        if (item != _counts.end()) {
47
2
            item->second += i;
48
15
        } else {
49
15
            _counts.emplace(std::make_pair(key, i));
50
15
        }
51
17
    }
_ZN5doris6CountsIlE9incrementElj
Line
Count
Source
44
17
    void increment(T key, uint32_t i) {
45
17
        auto item = _counts.find(key);
46
17
        if (item != _counts.end()) {
47
2
            item->second += i;
48
15
        } else {
49
15
            _counts.emplace(std::make_pair(key, i));
50
15
        }
51
17
    }
Unexecuted instantiation: _ZN5doris6CountsIhE9incrementEhj
Unexecuted instantiation: _ZN5doris6CountsIaE9incrementEaj
Unexecuted instantiation: _ZN5doris6CountsIsE9incrementEsj
Unexecuted instantiation: _ZN5doris6CountsIiE9incrementEij
Unexecuted instantiation: _ZN5doris6CountsInE9incrementEnj
Unexecuted instantiation: _ZN5doris6CountsIfE9incrementEfj
Unexecuted instantiation: _ZN5doris6CountsIdE9incrementEdj
52
53
1
    uint32_t serialized_size() const {
54
1
        return sizeof(uint32_t) + sizeof(T) * _counts.size() + sizeof(uint32_t) * _counts.size();
55
1
    }
_ZNK5doris6CountsIlE15serialized_sizeEv
Line
Count
Source
53
1
    uint32_t serialized_size() const {
54
1
        return sizeof(uint32_t) + sizeof(T) * _counts.size() + sizeof(uint32_t) * _counts.size();
55
1
    }
Unexecuted instantiation: _ZNK5doris6CountsIhE15serialized_sizeEv
Unexecuted instantiation: _ZNK5doris6CountsIaE15serialized_sizeEv
Unexecuted instantiation: _ZNK5doris6CountsIsE15serialized_sizeEv
Unexecuted instantiation: _ZNK5doris6CountsIiE15serialized_sizeEv
Unexecuted instantiation: _ZNK5doris6CountsInE15serialized_sizeEv
Unexecuted instantiation: _ZNK5doris6CountsIfE15serialized_sizeEv
Unexecuted instantiation: _ZNK5doris6CountsIdE15serialized_sizeEv
56
57
1
    void serialize(uint8_t* writer) const {
58
1
        uint32_t size = _counts.size();
59
1
        memcpy(writer, &size, sizeof(uint32_t));
60
1
        writer += sizeof(uint32_t);
61
6
        for (auto& cell : _counts) {
62
6
            memcpy(writer, &cell.first, sizeof(T));
63
6
            writer += sizeof(T);
64
6
            memcpy(writer, &cell.second, sizeof(uint32_t));
65
6
            writer += sizeof(uint32_t);
66
6
        }
67
1
    }
_ZNK5doris6CountsIlE9serializeEPh
Line
Count
Source
57
1
    void serialize(uint8_t* writer) const {
58
1
        uint32_t size = _counts.size();
59
1
        memcpy(writer, &size, sizeof(uint32_t));
60
1
        writer += sizeof(uint32_t);
61
6
        for (auto& cell : _counts) {
62
6
            memcpy(writer, &cell.first, sizeof(T));
63
6
            writer += sizeof(T);
64
6
            memcpy(writer, &cell.second, sizeof(uint32_t));
65
6
            writer += sizeof(uint32_t);
66
6
        }
67
1
    }
Unexecuted instantiation: _ZNK5doris6CountsIhE9serializeEPh
Unexecuted instantiation: _ZNK5doris6CountsIaE9serializeEPh
Unexecuted instantiation: _ZNK5doris6CountsIsE9serializeEPh
Unexecuted instantiation: _ZNK5doris6CountsIiE9serializeEPh
Unexecuted instantiation: _ZNK5doris6CountsInE9serializeEPh
Unexecuted instantiation: _ZNK5doris6CountsIfE9serializeEPh
Unexecuted instantiation: _ZNK5doris6CountsIdE9serializeEPh
68
69
1
    void unserialize(const uint8_t* type_reader) {
70
1
        uint32_t size;
71
1
        memcpy(&size, type_reader, sizeof(uint32_t));
72
1
        type_reader += sizeof(uint32_t);
73
7
        for (uint32_t i = 0; i < size; ++i) {
74
6
            T key;
75
6
            uint32_t count;
76
6
            memcpy(&key, type_reader, sizeof(T));
77
6
            type_reader += sizeof(T);
78
6
            memcpy(&count, type_reader, sizeof(uint32_t));
79
6
            type_reader += sizeof(uint32_t);
80
6
            _counts.emplace(std::make_pair(key, count));
81
6
        }
82
1
    }
_ZN5doris6CountsIlE11unserializeEPKh
Line
Count
Source
69
1
    void unserialize(const uint8_t* type_reader) {
70
1
        uint32_t size;
71
1
        memcpy(&size, type_reader, sizeof(uint32_t));
72
1
        type_reader += sizeof(uint32_t);
73
7
        for (uint32_t i = 0; i < size; ++i) {
74
6
            T key;
75
6
            uint32_t count;
76
6
            memcpy(&key, type_reader, sizeof(T));
77
6
            type_reader += sizeof(T);
78
6
            memcpy(&count, type_reader, sizeof(uint32_t));
79
6
            type_reader += sizeof(uint32_t);
80
6
            _counts.emplace(std::make_pair(key, count));
81
6
        }
82
1
    }
Unexecuted instantiation: _ZN5doris6CountsIhE11unserializeEPKh
Unexecuted instantiation: _ZN5doris6CountsIaE11unserializeEPKh
Unexecuted instantiation: _ZN5doris6CountsIsE11unserializeEPKh
Unexecuted instantiation: _ZN5doris6CountsIiE11unserializeEPKh
Unexecuted instantiation: _ZN5doris6CountsInE11unserializeEPKh
Unexecuted instantiation: _ZN5doris6CountsIfE11unserializeEPKh
Unexecuted instantiation: _ZN5doris6CountsIdE11unserializeEPKh
83
84
3
    double get_percentile(std::vector<std::pair<T, uint32_t>>& counts, double position) const {
85
3
        long lower = long(std::floor(position));
86
3
        long higher = long(std::ceil(position));
87
88
3
        auto iter = counts.begin();
89
5
        for (; iter != counts.end() && iter->second < lower + 1; ++iter)
90
2
            ;
91
92
3
        T lower_key = iter->first;
93
3
        if (higher == lower) {
94
0
            return lower_key;
95
0
        }
96
97
3
        if (iter->second < higher + 1) {
98
1
            iter++;
99
1
        }
100
101
3
        T higher_key = iter->first;
102
3
        if (lower_key == higher_key) {
103
2
            return lower_key;
104
2
        }
105
106
1
        return (higher - position) * lower_key + (position - lower) * higher_key;
107
3
    }
_ZNK5doris6CountsIlE14get_percentileERSt6vectorISt4pairIljESaIS4_EEd
Line
Count
Source
84
3
    double get_percentile(std::vector<std::pair<T, uint32_t>>& counts, double position) const {
85
3
        long lower = long(std::floor(position));
86
3
        long higher = long(std::ceil(position));
87
88
3
        auto iter = counts.begin();
89
5
        for (; iter != counts.end() && iter->second < lower + 1; ++iter)
90
2
            ;
91
92
3
        T lower_key = iter->first;
93
3
        if (higher == lower) {
94
0
            return lower_key;
95
0
        }
96
97
3
        if (iter->second < higher + 1) {
98
1
            iter++;
99
1
        }
100
101
3
        T higher_key = iter->first;
102
3
        if (lower_key == higher_key) {
103
2
            return lower_key;
104
2
        }
105
106
1
        return (higher - position) * lower_key + (position - lower) * higher_key;
107
3
    }
Unexecuted instantiation: _ZNK5doris6CountsIhE14get_percentileERSt6vectorISt4pairIhjESaIS4_EEd
Unexecuted instantiation: _ZNK5doris6CountsIaE14get_percentileERSt6vectorISt4pairIajESaIS4_EEd
Unexecuted instantiation: _ZNK5doris6CountsIsE14get_percentileERSt6vectorISt4pairIsjESaIS4_EEd
Unexecuted instantiation: _ZNK5doris6CountsIiE14get_percentileERSt6vectorISt4pairIijESaIS4_EEd
Unexecuted instantiation: _ZNK5doris6CountsInE14get_percentileERSt6vectorISt4pairInjESaIS4_EEd
Unexecuted instantiation: _ZNK5doris6CountsIfE14get_percentileERSt6vectorISt4pairIfjESaIS4_EEd
Unexecuted instantiation: _ZNK5doris6CountsIdE14get_percentileERSt6vectorISt4pairIdjESaIS4_EEd
108
109
3
    double terminate(double quantile) const {
110
3
        if (_counts.empty()) {
111
            // Although set null here, but the value is 0.0 and the call method just
112
            // get val in aggregate_function_percentile_approx.h
113
0
            return 0.0;
114
0
        }
115
116
3
        std::vector<std::pair<T, uint32_t>> elems(_counts.begin(), _counts.end());
117
3
        sort(elems.begin(), elems.end(),
118
53
             [](const std::pair<T, uint32_t> l, const std::pair<T, uint32_t> r) {
119
53
                 return l.first < r.first;
120
53
             });
_ZZNK5doris6CountsIlE9terminateEdENKUlSt4pairIljES3_E_clES3_S3_
Line
Count
Source
118
53
             [](const std::pair<T, uint32_t> l, const std::pair<T, uint32_t> r) {
119
53
                 return l.first < r.first;
120
53
             });
Unexecuted instantiation: _ZZNK5doris6CountsIhE9terminateEdENKUlSt4pairIhjES3_E_clES3_S3_
Unexecuted instantiation: _ZZNK5doris6CountsIaE9terminateEdENKUlSt4pairIajES3_E_clES3_S3_
Unexecuted instantiation: _ZZNK5doris6CountsIsE9terminateEdENKUlSt4pairIsjES3_E_clES3_S3_
Unexecuted instantiation: _ZZNK5doris6CountsIiE9terminateEdENKUlSt4pairIijES3_E_clES3_S3_
Unexecuted instantiation: _ZZNK5doris6CountsInE9terminateEdENKUlSt4pairInjES3_E_clES3_S3_
Unexecuted instantiation: _ZZNK5doris6CountsIfE9terminateEdENKUlSt4pairIfjES3_E_clES3_S3_
Unexecuted instantiation: _ZZNK5doris6CountsIdE9terminateEdENKUlSt4pairIdjES3_E_clES3_S3_
121
122
3
        long total = 0;
123
22
        for (auto& cell : elems) {
124
22
            total += cell.second;
125
22
            cell.second = total;
126
22
        }
127
128
3
        long max_position = total - 1;
129
3
        double position = max_position * quantile;
130
3
        return get_percentile(elems, position);
131
3
    }
_ZNK5doris6CountsIlE9terminateEd
Line
Count
Source
109
3
    double terminate(double quantile) const {
110
3
        if (_counts.empty()) {
111
            // Although set null here, but the value is 0.0 and the call method just
112
            // get val in aggregate_function_percentile_approx.h
113
0
            return 0.0;
114
0
        }
115
116
3
        std::vector<std::pair<T, uint32_t>> elems(_counts.begin(), _counts.end());
117
3
        sort(elems.begin(), elems.end(),
118
3
             [](const std::pair<T, uint32_t> l, const std::pair<T, uint32_t> r) {
119
3
                 return l.first < r.first;
120
3
             });
121
122
3
        long total = 0;
123
22
        for (auto& cell : elems) {
124
22
            total += cell.second;
125
22
            cell.second = total;
126
22
        }
127
128
3
        long max_position = total - 1;
129
3
        double position = max_position * quantile;
130
3
        return get_percentile(elems, position);
131
3
    }
Unexecuted instantiation: _ZNK5doris6CountsIhE9terminateEd
Unexecuted instantiation: _ZNK5doris6CountsIaE9terminateEd
Unexecuted instantiation: _ZNK5doris6CountsIsE9terminateEd
Unexecuted instantiation: _ZNK5doris6CountsIiE9terminateEd
Unexecuted instantiation: _ZNK5doris6CountsInE9terminateEd
Unexecuted instantiation: _ZNK5doris6CountsIfE9terminateEd
Unexecuted instantiation: _ZNK5doris6CountsIdE9terminateEd
132
133
private:
134
    std::unordered_map<T, uint32_t> _counts;
135
};
136
137
} // namespace doris