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 |