Coverage Report

Created: 2026-10-23 00:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/format/format_common.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 <memory>
21
#include <typeindex>
22
23
#include "core/data_type/primitive_type.h"
24
#include "core/types.h"
25
#include "exec/common/int_exp.h"
26
27
namespace doris {
28
29
struct DecimalScaleParams {
30
    enum ScaleType {
31
        NOT_INIT,
32
        NO_SCALE,
33
        SCALE_UP,
34
        SCALE_DOWN,
35
    };
36
    ScaleType scale_type = ScaleType::NOT_INIT;
37
    int64_t scale_factor = 1;
38
39
    template <PrimitiveType DecimalPrimitiveType>
40
    static inline constexpr typename PrimitiveTypeTraits<DecimalPrimitiveType>::CppType::NativeType
41
7.65k
    get_scale_factor(int32_t n) {
42
7.65k
        if constexpr (DecimalPrimitiveType == TYPE_DECIMAL32) {
43
4.28k
            return common::exp10_i32(n);
44
4.28k
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL64) {
45
2.74k
            return common::exp10_i64(n);
46
2.74k
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMALV2) {
47
0
            return common::exp10_i128(n);
48
614
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL128I) {
49
614
            return common::exp10_i128(n);
50
614
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL256) {
51
4
            return common::exp10_i256(n);
52
        } else {
53
            static_assert(!sizeof(typename PrimitiveTypeTraits<DecimalPrimitiveType>::CppType),
54
                          "All types must be matched with if constexpr.");
55
        }
56
7.65k
    }
_ZN5doris18DecimalScaleParams16get_scale_factorILNS_13PrimitiveTypeE28EEENS_19PrimitiveTypeTraitsIXT_EE7CppType10NativeTypeEi
Line
Count
Source
41
4.28k
    get_scale_factor(int32_t n) {
42
4.28k
        if constexpr (DecimalPrimitiveType == TYPE_DECIMAL32) {
43
4.28k
            return common::exp10_i32(n);
44
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL64) {
45
            return common::exp10_i64(n);
46
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMALV2) {
47
            return common::exp10_i128(n);
48
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL128I) {
49
            return common::exp10_i128(n);
50
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL256) {
51
            return common::exp10_i256(n);
52
        } else {
53
            static_assert(!sizeof(typename PrimitiveTypeTraits<DecimalPrimitiveType>::CppType),
54
                          "All types must be matched with if constexpr.");
55
        }
56
4.28k
    }
_ZN5doris18DecimalScaleParams16get_scale_factorILNS_13PrimitiveTypeE29EEENS_19PrimitiveTypeTraitsIXT_EE7CppType10NativeTypeEi
Line
Count
Source
41
2.74k
    get_scale_factor(int32_t n) {
42
        if constexpr (DecimalPrimitiveType == TYPE_DECIMAL32) {
43
            return common::exp10_i32(n);
44
2.74k
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL64) {
45
2.74k
            return common::exp10_i64(n);
46
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMALV2) {
47
            return common::exp10_i128(n);
48
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL128I) {
49
            return common::exp10_i128(n);
50
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL256) {
51
            return common::exp10_i256(n);
52
        } else {
53
            static_assert(!sizeof(typename PrimitiveTypeTraits<DecimalPrimitiveType>::CppType),
54
                          "All types must be matched with if constexpr.");
55
        }
56
2.74k
    }
Unexecuted instantiation: _ZN5doris18DecimalScaleParams16get_scale_factorILNS_13PrimitiveTypeE20EEENS_19PrimitiveTypeTraitsIXT_EE7CppType10NativeTypeEi
_ZN5doris18DecimalScaleParams16get_scale_factorILNS_13PrimitiveTypeE30EEENS_19PrimitiveTypeTraitsIXT_EE7CppType10NativeTypeEi
Line
Count
Source
41
614
    get_scale_factor(int32_t n) {
42
        if constexpr (DecimalPrimitiveType == TYPE_DECIMAL32) {
43
            return common::exp10_i32(n);
44
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL64) {
45
            return common::exp10_i64(n);
46
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMALV2) {
47
            return common::exp10_i128(n);
48
614
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL128I) {
49
614
            return common::exp10_i128(n);
50
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL256) {
51
            return common::exp10_i256(n);
52
        } else {
53
            static_assert(!sizeof(typename PrimitiveTypeTraits<DecimalPrimitiveType>::CppType),
54
                          "All types must be matched with if constexpr.");
55
        }
56
614
    }
_ZN5doris18DecimalScaleParams16get_scale_factorILNS_13PrimitiveTypeE35EEENS_19PrimitiveTypeTraitsIXT_EE7CppType10NativeTypeEi
Line
Count
Source
41
4
    get_scale_factor(int32_t n) {
42
        if constexpr (DecimalPrimitiveType == TYPE_DECIMAL32) {
43
            return common::exp10_i32(n);
44
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL64) {
45
            return common::exp10_i64(n);
46
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMALV2) {
47
            return common::exp10_i128(n);
48
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL128I) {
49
            return common::exp10_i128(n);
50
4
        } else if constexpr (DecimalPrimitiveType == TYPE_DECIMAL256) {
51
4
            return common::exp10_i256(n);
52
        } else {
53
            static_assert(!sizeof(typename PrimitiveTypeTraits<DecimalPrimitiveType>::CppType),
54
                          "All types must be matched with if constexpr.");
55
        }
56
4
    }
57
};
58
59
/**
60
 * Key-Value Cache Helper.
61
 *
62
 * It store a object instance global. User can invoke get method by key and a
63
 * object creator callback. If there is a instance stored in cache, then it will
64
 * return a void pointer of it, otherwise, it will invoke creator callback, create
65
 * a new instance store global, and return it.
66
 *
67
 * The stored objects will be deleted when deconstructing, so user do not need to
68
 * delete the returned pointer.
69
 *
70
 * User can invoke erase method by key to delete data.
71
 *
72
 * @tparam KType is the key type
73
 */
74
template <typename KType>
75
class KVCache {
76
public:
77
104k
    KVCache() = default;
78
96
    ~KVCache() = default;
79
80
    template <class T>
81
    void erase(const KType& key) {
82
        std::shared_ptr<Entry> erased_entry;
83
        {
84
            std::lock_guard<std::mutex> lock(_lock);
85
            auto key_it = _entries.find(key);
86
            if (key_it == _entries.end()) {
87
                return;
88
            }
89
            auto type_it = key_it->second.find(typeid(T));
90
            if (type_it == key_it->second.end()) {
91
                return;
92
            }
93
            erased_entry = std::move(type_it->second);
94
            key_it->second.erase(type_it);
95
            if (key_it->second.empty()) {
96
                _entries.erase(key_it);
97
            }
98
        }
99
        // Destroy the cached value outside the shard lock.
100
    }
101
102
    template <class T>
103
0
    T* get(const KType& key, const std::function<T*()> create_func, bool* cache_hit = nullptr) {
104
0
        std::shared_ptr<Entry> entry = _get_or_create_entry<T>(key);
105
0
        std::lock_guard<std::mutex> entry_lock(entry->_lock);
106
0
        if (entry->_value != nullptr) {
107
0
            if (cache_hit != nullptr) {
108
0
                *cache_hit = true;
109
0
            }
110
0
            return static_cast<T*>(entry->_value);
111
0
        } else {
112
0
            if (cache_hit != nullptr) {
113
0
                *cache_hit = false;
114
0
            }
115
0
            T* rawPtr = create_func();
116
0
            if (rawPtr != nullptr) {
117
110
                entry->_delete_fn = [](void* obj) { delete static_cast<T*>(obj); };
_ZZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getIN7roaring12Roaring64MapEEEPT_RKS6_St8functionIFSC_vEEPbENKUlPvE_clESJ_
Line
Count
Source
117
4
                entry->_delete_fn = [](void* obj) { delete static_cast<T*>(obj); };
_ZZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getINS_6format5fluss20FlussUnionLakeReader15SuppressionKeysEEEPT_RKS6_St8functionIFSE_vEEPbENKUlPvE_clESL_
Line
Count
Source
117
17
                entry->_delete_fn = [](void* obj) { delete static_cast<T*>(obj); };
_ZZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getISt13unordered_mapIS6_St6vectorIlSaIlEESt4hashIS6_ESt8equal_toIS6_ESaISt4pairIKS6_SC_EEEEEPT_RSI_St8functionIFSN_vEEPbENKUlPvE_clEST_
Line
Count
Source
117
11
                entry->_delete_fn = [](void* obj) { delete static_cast<T*>(obj); };
_ZZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getINS_6format7iceberg18IcebergTableReader20EqualityDeleteFilterEEEPT_RKS6_St8functionIFSE_vEEPbENKUlPvE_clESL_
Line
Count
Source
117
78
                entry->_delete_fn = [](void* obj) { delete static_cast<T*>(obj); };
Unexecuted instantiation: _ZZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getIN5phmap22parallel_flat_hash_mapIS6_St10unique_ptrISt6vectorIlSaIlEESt14default_deleteISE_EESt4hashIS6_ESt8equal_toIvESaISt4pairIKS6_SH_EELm8ESt5mutexEEEEPT_RSN_St8functionIFST_vEEPbENKUlPvE_clESZ_
Unexecuted instantiation: _ZZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getISt6vectorIlSaIlEEEEPT_RKS6_St8functionIFSD_vEEPbENKUlPvE_clESK_
118
0
                entry->_value = rawPtr;
119
0
            }
120
0
            return rawPtr;
121
0
        }
122
0
    }
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getIN7roaring12Roaring64MapEEEPT_RKS6_St8functionIFSC_vEEPb
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getINS_6format5fluss20FlussUnionLakeReader15SuppressionKeysEEEPT_RKS6_St8functionIFSE_vEEPb
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getISt13unordered_mapIS6_St6vectorIlSaIlEESt4hashIS6_ESt8equal_toIS6_ESaISt4pairIKS6_SC_EEEEEPT_RSI_St8functionIFSN_vEEPb
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getINS_6format7iceberg18IcebergTableReader20EqualityDeleteFilterEEEPT_RKS6_St8functionIFSE_vEEPb
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getIN5phmap22parallel_flat_hash_mapIS6_St10unique_ptrISt6vectorIlSaIlEESt14default_deleteISE_EESt4hashIS6_ESt8equal_toIvESaISt4pairIKS6_SH_EELm8ESt5mutexEEEEPT_RSN_St8functionIFST_vEEPb
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3getISt6vectorIlSaIlEEEEPT_RKS6_St8functionIFSD_vEEPb
123
124
private:
125
    using DeleteFn = void (*)(void*);
126
127
    struct Entry {
128
0
        ~Entry() {
129
0
            if (_value != nullptr) {
130
0
                _delete_fn(_value);
131
0
            }
132
0
        }
133
134
        // The shard lock only protects the map. Factory calls hold this entry lock, so an
135
        // unrelated key can keep loading while another key is doing remote I/O.
136
        std::mutex _lock;
137
        void* _value = nullptr;
138
        DeleteFn _delete_fn = nullptr;
139
    };
140
141
    template <class T>
142
0
    std::shared_ptr<Entry> _get_or_create_entry(const KType& key) {
143
0
        std::lock_guard<std::mutex> lock(_lock);
144
0
        auto key_it = _entries.try_emplace(key).first;
145
0
        auto type_it = key_it->second.find(typeid(T));
146
0
        if (type_it != key_it->second.end()) {
147
0
            return type_it->second;
148
0
        }
149
0
        auto entry = std::make_shared<Entry>();
150
0
        key_it->second.emplace(typeid(T), entry);
151
0
        return entry;
152
0
    }
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE20_get_or_create_entryIN7roaring12Roaring64MapEEESt10shared_ptrINS7_5EntryEERKS6_
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE20_get_or_create_entryINS_6format5fluss20FlussUnionLakeReader15SuppressionKeysEEESt10shared_ptrINS7_5EntryEERKS6_
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE20_get_or_create_entryISt13unordered_mapIS6_St6vectorIlSaIlEESt4hashIS6_ESt8equal_toIS6_ESaISt4pairIKS6_SC_EEEEESt10shared_ptrINS7_5EntryEERSI_
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE20_get_or_create_entryINS_6format7iceberg18IcebergTableReader20EqualityDeleteFilterEEESt10shared_ptrINS7_5EntryEERKS6_
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE20_get_or_create_entryIN5phmap22parallel_flat_hash_mapIS6_St10unique_ptrISt6vectorIlSaIlEESt14default_deleteISE_EESt4hashIS6_ESt8equal_toIvESaISt4pairIKS6_SH_EELm8ESt5mutexEEEESt10shared_ptrINS7_5EntryEERSN_
Unexecuted instantiation: _ZN5doris7KVCacheINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE20_get_or_create_entryISt6vectorIlSaIlEEEESt10shared_ptrINS7_5EntryEERKS6_
153
154
    std::mutex _lock;
155
    std::unordered_map<KType, std::unordered_map<std::type_index, std::shared_ptr<Entry>>> _entries;
156
};
157
158
class ShardedKVCache {
159
public:
160
3.47k
    ShardedKVCache(uint32_t num_shards) : _num_shards(num_shards) {
161
3.47k
        _shards = new (std::nothrow) KVCache<std::string>*[_num_shards];
162
107k
        for (uint32_t i = 0; i < _num_shards; i++) {
163
104k
            _shards[i] = new KVCache<std::string>();
164
104k
        }
165
3.47k
    }
166
167
3.46k
    ~ShardedKVCache() {
168
107k
        for (uint32_t i = 0; i < _num_shards; i++) {
169
104k
            delete _shards[i];
170
104k
        }
171
3.46k
        delete[] _shards;
172
3.46k
    }
173
174
    template <class T>
175
    T* get(const std::string& key, const std::function<T*()> create_func,
176
156
           bool* cache_hit = nullptr) {
177
156
        return _shards[_get_idx(key)]->get(key, create_func, cache_hit);
178
156
    }
_ZN5doris14ShardedKVCache3getIN7roaring12Roaring64MapEEEPT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt8functionIFS5_vEEPb
Line
Count
Source
176
8
           bool* cache_hit = nullptr) {
177
8
        return _shards[_get_idx(key)]->get(key, create_func, cache_hit);
178
8
    }
_ZN5doris14ShardedKVCache3getINS_6format5fluss20FlussUnionLakeReader15SuppressionKeysEEEPT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt8functionIFS7_vEEPb
Line
Count
Source
176
36
           bool* cache_hit = nullptr) {
177
36
        return _shards[_get_idx(key)]->get(key, create_func, cache_hit);
178
36
    }
