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 | 3.48k | : _data(data), _index(index) { |
60 | 3.48k | _find_next(); |
61 | 3.48k | } _ZN5doris15BitSetContainerIaE8IteratorC2EPKSt5arrayIbLm256EEm Line | Count | Source | 59 | 2.46k | : _data(data), _index(index) { | 60 | 2.46k | _find_next(); | 61 | 2.46k | } |
_ZN5doris15BitSetContainerIsE8IteratorC2EPKSt5arrayIbLm65536EEm Line | Count | Source | 59 | 1.02k | : _data(data), _index(index) { | 60 | 1.02k | _find_next(); | 61 | 1.02k | } |
|
62 | | |
63 | 3.89k | Iterator& operator++() { |
64 | 3.89k | ++_index; |
65 | 3.89k | _find_next(); |
66 | 3.89k | return *this; |
67 | 3.89k | } _ZN5doris15BitSetContainerIaE8IteratorppEv Line | Count | Source | 63 | 2.13k | Iterator& operator++() { | 64 | 2.13k | ++_index; | 65 | 2.13k | _find_next(); | 66 | 2.13k | return *this; | 67 | 2.13k | } |
_ZN5doris15BitSetContainerIsE8IteratorppEv Line | Count | Source | 63 | 1.75k | Iterator& operator++() { | 64 | 1.75k | ++_index; | 65 | 1.75k | _find_next(); | 66 | 1.75k | return *this; | 67 | 1.75k | } |
|
68 | | |
69 | | Iterator operator++(int) { |
70 | | Iterator ret_val = *this; |
71 | | ++(*this); |
72 | | return ret_val; |
73 | | } |
74 | | |
75 | 6.22k | bool operator==(Iterator other) const { return _index == other._index; }_ZNK5doris15BitSetContainerIaE8IteratoreqES2_ Line | Count | Source | 75 | 3.78k | bool operator==(Iterator other) const { return _index == other._index; } |
_ZNK5doris15BitSetContainerIsE8IteratoreqES2_ Line | Count | Source | 75 | 2.44k | bool operator==(Iterator other) const { return _index == other._index; } |
|
76 | 3.54k | bool operator!=(Iterator other) const { return !(*this == other); }_ZNK5doris15BitSetContainerIaE8IteratorneES2_ Line | Count | Source | 76 | 1.87k | bool operator!=(Iterator other) const { return !(*this == other); } |
_ZNK5doris15BitSetContainerIsE8IteratorneES2_ Line | Count | Source | 76 | 1.67k | bool operator!=(Iterator other) const { return !(*this == other); } |
|
77 | | |
78 | 1.26k | T operator*() const { return static_cast<T>(_index); }_ZNK5doris15BitSetContainerIaE8IteratordeEv Line | Count | Source | 78 | 541 | T operator*() const { return static_cast<T>(_index); } |
_ZNK5doris15BitSetContainerIsE8IteratordeEv Line | Count | Source | 78 | 721 | T operator*() const { return static_cast<T>(_index); } |
|
79 | | |
80 | 2.35k | T* operator->() const { |
81 | 2.35k | _cached_value = static_cast<T>(_index); |
82 | 2.35k | return &_cached_value; |
83 | 2.35k | } _ZNK5doris15BitSetContainerIaE8IteratorptEv Line | Count | Source | 80 | 1.61k | T* operator->() const { | 81 | 1.61k | _cached_value = static_cast<T>(_index); | 82 | 1.61k | return &_cached_value; | 83 | 1.61k | } |
_ZNK5doris15BitSetContainerIsE8IteratorptEv Line | Count | Source | 80 | 736 | T* operator->() const { | 81 | 736 | _cached_value = static_cast<T>(_index); | 82 | 736 | return &_cached_value; | 83 | 736 | } |
|
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 | 7.37k | void _find_next() { |
93 | 38.3M | while (_index < RANGE && !(*_data)[_index]) { |
94 | 38.3M | ++_index; |
95 | 38.3M | } |
96 | 7.37k | } _ZN5doris15BitSetContainerIaE8Iterator10_find_nextEv Line | Count | Source | 92 | 4.60k | void _find_next() { | 93 | 375k | while (_index < RANGE && !(*_data)[_index]) { | 94 | 371k | ++_index; | 95 | 371k | } | 96 | 4.60k | } |
_ZN5doris15BitSetContainerIsE8Iterator10_find_nextEv Line | Count | Source | 92 | 2.77k | void _find_next() { | 93 | 38.0M | while (_index < RANGE && !(*_data)[_index]) { | 94 | 38.0M | ++_index; | 95 | 38.0M | } | 96 | 2.77k | } |
|
97 | | |
98 | | const std::array<bool, RANGE>* _data; |
99 | | size_t _index; |
100 | | mutable T _cached_value = T(); |
101 | | }; |
102 | | |
103 | 1.90k | BitSetContainer() { _data.fill(false); }_ZN5doris15BitSetContainerIaEC2Ev Line | Count | Source | 103 | 1.15k | BitSetContainer() { _data.fill(false); } |
_ZN5doris15BitSetContainerIsEC2Ev Line | Count | Source | 103 | 755 | BitSetContainer() { _data.fill(false); } |
|
104 | | |
105 | | ~BitSetContainer() = default; |
106 | | |
107 | 1.13k | ALWAYS_INLINE void insert(const T& value) { |
108 | 1.13k | auto idx = _to_index(value); |
109 | 1.13k | if (!_data[idx]) { |
110 | 1.02k | _data[idx] = true; |
111 | 1.02k | _size++; |
112 | 1.02k | } |
113 | 1.13k | } _ZN5doris15BitSetContainerIaE6insertERKa Line | Count | Source | 107 | 436 | ALWAYS_INLINE void insert(const T& value) { | 108 | 436 | auto idx = _to_index(value); | 109 | 436 | if (!_data[idx]) { | 110 | 436 | _data[idx] = true; | 111 | 436 | _size++; | 112 | 436 | } | 113 | 436 | } |
_ZN5doris15BitSetContainerIsE6insertERKs Line | Count | Source | 107 | 697 | ALWAYS_INLINE void insert(const T& value) { | 108 | 697 | auto idx = _to_index(value); | 109 | 697 | if (!_data[idx]) { | 110 | 588 | _data[idx] = true; | 111 | 588 | _size++; | 112 | 588 | } | 113 | 697 | } |
|
114 | | |
115 | 1.43k | ALWAYS_INLINE bool find(const T& value) const { return _data[_to_index(value)]; }_ZNK5doris15BitSetContainerIaE4findERKa Line | Count | Source | 115 | 952 | ALWAYS_INLINE bool find(const T& value) const { return _data[_to_index(value)]; } |
_ZNK5doris15BitSetContainerIsE4findERKs Line | Count | Source | 115 | 487 | ALWAYS_INLINE bool find(const T& value) const { return _data[_to_index(value)]; } |
|
116 | | |
117 | 5 | void clear() { |
118 | 5 | _data.fill(false); |
119 | 5 | _size = 0; |
120 | 5 | } _ZN5doris15BitSetContainerIaE5clearEv Line | Count | Source | 117 | 1 | void clear() { | 118 | 1 | _data.fill(false); | 119 | 1 | _size = 0; | 120 | 1 | } |
_ZN5doris15BitSetContainerIsE5clearEv Line | Count | Source | 117 | 4 | void clear() { | 118 | 4 | _data.fill(false); | 119 | 4 | _size = 0; | 120 | 4 | } |
|
121 | | |
122 | 2.14k | size_t size() const { return _size; }_ZNK5doris15BitSetContainerIaE4sizeEv Line | Count | Source | 122 | 1.50k | size_t size() const { return _size; } |
_ZNK5doris15BitSetContainerIsE4sizeEv Line | Count | Source | 122 | 638 | size_t size() const { return _size; } |
|
123 | | |
124 | 1.74k | Iterator begin() const { return Iterator(&_data, 0); }_ZNK5doris15BitSetContainerIaE5beginEv Line | Count | Source | 124 | 1.22k | Iterator begin() const { return Iterator(&_data, 0); } |
_ZNK5doris15BitSetContainerIsE5beginEv Line | Count | Source | 124 | 512 | Iterator begin() const { return Iterator(&_data, 0); } |
|
125 | 1.75k | Iterator end() const { return Iterator(&_data, RANGE); }_ZNK5doris15BitSetContainerIaE3endEv Line | Count | Source | 125 | 1.24k | Iterator end() const { return Iterator(&_data, RANGE); } |
_ZNK5doris15BitSetContainerIsE3endEv Line | Count | Source | 125 | 514 | 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.57k | ALWAYS_INLINE constexpr size_t _to_index(T value) const { |
145 | 2.57k | if constexpr (std::is_same_v<T, int8_t>) { |
146 | 1.38k | return static_cast<uint8_t>(value); |
147 | 1.38k | } else { |
148 | 1.18k | return static_cast<uint16_t>(value); |
149 | 1.18k | } |
150 | 2.57k | } _ZNK5doris15BitSetContainerIaE9_to_indexEa Line | Count | Source | 144 | 1.38k | ALWAYS_INLINE constexpr size_t _to_index(T value) const { | 145 | 1.38k | if constexpr (std::is_same_v<T, int8_t>) { | 146 | 1.38k | return static_cast<uint8_t>(value); | 147 | | } else { | 148 | | return static_cast<uint16_t>(value); | 149 | | } | 150 | 1.38k | } |
_ZNK5doris15BitSetContainerIsE9_to_indexEs Line | Count | Source | 144 | 1.18k | 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.18k | } else { | 148 | 1.18k | return static_cast<uint16_t>(value); | 149 | 1.18k | } | 150 | 1.18k | } |
|
151 | | |
152 | | std::array<bool, RANGE> _data; |
153 | | size_t _size = 0; |
154 | | }; |
155 | | |
156 | | } // namespace doris |