Coverage Report

Created: 2024-11-22 20:18

/root/doris/be/src/util/bitmap_intersect.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
#pragma once
18
#include <parallel_hashmap/phmap.h>
19
20
#include "util/bitmap_value.h"
21
#include "vec/common/string_ref.h"
22
23
namespace doris {
24
25
namespace detail {
26
class Helper {
27
public:
28
    static const int DATETIME_PACKED_TIME_BYTE_SIZE = 8;
29
    static const int DATETIME_TYPE_BYTE_SIZE = 4;
30
    static const int DECIMAL_BYTE_SIZE = 16;
31
32
    // serialize_size start
33
    template <typename T>
34
0
    static int32_t serialize_size(const T& v) {
35
0
        return sizeof(T);
36
0
    }
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIhEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIaEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIsEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIiEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIlEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeInEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIfEEiRKT_
Unexecuted instantiation: _ZN5doris6detail6Helper14serialize_sizeIdEEiRKT_
37
38
    // write_to start
39
    template <typename T>
40
0
    static char* write_to(const T& v, char* dest) {
41
0
        size_t type_size = sizeof(T);
42
0
        memcpy(dest, &v, type_size);
43
0
        dest += type_size;
44
0
        return dest;
45
0
    }
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIhEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIaEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIsEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIiEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIlEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toInEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIfEEPcRKT_S3_
Unexecuted instantiation: _ZN5doris6detail6Helper8write_toIdEEPcRKT_S3_
46
47
    // read_from start
48
    template <typename T>
49
0
    static void read_from(const char** src, T* result) {
50
0
        size_t type_size = sizeof(T);
51
0
        memcpy(result, *src, type_size);
52
0
        *src += type_size;
53
0
    }
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIhEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIaEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIsEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIiEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIlEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromInEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIfEEvPPKcPT_
Unexecuted instantiation: _ZN5doris6detail6Helper9read_fromIdEEvPPKcPT_
54
};
55
56
template <>
57
0
char* Helper::write_to<VecDateTimeValue>(const VecDateTimeValue& v, char* dest) {
58
0
    *(int64_t*)dest = v.to_int64_datetime_packed();
59
0
    dest += DATETIME_PACKED_TIME_BYTE_SIZE;
60
0
    *(int*)dest = v.type();
61
0
    dest += DATETIME_TYPE_BYTE_SIZE;
62
0
    return dest;
63
0
}
64
65
template <>
66
0
char* Helper::write_to<DecimalV2Value>(const DecimalV2Value& v, char* dest) {
67
0
    __int128 value = v.value();
68
0
    memcpy(dest, &value, DECIMAL_BYTE_SIZE);
69
0
    dest += DECIMAL_BYTE_SIZE;
70
0
    return dest;
71
0
}
72
73
template <>
74
0
char* Helper::write_to<StringRef>(const StringRef& v, char* dest) {
75
0
    *(int32_t*)dest = v.size;
76
0
    dest += 4;
77
0
    memcpy(dest, v.data, v.size);
78
0
    dest += v.size;
79
0
    return dest;
80
0
}
81
82
template <>
83
0
char* Helper::write_to<std::string>(const std::string& v, char* dest) {
84
0
    *(uint32_t*)dest = v.size();
85
0
    dest += 4;
86
0
    memcpy(dest, v.c_str(), v.size());
87
0
    dest += v.size();
88
0
    return dest;
89
0
}
90
// write_to end
91
92
template <>
93
0
int32_t Helper::serialize_size<VecDateTimeValue>(const VecDateTimeValue& v) {
94
0
    return Helper::DATETIME_PACKED_TIME_BYTE_SIZE + Helper::DATETIME_TYPE_BYTE_SIZE;
95
0
}
96
97
template <>
98
0
int32_t Helper::serialize_size<DecimalV2Value>(const DecimalV2Value& v) {
99
0
    return Helper::DECIMAL_BYTE_SIZE;
100
0
}
101
102
template <>
103
0
int32_t Helper::serialize_size<StringRef>(const StringRef& v) {
104
0
    return v.size + 4;
105
0
}
106
107
template <>
108
0
int32_t Helper::serialize_size<std::string>(const std::string& v) {
109
0
    return v.size() + 4;
110
0
}
111
// serialize_size end
112
113
template <>
114
0
void Helper::read_from<VecDateTimeValue>(const char** src, VecDateTimeValue* result) {
115
0
    result->from_packed_time(*(int64_t*)(*src));
116
0
    *src += DATETIME_PACKED_TIME_BYTE_SIZE;
117
0
    if (*(int*)(*src) == TIME_DATE) {
118
0
        result->cast_to_date();
119
0
    }
120
0
    *src += DATETIME_TYPE_BYTE_SIZE;
121
0
}
122
123
template <>
124
0
void Helper::read_from<DecimalV2Value>(const char** src, DecimalV2Value* result) {
125
0
    __int128 v = 0;
126
0
    memcpy(&v, *src, DECIMAL_BYTE_SIZE);
127
0
    *src += DECIMAL_BYTE_SIZE;
128
0
    *result = DecimalV2Value(v);
129
0
}
130
131
template <>
132
0
void Helper::read_from<StringRef>(const char** src, StringRef* result) {
133
0
    int32_t length = *(int32_t*)(*src);
134
0
    *src += 4;
135
0
    *result = StringRef((char*)*src, length);
136
0
    *src += length;
137
0
}
138
139
template <>
140
0
void Helper::read_from<std::string>(const char** src, std::string* result) {
141
0
    int32_t length = *(int32_t*)(*src);
142
0
    *src += 4;
143
0
    *result = std::string((char*)*src, length);
144
0
    *src += length;
145
0
}
146
// read_from end
147
} // namespace detail
148
149
// Calculate the intersection of two or more bitmaps
150
// Usage: intersect_count(bitmap_column_to_count, filter_column, filter_values ...)
151
// Example: intersect_count(user_id, event, 'A', 'B', 'C'), meaning find the intersect count of user_id in all A/B/C 3 bitmaps
152
// Todo(kks) Use Array type instead of variable arguments
153
template <typename T>
154
struct BitmapIntersect {
155
public:
156
0
    BitmapIntersect() = default;
Unexecuted instantiation: _ZN5doris15BitmapIntersectINS_9StringRefEEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectInEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdEC2Ev
Unexecuted instantiation: _ZN5doris15BitmapIntersectINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2Ev
157
158
    explicit BitmapIntersect(const char* src) { deserialize(src); }
159
160
0
    void add_key(const T key) {
161
0
        BitmapValue empty_bitmap;
162
0
        _bitmaps[key] = empty_bitmap;
163
0
    }
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhE7add_keyEh
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaE7add_keyEa
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsE7add_keyEs
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiE7add_keyEi
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlE7add_keyEl
Unexecuted instantiation: _ZN5doris15BitmapIntersectInE7add_keyEn
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfE7add_keyEf
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdE7add_keyEd
Unexecuted instantiation: _ZN5doris15BitmapIntersectINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE7add_keyES6_
164
165
0
    void update(const T& key, const BitmapValue& bitmap) {
166
0
        if (_bitmaps.find(key) != _bitmaps.end()) {
167
0
            _bitmaps[key] |= bitmap;
168
0
        }
169
0
    }
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhE6updateERKhRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaE6updateERKaRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsE6updateERKsRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiE6updateERKiRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlE6updateERKlRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectInE6updateERKnRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfE6updateERKfRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdE6updateERKdRKNS_11BitmapValueE
Unexecuted instantiation: _ZN5doris15BitmapIntersectINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE6updateERKS6_RKNS_11BitmapValueE
170
171
0
    void merge(const BitmapIntersect& other) {
172
0
        for (auto& kv : other._bitmaps) {
173
0
            if (_bitmaps.find(kv.first) != _bitmaps.end()) {
174
0
                _bitmaps[kv.first] |= kv.second;
175
0
            } else {
176
0
                _bitmaps[kv.first] = kv.second;
177
0
            }
178
0
        }
179
0
    }
Unexecuted instantiation: _ZN5doris15BitmapIntersectINS_9StringRefEE5mergeERKS2_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectInE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfE5mergeERKS1_
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdE5mergeERKS1_
180
181
    // intersection
182
0
    BitmapValue intersect() const {
183
0
        BitmapValue result;
184
0
        if (_bitmaps.empty()) {
185
0
            return result;
186
0
        }
187
0
        auto it = _bitmaps.begin();
188
0
        result |= it->second;
189
0
        it++;
190
0
        for (; it != _bitmaps.end(); it++) {
191
0
            result &= it->second;
192
0
        }
193
0
        return result;
194
0
    }
Unexecuted instantiation: _ZNK5doris15BitmapIntersectINS_9StringRefEE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIhE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIaE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIsE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIiE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIlE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectInE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIfE9intersectEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIdE9intersectEv
195
196
    // calculate the intersection for _bitmaps's bitmap values
197
0
    int64_t intersect_count() const {
198
0
        if (_bitmaps.empty()) {
199
0
            return 0;
200
0
        }
201
0
        return intersect().cardinality();
202
0
    }
Unexecuted instantiation: _ZNK5doris15BitmapIntersectINS_9StringRefEE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIhE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIaE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIsE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIiE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIlE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectInE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIfE15intersect_countEv
Unexecuted instantiation: _ZNK5doris15BitmapIntersectIdE15intersect_countEv
203
204
    // the serialize size
205
0
    size_t size() {
206
0
        size_t size = 4;
207
0
        for (auto& kv : _bitmaps) {
208
0
            size += detail::Helper::serialize_size(kv.first);
209
0
            size += kv.second.getSizeInBytes();
210
0
        }
211
0
        return size;
212
0
    }
Unexecuted instantiation: _ZN5doris15BitmapIntersectINS_9StringRefEE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectInE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfE4sizeEv
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdE4sizeEv
213
214
    //must call size() first
215
0
    void serialize(char* dest) {
216
0
        char* writer = dest;
217
0
        *(int32_t*)writer = _bitmaps.size();
218
0
        writer += 4;
219
0
        for (auto& kv : _bitmaps) {
220
0
            writer = detail::Helper::write_to(kv.first, writer);
221
0
            kv.second.write_to(writer);
222
0
            writer += kv.second.getSizeInBytes();
223
0
        }
224
0
    }
Unexecuted instantiation: _ZN5doris15BitmapIntersectINS_9StringRefEE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectInE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfE9serializeEPc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdE9serializeEPc
225
226
0
    void deserialize(const char* src) {
227
0
        const char* reader = src;
228
0
        int32_t bitmaps_size = *(int32_t*)reader;
229
0
        reader += 4;
230
0
        for (int32_t i = 0; i < bitmaps_size; i++) {
231
0
            T key;
232
0
            detail::Helper::read_from(&reader, &key);
233
0
            BitmapValue bitmap(reader);
234
0
            reader += bitmap.getSizeInBytes();
235
0
            _bitmaps[key] = bitmap;
236
0
        }
237
0
    }
Unexecuted instantiation: _ZN5doris15BitmapIntersectINS_9StringRefEE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIhE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIaE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIsE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIiE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIlE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectInE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIfE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectIdE11deserializeEPKc
Unexecuted instantiation: _ZN5doris15BitmapIntersectINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE11deserializeEPKc
238
239
protected:
240
    std::map<T, BitmapValue> _bitmaps;
241
};
242
243
template <>
244
struct BitmapIntersect<std::string_view> {
245
public:
246
0
    BitmapIntersect() = default;
247
248
0
    explicit BitmapIntersect(const char* src) { deserialize(src); }
249
250
0
    void add_key(const std::string_view key) {
251
0
        BitmapValue empty_bitmap;
252
0
        _bitmaps[key] = empty_bitmap;
253
0
    }
254
255
0
    void update(const std::string_view& key, const BitmapValue& bitmap) {
256
0
        if (_bitmaps.find(key) != _bitmaps.end()) {
257
0
            _bitmaps[key] |= bitmap;
258
0
        }
259
0
    }
260
261
0
    void merge(const BitmapIntersect& other) {
262
0
        for (auto& kv : other._bitmaps) {
263
0
            if (_bitmaps.find(kv.first) != _bitmaps.end()) {
264
0
                _bitmaps[kv.first] |= kv.second;
265
0
            } else {
266
0
                _bitmaps[kv.first] = kv.second;
267
0
            }
268
0
        }
269
0
    }
270
271
    // intersection
272
0
    BitmapValue intersect() const {
273
0
        BitmapValue result;
274
0
        auto it = _bitmaps.begin();
275
0
        result |= it->second;
276
0
        it++;
277
0
        for (; it != _bitmaps.end(); it++) {
278
0
            result &= it->second;
279
0
        }
280
0
        return result;
281
0
    }
282
283
    // calculate the intersection for _bitmaps's bitmap values
284
0
    int64_t intersect_count() const {
285
0
        if (_bitmaps.empty()) {
286
0
            return 0;
287
0
        }
288
0
        return intersect().cardinality();
289
0
    }
290
291
    // the serialize size
292
0
    size_t size() {
293
0
        size_t size = 4;
294
0
        for (auto& kv : _bitmaps) {
295
0
            size += detail::Helper::serialize_size(kv.first);
296
0
            size += kv.second.getSizeInBytes();
297
0
        }
298
0
        return size;
299
0
    }
300
301
    //must call size() first
302
0
    void serialize(char* dest) {
303
0
        char* writer = dest;
304
0
        *(int32_t*)writer = _bitmaps.size();
305
0
        writer += 4;
306
0
        for (auto& kv : _bitmaps) {
307
0
            writer = detail::Helper::write_to(kv.first, writer);
308
0
            kv.second.write_to(writer);
309
0
            writer += kv.second.getSizeInBytes();
310
0
        }
311
0
    }
312
313
0
    void deserialize(const char* src) {
314
0
        const char* reader = src;
315
0
        int32_t bitmaps_size = *(int32_t*)reader;
316
0
        reader += 4;
317
0
        for (int32_t i = 0; i < bitmaps_size; i++) {
318
0
            std::string key;
319
0
            detail::Helper::read_from(&reader, &key);
320
0
            BitmapValue bitmap(reader);
321
0
            reader += bitmap.getSizeInBytes();
322
0
            _bitmaps[key] = bitmap;
323
0
        }
324
0
    }
325
326
protected:
327
    phmap::flat_hash_map<std::string, BitmapValue> _bitmaps;
328
};
329
330
} // namespace doris