be/src/exec/common/hash_table/hash.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 | | // This file is copied from |
18 | | // https://github.com/ClickHouse/ClickHouse/blob/master/src/Common/HashTable/Hash.h |
19 | | // and modified by Doris |
20 | | |
21 | | #pragma once |
22 | | |
23 | | #include <type_traits> |
24 | | |
25 | | #include "core/extended_types.h" |
26 | | #include "core/string_ref.h" |
27 | | #include "core/types.h" |
28 | | #include "core/uint128.h" |
29 | | #include "core/value/timestamp_ns_value.h" |
30 | | #include "parallel_hashmap/phmap_utils.h" |
31 | | |
32 | | // Here is an empirical value. |
33 | | static constexpr size_t HASH_MAP_PREFETCH_DIST = 16; |
34 | | |
35 | | /** Hash functions that are better than the trivial function std::hash. |
36 | | * |
37 | | * Example: when we do aggregation by the visitor ID, the performance increase is more than 5 times. |
38 | | * This is because of following reasons: |
39 | | * - in Yandex, visitor identifier is an integer that has timestamp with seconds resolution in lower bits; |
40 | | * - in typical implementation of standard library, hash function for integers is trivial and just use lower bits; |
41 | | * - traffic is non-uniformly distributed across a day; |
42 | | * - we are using open-addressing linear probing hash tables that are most critical to hash function quality, |
43 | | * and trivial hash function gives disastrous results. |
44 | | */ |
45 | | |
46 | | /** Taken from MurmurHash. This is Murmur finalizer. |
47 | | * Faster than int_hash32 when inserting into the hash table UInt64 -> UInt64, where the key is the visitor ID. |
48 | | */ |
49 | 23.0k | inline doris::UInt64 int_hash64(doris::UInt64 x) { |
50 | 23.0k | x ^= x >> 33; |
51 | 23.0k | x *= 0xff51afd7ed558ccdULL; |
52 | 23.0k | x ^= x >> 33; |
53 | 23.0k | x *= 0xc4ceb9fe1a85ec53ULL; |
54 | 23.0k | x ^= x >> 33; |
55 | | |
56 | 23.0k | return x; |
57 | 23.0k | } |
58 | | |
59 | | /** CRC32C is not very high-quality as a hash function, |
60 | | * according to avalanche and bit independence tests (see SMHasher software), as well as a small number of bits, |
61 | | * but can behave well when used in hash tables, |
62 | | * due to high speed (latency 3 + 1 clock cycle, throughput 1 clock cycle). |
63 | | * Works only with SSE 4.2 support. |
64 | | */ |
65 | | #include "util/sse_util.hpp" |
66 | | |
67 | 36.1M | inline doris::UInt64 int_hash_crc32(doris::UInt64 x) { |
68 | 36.1M | #if defined(__SSE4_2__) || (defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)) |
69 | 36.1M | return _mm_crc32_u64(-1ULL, x); |
70 | | #else |
71 | | /// On other platforms we do not have CRC32. NOTE This can be confusing. |
72 | | return int_hash64(x); |
73 | | #endif |
74 | 36.1M | } |
75 | | |
76 | | template <typename T> |
77 | 19.9k | inline size_t default_hash64(T key) { |
78 | 19.9k | union { |
79 | 19.9k | T in; |
80 | 19.9k | doris::UInt64 out; |
81 | 19.9k | } u; |
82 | 19.9k | u.out = 0; |
83 | 19.9k | u.in = key; |
84 | 19.9k | return int_hash64(u.out); |
85 | 19.9k | } Line | Count | Source | 77 | 112 | inline size_t default_hash64(T key) { | 78 | 112 | union { | 79 | 112 | T in; | 80 | 112 | doris::UInt64 out; | 81 | 112 | } u; | 82 | 112 | u.out = 0; | 83 | 112 | u.in = key; | 84 | 112 | return int_hash64(u.out); | 85 | 112 | } |
Line | Count | Source | 77 | 1.43k | inline size_t default_hash64(T key) { | 78 | 1.43k | union { | 79 | 1.43k | T in; | 80 | 1.43k | doris::UInt64 out; | 81 | 1.43k | } u; | 82 | 1.43k | u.out = 0; | 83 | 1.43k | u.in = key; | 84 | 1.43k | return int_hash64(u.out); | 85 | 1.43k | } |
Line | Count | Source | 77 | 2.14k | inline size_t default_hash64(T key) { | 78 | 2.14k | union { | 79 | 2.14k | T in; | 80 | 2.14k | doris::UInt64 out; | 81 | 2.14k | } u; | 82 | 2.14k | u.out = 0; | 83 | 2.14k | u.in = key; | 84 | 2.14k | return int_hash64(u.out); | 85 | 2.14k | } |
Line | Count | Source | 77 | 4.09k | inline size_t default_hash64(T key) { | 78 | 4.09k | union { | 79 | 4.09k | T in; | 80 | 4.09k | doris::UInt64 out; | 81 | 4.09k | } u; | 82 | 4.09k | u.out = 0; | 83 | 4.09k | u.in = key; | 84 | 4.09k | return int_hash64(u.out); | 85 | 4.09k | } |
Line | Count | Source | 77 | 3.05k | inline size_t default_hash64(T key) { | 78 | 3.05k | union { | 79 | 3.05k | T in; | 80 | 3.05k | doris::UInt64 out; | 81 | 3.05k | } u; | 82 | 3.05k | u.out = 0; | 83 | 3.05k | u.in = key; | 84 | 3.05k | return int_hash64(u.out); | 85 | 3.05k | } |
Line | Count | Source | 77 | 4.68k | inline size_t default_hash64(T key) { | 78 | 4.68k | union { | 79 | 4.68k | T in; | 80 | 4.68k | doris::UInt64 out; | 81 | 4.68k | } u; | 82 | 4.68k | u.out = 0; | 83 | 4.68k | u.in = key; | 84 | 4.68k | return int_hash64(u.out); | 85 | 4.68k | } |
Line | Count | Source | 77 | 1.18k | inline size_t default_hash64(T key) { | 78 | 1.18k | union { | 79 | 1.18k | T in; | 80 | 1.18k | doris::UInt64 out; | 81 | 1.18k | } u; | 82 | 1.18k | u.out = 0; | 83 | 1.18k | u.in = key; | 84 | 1.18k | return int_hash64(u.out); | 85 | 1.18k | } |
Line | Count | Source | 77 | 1.52k | inline size_t default_hash64(T key) { | 78 | 1.52k | union { | 79 | 1.52k | T in; | 80 | 1.52k | doris::UInt64 out; | 81 | 1.52k | } u; | 82 | 1.52k | u.out = 0; | 83 | 1.52k | u.in = key; | 84 | 1.52k | return int_hash64(u.out); | 85 | 1.52k | } |
Line | Count | Source | 77 | 1.72k | inline size_t default_hash64(T key) { | 78 | 1.72k | union { | 79 | 1.72k | T in; | 80 | 1.72k | doris::UInt64 out; | 81 | 1.72k | } u; | 82 | 1.72k | u.out = 0; | 83 | 1.72k | u.in = key; | 84 | 1.72k | return int_hash64(u.out); | 85 | 1.72k | } |
|
86 | | |
87 | | template <typename T, typename Enable = void> |
88 | | struct DefaultHash; |
89 | | |
90 | | template <typename T> |
91 | | requires std::is_arithmetic_v<T> |
92 | | struct DefaultHash<T> { |
93 | 19.9k | size_t operator()(T key) const { return default_hash64<T>(key); }_ZNK11DefaultHashIhvEclEh Line | Count | Source | 93 | 112 | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIavEclEa Line | Count | Source | 93 | 1.43k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIsvEclEs Line | Count | Source | 93 | 2.14k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIivEclEi Line | Count | Source | 93 | 4.09k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIlvEclEl Line | Count | Source | 93 | 3.05k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashInvEclEn Line | Count | Source | 93 | 4.68k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIfvEclEf Line | Count | Source | 93 | 1.18k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIdvEclEd Line | Count | Source | 93 | 1.52k | size_t operator()(T key) const { return default_hash64<T>(key); } |
_ZNK11DefaultHashIjvEclEj Line | Count | Source | 93 | 1.72k | size_t operator()(T key) const { return default_hash64<T>(key); } |
|
94 | | }; |
95 | | |
96 | | template <> |
97 | | struct DefaultHash<unsigned __int128> { |
98 | 1.66M | size_t operator()(unsigned __int128 key) const { return doris::UInt128HashCRC32()(key); } |
99 | | }; |
100 | | |
101 | | template <> |
102 | | struct DefaultHash<doris::VecDateTimeValue> { |
103 | 0 | size_t operator()(doris::VecDateTimeValue key) const { return int_hash64(*(int64_t*)&key); } |
104 | | }; |
105 | | |
106 | | template <> |
107 | | struct DefaultHash<doris::DateV2Value<doris::DateTimeV2ValueType>> { |
108 | 817 | size_t operator()(doris::DateV2Value<doris::DateTimeV2ValueType> key) const { |
109 | 817 | return int_hash64(key.to_date_int_val()); |
110 | 817 | } |
111 | | }; |
112 | | |
113 | | template <> |
114 | | struct DefaultHash<doris::DateV2Value<doris::DateV2ValueType>> { |
115 | 1.91k | size_t operator()(doris::DateV2Value<doris::DateV2ValueType> key) const { |
116 | 1.91k | return int_hash64(key.to_date_int_val()); |
117 | 1.91k | } |
118 | | }; |
119 | | |
120 | | template <> |
121 | | struct DefaultHash<doris::TimeStampNsValue> { |
122 | 304 | size_t operator()(doris::TimeStampNsValue key) const { return int_hash64(key.epoch_nanos()); } |
123 | | }; |
124 | | |
125 | | template <> |
126 | | struct DefaultHash<doris::TimestampTzValue> { |
127 | 0 | size_t operator()(doris::TimestampTzValue key) const { |
128 | 0 | return int_hash64(key.to_date_int_val()); |
129 | 0 | } |
130 | | }; |
131 | | |
132 | | template <> |
133 | | struct DefaultHash<doris::StringRef> : public doris::StringRefHash {}; |
134 | | |
135 | | template <> |
136 | | struct DefaultHash<wide::Int256> : public std::hash<wide::Int256> {}; |
137 | | |
138 | | template <typename T> |
139 | | struct HashCRC32; |
140 | | |
141 | | template <typename T> |
142 | 36.1M | inline size_t hash_crc32(T key) { |
143 | 36.1M | union { |
144 | 36.1M | T in; |
145 | 36.1M | doris::UInt64 out; |
146 | 36.1M | } u; |
147 | 36.1M | u.out = 0; |
148 | 36.1M | u.in = key; |
149 | 36.1M | return int_hash_crc32(u.out); |
150 | 36.1M | } Line | Count | Source | 142 | 202k | inline size_t hash_crc32(T key) { | 143 | 202k | union { | 144 | 202k | T in; | 145 | 202k | doris::UInt64 out; | 146 | 202k | } u; | 147 | 202k | u.out = 0; | 148 | 202k | u.in = key; | 149 | 202k | return int_hash_crc32(u.out); | 150 | 202k | } |
Line | Count | Source | 142 | 17.3M | inline size_t hash_crc32(T key) { | 143 | 17.3M | union { | 144 | 17.3M | T in; | 145 | 17.3M | doris::UInt64 out; | 146 | 17.3M | } u; | 147 | 17.3M | u.out = 0; | 148 | 17.3M | u.in = key; | 149 | 17.3M | return int_hash_crc32(u.out); | 150 | 17.3M | } |
Line | Count | Source | 142 | 17.9M | inline size_t hash_crc32(T key) { | 143 | 17.9M | union { | 144 | 17.9M | T in; | 145 | 17.9M | doris::UInt64 out; | 146 | 17.9M | } u; | 147 | 17.9M | u.out = 0; | 148 | 17.9M | u.in = key; | 149 | 17.9M | return int_hash_crc32(u.out); | 150 | 17.9M | } |
Line | Count | Source | 142 | 474k | inline size_t hash_crc32(T key) { | 143 | 474k | union { | 144 | 474k | T in; | 145 | 474k | doris::UInt64 out; | 146 | 474k | } u; | 147 | 474k | u.out = 0; | 148 | 474k | u.in = key; | 149 | 474k | return int_hash_crc32(u.out); | 150 | 474k | } |
Line | Count | Source | 142 | 21.8k | inline size_t hash_crc32(T key) { | 143 | 21.8k | union { | 144 | 21.8k | T in; | 145 | 21.8k | doris::UInt64 out; | 146 | 21.8k | } u; | 147 | 21.8k | u.out = 0; | 148 | 21.8k | u.in = key; | 149 | 21.8k | return int_hash_crc32(u.out); | 150 | 21.8k | } |
Line | Count | Source | 142 | 8.91k | inline size_t hash_crc32(T key) { | 143 | 8.91k | union { | 144 | 8.91k | T in; | 145 | 8.91k | doris::UInt64 out; | 146 | 8.91k | } u; | 147 | 8.91k | u.out = 0; | 148 | 8.91k | u.in = key; | 149 | 8.91k | return int_hash_crc32(u.out); | 150 | 8.91k | } |
Line | Count | Source | 142 | 8.50k | inline size_t hash_crc32(T key) { | 143 | 8.50k | union { | 144 | 8.50k | T in; | 145 | 8.50k | doris::UInt64 out; | 146 | 8.50k | } u; | 147 | 8.50k | u.out = 0; | 148 | 8.50k | u.in = key; | 149 | 8.50k | return int_hash_crc32(u.out); | 150 | 8.50k | } |
Line | Count | Source | 142 | 180k | inline size_t hash_crc32(T key) { | 143 | 180k | union { | 144 | 180k | T in; | 145 | 180k | doris::UInt64 out; | 146 | 180k | } u; | 147 | 180k | u.out = 0; | 148 | 180k | u.in = key; | 149 | 180k | return int_hash_crc32(u.out); | 150 | 180k | } |
Unexecuted instantiation: _Z10hash_crc32IfEmT_ Line | Count | Source | 142 | 13 | inline size_t hash_crc32(T key) { | 143 | 13 | union { | 144 | 13 | T in; | 145 | 13 | doris::UInt64 out; | 146 | 13 | } u; | 147 | 13 | u.out = 0; | 148 | 13 | u.in = key; | 149 | 13 | return int_hash_crc32(u.out); | 150 | 13 | } |
|
151 | | |
152 | | template <> |
153 | 4.04M | inline size_t hash_crc32(doris::UInt128 u) { |
154 | 4.04M | return doris::UInt128HashCRC32()(u); |
155 | 4.04M | } |
156 | | |
157 | | template <> |
158 | 43.2k | inline size_t hash_crc32(unsigned __int128 u) { |
159 | 43.2k | return doris::UInt128HashCRC32()(u); |
160 | 43.2k | } |
161 | | |
162 | | template <> |
163 | 801 | inline size_t hash_crc32(doris::Int128 u) { |
164 | 801 | return doris::UInt128HashCRC32()({(u >> 64) & int64_t(-1), u & int64_t(-1)}); |
165 | 801 | } |
166 | | |
167 | | template <> |
168 | 0 | inline size_t hash_crc32(doris::VecDateTimeValue u) { |
169 | 0 | return hash_crc32(*(int64_t*)&u); |
170 | 0 | } |
171 | | |
172 | | template <> |
173 | 83 | inline size_t hash_crc32(doris::DateV2Value<doris::DateTimeV2ValueType> u) { |
174 | 83 | return hash_crc32(u.to_date_int_val()); |
175 | 83 | } |
176 | | |
177 | | template <> |
178 | 1.35k | inline size_t hash_crc32(doris::DateV2Value<doris::DateV2ValueType> u) { |
179 | 1.35k | return hash_crc32(u.to_date_int_val()); |
180 | 1.35k | } |
181 | | |
182 | | template <> |
183 | 35 | inline size_t hash_crc32(doris::TimeStampNsValue u) { |
184 | 35 | return hash_crc32(u.epoch_nanos()); |
185 | 35 | } |
186 | | |
187 | | template <> |
188 | 306 | inline size_t hash_crc32(doris::TimestampTzValue u) { |
189 | 306 | return hash_crc32(u.to_date_int_val()); |
190 | 306 | } |
191 | | |
192 | | #define DEFINE_HASH(T) \ |
193 | | template <> \ |
194 | | struct HashCRC32<T> { \ |
195 | 40.2M | size_t operator()(T key) const { \ |
196 | 40.2M | return hash_crc32<T>(key); \ |
197 | 40.2M | } \ Line | Count | Source | 195 | 474k | size_t operator()(T key) const { \ | 196 | 474k | return hash_crc32<T>(key); \ | 197 | 474k | } \ |
Line | Count | Source | 195 | 21.8k | size_t operator()(T key) const { \ | 196 | 21.8k | return hash_crc32<T>(key); \ | 197 | 21.8k | } \ |
Line | Count | Source | 195 | 17.9M | size_t operator()(T key) const { \ | 196 | 17.9M | return hash_crc32<T>(key); \ | 197 | 17.9M | } \ |
Line | Count | Source | 195 | 17.3M | size_t operator()(T key) const { \ | 196 | 17.3M | return hash_crc32<T>(key); \ | 197 | 17.3M | } \ |
_ZNK9HashCRC32IN4wide7integerILm128EjEEEclES2_ Line | Count | Source | 195 | 4.04M | size_t operator()(T key) const { \ | 196 | 4.04M | return hash_crc32<T>(key); \ | 197 | 4.04M | } \ |
Line | Count | Source | 195 | 8.91k | size_t operator()(T key) const { \ | 196 | 8.91k | return hash_crc32<T>(key); \ | 197 | 8.91k | } \ |
Line | Count | Source | 195 | 8.50k | size_t operator()(T key) const { \ | 196 | 8.50k | return hash_crc32<T>(key); \ | 197 | 8.50k | } \ |
Line | Count | Source | 195 | 180k | size_t operator()(T key) const { \ | 196 | 180k | return hash_crc32<T>(key); \ | 197 | 180k | } \ |
Line | Count | Source | 195 | 202k | size_t operator()(T key) const { \ | 196 | 202k | return hash_crc32<T>(key); \ | 197 | 202k | } \ |
Line | Count | Source | 195 | 801 | size_t operator()(T key) const { \ | 196 | 801 | return hash_crc32<T>(key); \ | 197 | 801 | } \ |
Unexecuted instantiation: _ZNK9HashCRC32IfEclEf Line | Count | Source | 195 | 13 | size_t operator()(T key) const { \ | 196 | 13 | return hash_crc32<T>(key); \ | 197 | 13 | } \ |
Unexecuted instantiation: _ZNK9HashCRC32IN5doris16VecDateTimeValueEEclES1_ _ZNK9HashCRC32IN5doris11DateV2ValueINS0_19DateTimeV2ValueTypeEEEEclES3_ Line | Count | Source | 195 | 83 | size_t operator()(T key) const { \ | 196 | 83 | return hash_crc32<T>(key); \ | 197 | 83 | } \ |
_ZNK9HashCRC32IN5doris11DateV2ValueINS0_15DateV2ValueTypeEEEEclES3_ Line | Count | Source | 195 | 1.35k | size_t operator()(T key) const { \ | 196 | 1.35k | return hash_crc32<T>(key); \ | 197 | 1.35k | } \ |
_ZNK9HashCRC32IN5doris16TimeStampNsValueEEclES1_ Line | Count | Source | 195 | 35 | size_t operator()(T key) const { \ | 196 | 35 | return hash_crc32<T>(key); \ | 197 | 35 | } \ |
_ZNK9HashCRC32IN5doris16TimestampTzValueEEclES1_ Line | Count | Source | 195 | 306 | size_t operator()(T key) const { \ | 196 | 306 | return hash_crc32<T>(key); \ | 197 | 306 | } \ |
Line | Count | Source | 195 | 43.2k | size_t operator()(T key) const { \ | 196 | 43.2k | return hash_crc32<T>(key); \ | 197 | 43.2k | } \ |
|
198 | | }; |
199 | | |
200 | | DEFINE_HASH(doris::UInt8) |
201 | | DEFINE_HASH(doris::UInt16) |
202 | | DEFINE_HASH(doris::UInt32) |
203 | | DEFINE_HASH(doris::UInt64) |
204 | | DEFINE_HASH(doris::UInt128) |
205 | | DEFINE_HASH(doris::Int8) |
206 | | DEFINE_HASH(doris::Int16) |
207 | | DEFINE_HASH(doris::Int32) |
208 | | DEFINE_HASH(doris::Int64) |
209 | | DEFINE_HASH(doris::Int128) |
210 | | DEFINE_HASH(doris::Float32) |
211 | | DEFINE_HASH(doris::Float64) |
212 | | DEFINE_HASH(doris::VecDateTimeValue) |
213 | | DEFINE_HASH(doris::DateV2Value<doris::DateTimeV2ValueType>) |
214 | | DEFINE_HASH(doris::DateV2Value<doris::DateV2ValueType>) |
215 | | DEFINE_HASH(doris::TimeStampNsValue) |
216 | | DEFINE_HASH(doris::TimestampTzValue) |
217 | | DEFINE_HASH(unsigned __int128) |
218 | | |
219 | | #undef DEFINE_HASH |
220 | | |
221 | | template <typename Key, typename Hash = HashCRC32<Key>> |
222 | | struct HashMixWrapper { |
223 | 17.2M | size_t operator()(Key key) const { return phmap::phmap_mix<sizeof(size_t)>()(Hash()(key)); }_ZNK14HashMixWrapperIj9HashCRC32IjEEclEj Line | Count | Source | 223 | 16.6M | size_t operator()(Key key) const { return phmap::phmap_mix<sizeof(size_t)>()(Hash()(key)); } |
_ZNK14HashMixWrapperIm9HashCRC32ImEEclEm Line | Count | Source | 223 | 676k | size_t operator()(Key key) const { return phmap::phmap_mix<sizeof(size_t)>()(Hash()(key)); } |
|
224 | | }; |
225 | | |
226 | | template <> |
227 | | struct HashCRC32<doris::UInt256> { |
228 | 204k | size_t operator()(const doris::UInt256& x) const { |
229 | 204k | #if defined(__SSE4_2__) || defined(__aarch64__) |
230 | 204k | doris::UInt64 crc = -1ULL; |
231 | 204k | crc = _mm_crc32_u64(crc, x.items[0]); |
232 | 204k | crc = _mm_crc32_u64(crc, x.items[1]); |
233 | 204k | crc = _mm_crc32_u64(crc, x.items[2]); |
234 | 204k | crc = _mm_crc32_u64(crc, x.items[3]); |
235 | 204k | return crc; |
236 | | #else |
237 | | return Hash128to64({Hash128to64({x.a, x.b}), Hash128to64({x.c, x.d})}); |
238 | | #endif |
239 | 204k | } |
240 | | }; |
241 | | |
242 | | template <> |
243 | | struct HashCRC32<wide::Int256> { |
244 | 8.54k | size_t operator()(const wide::Int256& x) const { |
245 | 8.54k | #if defined(__SSE4_2__) || defined(__aarch64__) |
246 | 8.54k | doris::UInt64 crc = -1ULL; |
247 | 8.54k | crc = _mm_crc32_u64(crc, x.items[0]); |
248 | 8.54k | crc = _mm_crc32_u64(crc, x.items[1]); |
249 | 8.54k | crc = _mm_crc32_u64(crc, x.items[2]); |
250 | 8.54k | crc = _mm_crc32_u64(crc, x.items[3]); |
251 | 8.54k | return crc; |
252 | | #else |
253 | | return Hash128to64( |
254 | | {Hash128to64({x.items[0], x.items[1]}), Hash128to64({x.items[2], x.items[3]})}); |
255 | | #endif |
256 | 8.54k | } |
257 | | }; |
258 | | |
259 | | template <> |
260 | | struct HashCRC32<doris::Decimal256> { |
261 | 136 | size_t operator()(const doris::Decimal256& value) const { |
262 | 136 | return HashCRC32<wide::Int256>()(value.value); |
263 | 136 | } |
264 | | }; |
265 | | |
266 | | template <> |
267 | | struct HashCRC32<doris::Decimal32> { |
268 | 0 | size_t operator()(const doris::Decimal32& value) const { |
269 | 0 | return HashCRC32<int32_t>()(value.value); |
270 | 0 | } |
271 | | }; |
272 | | |
273 | | template <> |
274 | | struct HashCRC32<doris::Decimal64> { |
275 | 120 | size_t operator()(const doris::Decimal64& value) const { |
276 | 120 | return HashCRC32<int64_t>()(value.value); |
277 | 120 | } |
278 | | }; |
279 | | |
280 | | template <> |
281 | | struct HashCRC32<doris::Decimal128V3> { |
282 | 39 | size_t operator()(const doris::Decimal128V3& value) const { |
283 | 39 | return HashCRC32<__int128>()(value.value); |
284 | 39 | } |
285 | | }; |
286 | | |
287 | | template <> |
288 | | struct HashCRC32<doris::Decimal128V2> { |
289 | 0 | size_t operator()(const doris::Decimal128V2& value) const { |
290 | 0 | return HashCRC32<__int128>()(value.value); |
291 | 0 | } |
292 | | }; |
293 | | |
294 | | template <> |
295 | | struct HashCRC32<doris::DecimalV2Value> { |
296 | 0 | size_t operator()(const doris::DecimalV2Value& value) const { |
297 | 0 | return HashCRC32<__int128>()(value.value()); |
298 | 0 | } |
299 | | }; |
300 | | |
301 | | #include "common/compile_check_avoid_begin.h" |
302 | | |
303 | | template <> |
304 | | struct HashCRC32<doris::UInt72> { |
305 | 78.7k | size_t operator()(const doris::UInt72& x) const { |
306 | 78.7k | doris::UInt64 crc = -1ULL; |
307 | 78.7k | crc = _mm_crc32_u8(crc, x.a); |
308 | 78.7k | crc = _mm_crc32_u64(crc, x.b); |
309 | 78.7k | return crc; |
310 | 78.7k | } |
311 | | }; |
312 | | |
313 | | template <> |
314 | | struct HashCRC32<doris::UInt96> { |
315 | 32.3k | size_t operator()(const doris::UInt96& x) const { |
316 | 32.3k | doris::UInt64 crc = -1ULL; |
317 | 32.3k | crc = _mm_crc32_u32(crc, x.a); |
318 | 32.3k | crc = _mm_crc32_u64(crc, x.b); |
319 | 32.3k | return crc; |
320 | 32.3k | } |
321 | | }; |
322 | | |
323 | | template <> |
324 | | struct HashCRC32<doris::UInt104> { |
325 | 4.61k | size_t operator()(const doris::UInt104& x) const { |
326 | 4.61k | doris::UInt64 crc = -1ULL; |
327 | 4.61k | crc = _mm_crc32_u8(crc, x.a); |
328 | 4.61k | crc = _mm_crc32_u32(crc, x.b); |
329 | 4.61k | crc = _mm_crc32_u64(crc, x.c); |
330 | 4.61k | return crc; |
331 | 4.61k | } |
332 | | }; |
333 | | |
334 | | template <> |
335 | | struct HashCRC32<doris::UInt136> { |
336 | 43.8k | size_t operator()(const doris::UInt136& x) const { |
337 | 43.8k | doris::UInt64 crc = -1ULL; |
338 | 43.8k | crc = _mm_crc32_u8(crc, x.a); |
339 | 43.8k | crc = _mm_crc32_u64(crc, x.b); |
340 | 43.8k | crc = _mm_crc32_u64(crc, x.c); |
341 | 43.8k | return crc; |
342 | 43.8k | } |
343 | | }; |
344 | | |
345 | | #include "common/compile_check_avoid_end.h" |