_ZN5doris14ShardedKVCache3getISt13unordered_mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIlSaIlEESt4hashIS8_ESt8equal_toIS8_ESaISt4pairIKS8_SB_EEEEEPT_RSH_St8functionIFSM_vEEPb
Line
Count
Source
176
14
           bool* cache_hit = nullptr) {
177
14
        return _shards[_get_idx(key)]->get(key, create_func, cache_hit);
178
14
    }
_ZN5doris14ShardedKVCache3getINS_6format7iceberg18IcebergTableReader20EqualityDeleteFilterEEEPT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt8functionIFS7_vEEPb
Line
Count
Source
176
96
           bool* cache_hit = nullptr) {
177
96
        return _shards[_get_idx(key)]->get(key, create_func, cache_hit);
178
96
    }
_ZN5doris14ShardedKVCache3getIN5phmap22parallel_flat_hash_mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10unique_ptrISt6vectorIlSaIlEESt14default_deleteISD_EESt4hashIS9_ESt8equal_toIvESaISt4pairIKS9_SG_EELm8ESt5mutexEEEEPT_RSM_St8functionIFSS_vEEPb
Line
Count
Source
176
2
           bool* cache_hit = nullptr) {
177
2
        return _shards[_get_idx(key)]->get(key, create_func, cache_hit);
178
2
    }
Unexecuted instantiation: _ZN5doris14ShardedKVCache3getISt6vectorIlSaIlEEEEPT_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt8functionIFS6_vEEPb
179
180
private:
181
156
    uint32_t _get_idx(const std::string& key) const {
182
156
        return (uint32_t)std::hash<std::string>()(key) % _num_shards;
183
156
    }
184
185
    uint32_t _num_shards;
186
    KVCache<std::string>** _shards = nullptr;
187
};
188
189
} // namespace doris