Coverage Report

Created: 2026-08-15 14:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/bitset_container.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <array>
21
#include <cstddef>
22
#include <cstdint>
23
#include <type_traits>
24
#include <vector>
25
26
#include "common/compiler_util.h"
27
28
namespace doris {
29
30
template <typename T>
31
struct BitSetContainerTraits {
32
    static constexpr size_t RANGE = 0;
33
};
34
35
template <>
36
struct BitSetContainerTraits<int8_t> {
37
    static constexpr size_t RANGE = 256;
38
};
39
40
template <>
41
struct BitSetContainerTraits<int16_t> {
42
    static constexpr size_t RANGE = 65536;
43
};
44
45
template <typename T>
46
class BitSetContainer {
47
public:
48
    using Self = BitSetContainer;
49
    using ElementType = T;
50
51
    static_assert(std::is_same_v<T, int8_t> || std::is_same_v<T, int16_t>,
52
                  "BitSetContainer only supports int8_t or int16_t");
53
54
    static constexpr size_t RANGE = BitSetContainerTraits<T>::RANGE;
55
56
    class Iterator {
57
    public:
58
        explicit Iterator(const std::array<bool, RANGE>* data, size_t index)
59
4.72k
                : _data(data), _index(index) {
60
4.72k
            _find_next();
61
4.72k
        }
_ZN5doris15BitSetContainerIaE8IteratorC2EPKSt5arrayIbLm256EEm
Line
Count
Source
59
3.09k
                : _data(data), _index(index) {
60
3.09k
            _find_next();
61
3.09k
        }
_ZN5doris15BitSetContainerIsE8IteratorC2EPKSt5arrayIbLm65536EEm
Line
Count
Source
59
1.62k
                : _data(data), _index(index) {
60
1.62k
            _find_next();
61
1.62k
        }
62
63
4.22k
        Iterator& operator++() {
64
4.22k
            ++_index;
65
4.22k
            _find_next();
66
4.22k
            return *this;
67
4.22k
        }
_ZN5doris15BitSetContainerIaE8IteratorppEv
Line
Count
Source
63
1.55k
        Iterator& operator++() {
64
1.55k
            ++_index;
65
1.55k
            _find_next();
66
1.55k
            return *this;
67
1.55k
        }
_ZN5doris15BitSetContainerIsE8IteratorppEv
Line
Count
Source
63
2.66k
        Iterator& operator++() {
64
2.66k
            ++_index;
65
2.66k
            _find_next();
66
2.66k
            return *this;
67
2.66k
        }
68
69
        Iterator operator++(int) {
70
            Iterator ret_val = *this;
71
            ++(*this);
72
            return ret_val;
73
        }
74
75
7.11k
        bool operator==(Iterator other) const { return _index == other._index; }
_ZNK5doris15BitSetContainerIaE8IteratoreqES2_
Line
Count
Source
75
3.48k
        bool operator==(Iterator other) const { return _index == other._index; }
_ZNK5doris15BitSetContainerIsE8IteratoreqES2_
Line
Count
Source
75
3.63k
        bool operator==(Iterator other) const { return _index == other._index; }
76
2.62k
        bool operator!=(Iterator other) const { return !(*this == other); }
_ZNK5doris15BitSetContainerIaE8IteratorneES2_
Line
Count
Source
76
1.32k
        bool operator!=(Iterator other) const { return !(*this == other); }
_ZNK5doris15BitSetContainerIsE8IteratorneES2_
Line
Count
Source
76
1.30k
        bool operator!=(Iterator other) const { return !(*this == other); }
77
78
810
        T operator*() const { return static_cast<T>(_index); }
_ZNK5doris15BitSetContainerIaE8IteratordeEv
Line
Count
Source
78
315
        T operator*() const { return static_cast<T>(_index); }
_ZNK5doris15BitSetContainerIsE8IteratordeEv
Line
Count
Source
78
495
        T operator*() const { return static_cast<T>(_index); }
79
80
3.38k
        T* operator->() const {
81
3.38k
            _cached_value = static_cast<T>(_index);
82
3.38k
            return &_cached_value;
83
3.38k
        }
_ZNK5doris15BitSetContainerIaE8IteratorptEv
Line
Count
Source
80
1.24k
        T* operator->() const {
81
1.24k
            _cached_value = static_cast<T>(_index);
82
1.24k
            return &_cached_value;
83
1.24k
        }
_ZNK5doris15BitSetContainerIsE8IteratorptEv
Line
Count
Source
80
2.14k
        T* operator->() const {
81
2.14k
            _cached_value = static_cast<T>(_index);
82
2.14k
            return &_cached_value;
83
2.14k
        }
84
85
        using iterator_category = std::forward_iterator_tag;
86
        using difference_type = std::ptrdiff_t;
87
        using value_type = T;
88
        using pointer = const T*;
89
        using reference = const T&;
90
91
    private:
92
8.94k
        void _find_next() {
93
50.7M
            while (_index < RANGE && !(*_data)[_index]) {
94
50.7M
                ++_index;
95
50.7M
            }
96
8.94k
        }
_ZN5doris15BitSetContainerIaE8Iterator10_find_nextEv
Line
Count
Source
92
4.65k
        void _find_next() {
93
429k
            while (_index < RANGE && !(*_data)[_index]) {
94
424k
                ++_index;
95
424k
            }
96
4.65k
        }
_ZN5doris15BitSetContainerIsE8Iterator10_find_nextEv
Line
Count
Source
92
4.29k
        void _find_next() {
93
50.3M
            while (_index < RANGE && !(*_data)[_index]) {
94
50.3M
                ++_index;
95
50.3M
            }
96
4.29k
        }
97
98
        const std::array<bool, RANGE>* _data;
99
        size_t _index;
100
        mutable T _cached_value = T();
101
    };
102
103
3.69k
    BitSetContainer() { _data.fill(false); }
_ZN5doris15BitSetContainerIaEC2Ev
Line
Count
Source
103
2.09k
    BitSetContainer() { _data.fill(false); }
_ZN5doris15BitSetContainerIsEC2Ev
Line
Count
Source
103
1.59k
    BitSetContainer() { _data.fill(false); }
104
105
    ~BitSetContainer() = default;
106
107
1.17k
    ALWAYS_INLINE void insert(const T& value) {
108
1.17k
        auto idx = _to_index(value);
109
1.17k
        if (!_data[idx]) {
110
658
            _data[idx] = true;
111
658
            _size++;
112
658
        }
113
1.17k
    }
_ZN5doris15BitSetContainerIaE6insertERKa
Line
Count
Source
107
442
    ALWAYS_INLINE void insert(const T& value) {
108
442
        auto idx = _to_index(value);
109
442
        if (!_data[idx]) {
110
373
            _data[idx] = true;
111
373
            _size++;
112
373
        }
113
442
    }
_ZN5doris15BitSetContainerIsE6insertERKs
Line
Count
Source
107
731
    ALWAYS_INLINE void insert(const T& value) {
108
731
        auto idx = _to_index(value);
109
731
        if (!_data[idx]) {
110
285
            _data[idx] = true;
111
285
            _size++;
112
285
        }
113
731
    }
114
115
1.15k
    ALWAYS_INLINE bool find(const T& value) const { return _data[_to_index(value)]; }
_ZNK5doris15BitSetContainerIaE4findERKa
Line
Count
Source
115
670
    ALWAYS_INLINE bool find(const T& value) const { return _data[_to_index(value)]; }
_ZNK5doris15BitSetContainerIsE4findERKs
Line
Count
Source
115
483
    ALWAYS_INLINE bool find(const T& value) const { return _data[_to_index(value)]; }
116
117
37
    void clear() {
118
37
        _data.fill(false);
119
37
        _size = 0;
120
37
    }
_ZN5doris15BitSetContainerIaE5clearEv
Line
Count
Source
117
5
    void clear() {
118
5
        _data.fill(false);
119
5
        _size = 0;
120
5
    }
_ZN5doris15BitSetContainerIsE5clearEv
Line
Count
Source
117
32
    void clear() {
118
32
        _data.fill(false);
119
32
        _size = 0;
120
32
    }
121
122
2.14k
    size_t size() const { return _size; }
_ZNK5doris15BitSetContainerIaE4sizeEv
Line
Count
Source
122
1.39k
    size_t size() const { return _size; }
_ZNK5doris15BitSetContainerIsE4sizeEv
Line
Count
Source
122
744
    size_t size() const { return _size; }
123
124
2.36k
    Iterator begin() const { return Iterator(&_data, 0); }
_ZNK5doris15BitSetContainerIaE5beginEv
Line
Count
Source
124
1.54k
    Iterator begin() const { return Iterator(&_data, 0); }
_ZNK5doris15BitSetContainerIsE5beginEv
Line
Count
Source
124
814
    Iterator begin() const { return Iterator(&_data, 0); }
125
2.36k
    Iterator end() const { return Iterator(&_data, RANGE); }
_ZNK5doris15BitSetContainerIaE3endEv
Line
Count
Source
125
1.55k
    Iterator end() const { return Iterator(&_data, RANGE); }
_ZNK5doris15BitSetContainerIsE3endEv
Line
Count
Source
125
815
    Iterator end() const { return Iterator(&_data, RANGE); }
126
127
    template <typename ColumnData>
128
    void find_batch(const ColumnData& data, size_t rows, std::vector<bool>& results) const {
129
        results.resize(rows);
130
        for (size_t i = 0; i < rows; ++i) {
131
            results[i] = find(data[i]);
132
        }
133
    }
134
135
    template <typename ColumnData>
136
    void find_batch(const ColumnData& data, size_t rows, std::vector<uint8_t>& results) const {
137
        results.resize(rows);
138
        for (size_t i = 0; i < rows; ++i) {
139
            results[i] = find(data[i]) ? 1 : 0;
140
        }
141
    }
142
143
private:
144
2.32k
    ALWAYS_INLINE constexpr size_t _to_index(T value) const {
145
2.32k
        if constexpr (std::is_same_v<T, int8_t>) {
146
1.11k
            return static_cast<uint8_t>(value);
147
1.21k
        } else {
148
1.21k
            return static_cast<uint16_t>(value);
149
1.21k
        }
150
2.32k
    }
_ZNK5doris15BitSetContainerIaE9_to_indexEa
Line
Count
Source
144
1.11k
    ALWAYS_INLINE constexpr size_t _to_index(T value) const {
145
1.11k
        if constexpr (std::is_same_v<T, int8_t>) {
146
1.11k
            return static_cast<uint8_t>(value);
147
        } else {
148
            return static_cast<uint16_t>(value);
149
        }
150
1.11k
    }
_ZNK5doris15BitSetContainerIsE9_to_indexEs
Line
Count
Source
144
1.21k
    ALWAYS_INLINE constexpr size_t _to_index(T value) const {
145
        if constexpr (std::is_same_v<T, int8_t>) {
146
            return static_cast<uint8_t>(value);
147
1.21k
        } else {
148
1.21k
            return static_cast<uint16_t>(value);
149
1.21k
        }
150
1.21k
    }
151
152
    std::array<bool, RANGE> _data;
153
    size_t _size = 0;
154
};
155
156
} // namespace doris