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 | 24.2k | inline doris::UInt64 int_hash64(doris::UInt64 x) { |
50 | 24.2k | x ^= x >> 33; |
51 | 24.2k | x *= 0xff51afd7ed558ccdULL; |
52 | 24.2k | x ^= x >> 33; |
53 | 24.2k | x *= 0xc4ceb9fe1a85ec53ULL; |
54 | 24.2k | x ^= x >> 33; |
55 | | |
56 | 24.2k | return x; |
57 | 24.2k | } |
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.9M | inline doris::UInt64 int_hash_crc32(doris::UInt64 x) { |
68 | 36.9M | #if defined(__SSE4_2__) || (defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)) |
69 | 36.9M | 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.9M | } |
75 | | |
76 | | template <typename T> |
77 | 21.2k | inline size_t default_hash64(T key) { |
78 | 21.2k | union { |
79 | 21.2k | T in; |
80 | 21.2k | doris::UInt64 out; |
81 | 21.2k | } u; |
82 | 21.2k | u.out = 0; |
83 | 21.2k | u.in = key; |
84 | 21.2k | return int_hash64(u.out); |
85 | 21.2k | } 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.73k | inline size_t default_hash64(T key) { | 78 | 4.73k | union { | 79 | 4.73k | T in; | 80 | 4.73k | doris::UInt64 out; | 81 | 4.73k | } u; | 82 | 4.73k | u.out = 0; | 83 | 4.73k | u.in = key; | 84 | 4.73k | return int_hash64(u.out); | 85 | 4.73k | } |
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.51k | inline size_t default_hash64(T key) { | 78 | 1.51k | union { | 79 | 1.51k | T in; | 80 | 1.51k | doris::UInt64 out; | 81 | 1.51k | } u; | 82 | 1.51k | u.out = 0; | 83 | 1.51k | u.in = key; | 84 | 1.51k | return int_hash64(u.out); | 85 | 1.51k | } |
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 | } |
Line | Count | Source | 77 | 1.22k | inline size_t default_hash64(T key) { | 78 | 1.22k | union { | 79 | 1.22k | T in; | 80 | 1.22k | doris::UInt64 out; | 81 | 1.22k | } u; | 82 | 1.22k | u.out = 0; | 83 | 1.22k | u.in = key; | 84 | 1.22k | return int_hash64(u.out); | 85 | 1.22k | } |
|
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 | 21.2k | 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.73k | 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.51k | 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); } |
_ZNK11DefaultHashIovEclEo Line | Count | Source | 93 | 1.22k | size_t operator()(T key) const { return default_hash64<T>(key); } |
|
94 | | }; |
95 | | |
96 | | template <> |
97 | | struct DefaultHash<doris::VecDateTimeValue> { |
98 | 0 | size_t operator()(doris::VecDateTimeValue key) const { return int_hash64(*(int64_t*)&key); } |
99 | | }; |
100 | | |
101 | | template <> |
102 | | struct DefaultHash<doris::DateV2Value<doris::DateTimeV2ValueType>> { |
103 | 817 | size_t operator()(doris::DateV2Value<doris::DateTimeV2ValueType> key) const { |
104 | 817 | return int_hash64(key.to_date_int_val()); |
105 | 817 | } |
106 | | }; |
107 | | |
108 | | template <> |
109 | | struct DefaultHash<doris::DateV2Value<doris::DateV2ValueType>> { |
110 | 1.91k | size_t operator()(doris::DateV2Value<doris::DateV2ValueType> key) const { |
111 | 1.91k | return int_hash64(key.to_date_int_val()); |
112 | 1.91k | } |
113 | | }; |
114 | | |
115 | | template <> |
116 | | struct DefaultHash<doris::TimeStampNsValue> { |
117 | 304 | size_t operator()(doris::TimeStampNsValue key) const { return int_hash64(key.epoch_nanos()); } |
118 | | }; |
119 | | |
120 | | template <> |
121 | | struct DefaultHash<doris::TimestampTzValue> { |
122 | 0 | size_t operator()(doris::TimestampTzValue key) const { |
123 | 0 | return int_hash64(key.to_date_int_val()); |
124 | 0 | } |
125 | | }; |
126 | | |
127 | | template <> |
128 | | struct DefaultHash<doris::StringRef> : public doris::StringRefHash {}; |
129 | | |
130 | | template <> |
131 | | struct DefaultHash<wide::Int256> : public std::hash<wide::Int256> {}; |
132 | | |
133 | | template <typename T> |
134 | | struct HashCRC32; |
135 | | |
136 | | template <typename T> |
137 | 36.9M | inline size_t hash_crc32(T key) { |
138 | 36.9M | union { |
139 | 36.9M | T in; |
140 | 36.9M | doris::UInt64 out; |
141 | 36.9M | } u; |
142 | 36.9M | u.out = 0; |
143 | 36.9M | u.in = key; |
144 | 36.9M | return int_hash_crc32(u.out); |
145 | 36.9M | } Line | Count | Source | 137 | 146k | inline size_t hash_crc32(T key) { | 138 | 146k | union { | 139 | 146k | T in; | 140 | 146k | doris::UInt64 out; | 141 | 146k | } u; | 142 | 146k | u.out = 0; | 143 | 146k | u.in = key; | 144 | 146k | return int_hash_crc32(u.out); | 145 | 146k | } |
Line | Count | Source | 137 | 21.1M | inline size_t hash_crc32(T key) { | 138 | 21.1M | union { | 139 | 21.1M | T in; | 140 | 21.1M | doris::UInt64 out; | 141 | 21.1M | } u; | 142 | 21.1M | u.out = 0; | 143 | 21.1M | u.in = key; | 144 | 21.1M | return int_hash_crc32(u.out); | 145 | 21.1M | } |
Line | Count | Source | 137 | 15.4M | inline size_t hash_crc32(T key) { | 138 | 15.4M | union { | 139 | 15.4M | T in; | 140 | 15.4M | doris::UInt64 out; | 141 | 15.4M | } u; | 142 | 15.4M | u.out = 0; | 143 | 15.4M | u.in = key; | 144 | 15.4M | return int_hash_crc32(u.out); | 145 | 15.4M | } |
Line | Count | Source | 137 | 97.5k | inline size_t hash_crc32(T key) { | 138 | 97.5k | union { | 139 | 97.5k | T in; | 140 | 97.5k | doris::UInt64 out; | 141 | 97.5k | } u; | 142 | 97.5k | u.out = 0; | 143 | 97.5k | u.in = key; | 144 | 97.5k | return int_hash_crc32(u.out); | 145 | 97.5k | } |
Line | Count | Source | 137 | 22.0k | inline size_t hash_crc32(T key) { | 138 | 22.0k | union { | 139 | 22.0k | T in; | 140 | 22.0k | doris::UInt64 out; | 141 | 22.0k | } u; | 142 | 22.0k | u.out = 0; | 143 | 22.0k | u.in = key; | 144 | 22.0k | return int_hash_crc32(u.out); | 145 | 22.0k | } |
Line | Count | Source | 137 | 8.90k | inline size_t hash_crc32(T key) { | 138 | 8.90k | union { | 139 | 8.90k | T in; | 140 | 8.90k | doris::UInt64 out; | 141 | 8.90k | } u; | 142 | 8.90k | u.out = 0; | 143 | 8.90k | u.in = key; | 144 | 8.90k | return int_hash_crc32(u.out); | 145 | 8.90k | } |
Line | Count | Source | 137 | 8.50k | inline size_t hash_crc32(T key) { | 138 | 8.50k | union { | 139 | 8.50k | T in; | 140 | 8.50k | doris::UInt64 out; | 141 | 8.50k | } u; | 142 | 8.50k | u.out = 0; | 143 | 8.50k | u.in = key; | 144 | 8.50k | return int_hash_crc32(u.out); | 145 | 8.50k | } |
Line | Count | Source | 137 | 159k | inline size_t hash_crc32(T key) { | 138 | 159k | union { | 139 | 159k | T in; | 140 | 159k | doris::UInt64 out; | 141 | 159k | } u; | 142 | 159k | u.out = 0; | 143 | 159k | u.in = key; | 144 | 159k | return int_hash_crc32(u.out); | 145 | 159k | } |
Unexecuted instantiation: _Z10hash_crc32IfEmT_ Line | Count | Source | 137 | 186 | inline size_t hash_crc32(T key) { | 138 | 186 | union { | 139 | 186 | T in; | 140 | 186 | doris::UInt64 out; | 141 | 186 | } u; | 142 | 186 | u.out = 0; | 143 | 186 | u.in = key; | 144 | 186 | return int_hash_crc32(u.out); | 145 | 186 | } |
|
146 | | |
147 | | template <> |
148 | 137k | inline size_t hash_crc32(doris::UInt128 u) { |
149 | 137k | return doris::UInt128HashCRC32()(u); |
150 | 137k | } |
151 | | |
152 | | template <> |
153 | 51 | inline size_t hash_crc32(unsigned __int128 u) { |
154 | 51 | return doris::UInt128HashCRC32()(u); |
155 | 51 | } |
156 | | |
157 | | template <> |
158 | 262 | inline size_t hash_crc32(doris::Int128 u) { |
159 | 262 | return doris::UInt128HashCRC32()({(u >> 64) & int64_t(-1), u & int64_t(-1)}); |
160 | 262 | } |
161 | | |
162 | | template <> |
163 | 0 | inline size_t hash_crc32(doris::VecDateTimeValue u) { |
164 | 0 | return hash_crc32(*(int64_t*)&u); |
165 | 0 | } |
166 | | |
167 | | template <> |
168 | 258 | inline size_t hash_crc32(doris::DateV2Value<doris::DateTimeV2ValueType> u) { |
169 | 258 | return hash_crc32(u.to_date_int_val()); |
170 | 258 | } |
171 | | |
172 | | template <> |
173 | 1.45k | inline size_t hash_crc32(doris::DateV2Value<doris::DateV2ValueType> u) { |
174 | 1.45k | return hash_crc32(u.to_date_int_val()); |
175 | 1.45k | } |
176 | | |
177 | | template <> |
178 | 51 | inline size_t hash_crc32(doris::TimeStampNsValue u) { |
179 | 51 | return hash_crc32(u.epoch_nanos()); |
180 | 51 | } |
181 | | |
182 | | template <> |
183 | 306 | inline size_t hash_crc32(doris::TimestampTzValue u) { |
184 | 306 | return hash_crc32(u.to_date_int_val()); |
185 | 306 | } |
186 | | |
187 | | #define DEFINE_HASH(T) \ |
188 | | template <> \ |
189 | | struct HashCRC32<T> { \ |
190 | 37.1M | size_t operator()(T key) const { \ |
191 | 37.1M | return hash_crc32<T>(key); \ |
192 | 37.1M | } \ Line | Count | Source | 190 | 97.4k | size_t operator()(T key) const { \ | 191 | 97.4k | return hash_crc32<T>(key); \ | 192 | 97.4k | } \ |
Line | Count | Source | 190 | 22.0k | size_t operator()(T key) const { \ | 191 | 22.0k | return hash_crc32<T>(key); \ | 192 | 22.0k | } \ |
Line | Count | Source | 190 | 15.4M | size_t operator()(T key) const { \ | 191 | 15.4M | return hash_crc32<T>(key); \ | 192 | 15.4M | } \ |
Line | Count | Source | 190 | 21.1M | size_t operator()(T key) const { \ | 191 | 21.1M | return hash_crc32<T>(key); \ | 192 | 21.1M | } \ |
_ZNK9HashCRC32IN4wide7integerILm128EjEEEclES2_ Line | Count | Source | 190 | 137k | size_t operator()(T key) const { \ | 191 | 137k | return hash_crc32<T>(key); \ | 192 | 137k | } \ |
Line | Count | Source | 190 | 8.90k | size_t operator()(T key) const { \ | 191 | 8.90k | return hash_crc32<T>(key); \ | 192 | 8.90k | } \ |
Line | Count | Source | 190 | 8.50k | size_t operator()(T key) const { \ | 191 | 8.50k | return hash_crc32<T>(key); \ | 192 | 8.50k | } \ |
Line | Count | Source | 190 | 159k | size_t operator()(T key) const { \ | 191 | 159k | return hash_crc32<T>(key); \ | 192 | 159k | } \ |
Line | Count | Source | 190 | 146k | size_t operator()(T key) const { \ | 191 | 146k | return hash_crc32<T>(key); \ | 192 | 146k | } \ |
Line | Count | Source | 190 | 262 | size_t operator()(T key) const { \ | 191 | 262 | return hash_crc32<T>(key); \ | 192 | 262 | } \ |
Unexecuted instantiation: _ZNK9HashCRC32IfEclEf Line | Count | Source | 190 | 186 | size_t operator()(T key) const { \ | 191 | 186 | return hash_crc32<T>(key); \ | 192 | 186 | } \ |
Unexecuted instantiation: _ZNK9HashCRC32IN5doris16VecDateTimeValueEEclES1_ _ZNK9HashCRC32IN5doris11DateV2ValueINS0_19DateTimeV2ValueTypeEEEEclES3_ Line | Count | Source | 190 | 258 | size_t operator()(T key) const { \ | 191 | 258 | return hash_crc32<T>(key); \ | 192 | 258 | } \ |
_ZNK9HashCRC32IN5doris11DateV2ValueINS0_15DateV2ValueTypeEEEEclES3_ Line | Count | Source | 190 | 1.45k | size_t operator()(T key) const { \ | 191 | 1.45k | return hash_crc32<T>(key); \ | 192 | 1.45k | } \ |
_ZNK9HashCRC32IN5doris16TimeStampNsValueEEclES1_ Line | Count | Source | 190 | 51 | size_t operator()(T key) const { \ | 191 | 51 | return hash_crc32<T>(key); \ | 192 | 51 | } \ |
_ZNK9HashCRC32IN5doris16TimestampTzValueEEclES1_ Line | Count | Source | 190 | 306 | size_t operator()(T key) const { \ | 191 | 306 | return hash_crc32<T>(key); \ | 192 | 306 | } \ |
Line | Count | Source | 190 | 51 | size_t operator()(T key) const { \ | 191 | 51 | return hash_crc32<T>(key); \ | 192 | 51 | } \ |
|
193 | | }; |
194 | | |
195 | | DEFINE_HASH(doris::UInt8) |
196 | | DEFINE_HASH(doris::UInt16) |
197 | | DEFINE_HASH(doris::UInt32) |
198 | | DEFINE_HASH(doris::UInt64) |
199 | | DEFINE_HASH(doris::UInt128) |
200 | | DEFINE_HASH(doris::Int8) |
201 | | DEFINE_HASH(doris::Int16) |
202 | | DEFINE_HASH(doris::Int32) |
203 | | DEFINE_HASH(doris::Int64) |
204 | | DEFINE_HASH(doris::Int128) |
205 | | DEFINE_HASH(doris::Float32) |
206 | | DEFINE_HASH(doris::Float64) |
207 | | DEFINE_HASH(doris::VecDateTimeValue) |
208 | | DEFINE_HASH(doris::DateV2Value<doris::DateTimeV2ValueType>) |
209 | | DEFINE_HASH(doris::DateV2Value<doris::DateV2ValueType>) |
210 | | DEFINE_HASH(doris::TimeStampNsValue) |
211 | | DEFINE_HASH(doris::TimestampTzValue) |
212 | | DEFINE_HASH(unsigned __int128) |
213 | | |
214 | | #undef DEFINE_HASH |
215 | | |
216 | | template <typename Key, typename Hash = HashCRC32<Key>> |
217 | | struct HashMixWrapper { |
218 | 15.2M | size_t operator()(Key key) const { return phmap::phmap_mix<sizeof(size_t)>()(Hash()(key)); }_ZNK14HashMixWrapperIj9HashCRC32IjEEclEj Line | Count | Source | 218 | 15.0M | size_t operator()(Key key) const { return phmap::phmap_mix<sizeof(size_t)>()(Hash()(key)); } |
_ZNK14HashMixWrapperIm9HashCRC32ImEEclEm Line | Count | Source | 218 | 218k | size_t operator()(Key key) const { return phmap::phmap_mix<sizeof(size_t)>()(Hash()(key)); } |
|
219 | | }; |
220 | | |
221 | | template <> |
222 | | struct HashCRC32<doris::UInt256> { |
223 | 59.3k | size_t operator()(const doris::UInt256& x) const { |
224 | 59.3k | #if defined(__SSE4_2__) || defined(__aarch64__) |
225 | 59.3k | doris::UInt64 crc = -1ULL; |
226 | 59.3k | crc = _mm_crc32_u64(crc, x.items[0]); |
227 | 59.3k | crc = _mm_crc32_u64(crc, x.items[1]); |
228 | 59.3k | crc = _mm_crc32_u64(crc, x.items[2]); |
229 | 59.3k | crc = _mm_crc32_u64(crc, x.items[3]); |
230 | 59.3k | return crc; |
231 | | #else |
232 | | return Hash128to64({Hash128to64({x.a, x.b}), Hash128to64({x.c, x.d})}); |
233 | | #endif |
234 | 59.3k | } |
235 | | }; |
236 | | |
237 | | template <> |
238 | | struct HashCRC32<wide::Int256> { |
239 | 8.45k | size_t operator()(const wide::Int256& x) const { |
240 | 8.45k | #if defined(__SSE4_2__) || defined(__aarch64__) |
241 | 8.45k | doris::UInt64 crc = -1ULL; |
242 | 8.45k | crc = _mm_crc32_u64(crc, x.items[0]); |
243 | 8.45k | crc = _mm_crc32_u64(crc, x.items[1]); |
244 | 8.45k | crc = _mm_crc32_u64(crc, x.items[2]); |
245 | 8.45k | crc = _mm_crc32_u64(crc, x.items[3]); |
246 | 8.45k | return crc; |
247 | | #else |
248 | | return Hash128to64( |
249 | | {Hash128to64({x.items[0], x.items[1]}), Hash128to64({x.items[2], x.items[3]})}); |
250 | | #endif |
251 | 8.45k | } |
252 | | }; |
253 | | |
254 | | template <> |
255 | | struct HashCRC32<doris::Decimal256> { |
256 | 136 | size_t operator()(const doris::Decimal256& value) const { |
257 | 136 | return HashCRC32<wide::Int256>()(value.value); |
258 | 136 | } |
259 | | }; |
260 | | |
261 | | template <> |
262 | | struct HashCRC32<doris::Decimal32> { |
263 | 0 | size_t operator()(const doris::Decimal32& value) const { |
264 | 0 | return HashCRC32<int32_t>()(value.value); |
265 | 0 | } |
266 | | }; |
267 | | |
268 | | template <> |
269 | | struct HashCRC32<doris::Decimal64> { |
270 | 120 | size_t operator()(const doris::Decimal64& value) const { |
271 | 120 | return HashCRC32<int64_t>()(value.value); |
272 | 120 | } |
273 | | }; |
274 | | |
275 | | template <> |
276 | | struct HashCRC32<doris::Decimal128V3> { |
277 | 39 | size_t operator()(const doris::Decimal128V3& value) const { |
278 | 39 | return HashCRC32<__int128>()(value.value); |
279 | 39 | } |
280 | | }; |
281 | | |
282 | | template <> |
283 | | struct HashCRC32<doris::Decimal128V2> { |
284 | 0 | size_t operator()(const doris::Decimal128V2& value) const { |
285 | 0 | return HashCRC32<__int128>()(value.value); |
286 | 0 | } |
287 | | }; |
288 | | |
289 | | template <> |
290 | | struct HashCRC32<doris::DecimalV2Value> { |
291 | 0 | size_t operator()(const doris::DecimalV2Value& value) const { |
292 | 0 | return HashCRC32<__int128>()(value.value()); |
293 | 0 | } |
294 | | }; |
295 | | |
296 | | #include "common/compile_check_avoid_begin.h" |
297 | | |
298 | | template <> |
299 | | struct HashCRC32<doris::UInt72> { |
300 | 77.0k | size_t operator()(const doris::UInt72& x) const { |
301 | 77.0k | doris::UInt64 crc = -1ULL; |
302 | 77.0k | crc = _mm_crc32_u8(crc, x.a); |
303 | 77.0k | crc = _mm_crc32_u64(crc, x.b); |
304 | 77.0k | return crc; |
305 | 77.0k | } |
306 | | }; |
307 | | |
308 | | template <> |
309 | | struct HashCRC32<doris::UInt96> { |
310 | 26.1k | size_t operator()(const doris::UInt96& x) const { |
311 | 26.1k | doris::UInt64 crc = -1ULL; |
312 | 26.1k | crc = _mm_crc32_u32(crc, x.a); |
313 | 26.1k | crc = _mm_crc32_u64(crc, x.b); |
314 | 26.1k | return crc; |
315 | 26.1k | } |
316 | | }; |
317 | | |
318 | | template <> |
319 | | struct HashCRC32<doris::UInt104> { |
320 | 4.50k | size_t operator()(const doris::UInt104& x) const { |
321 | 4.50k | doris::UInt64 crc = -1ULL; |
322 | 4.50k | crc = _mm_crc32_u8(crc, x.a); |
323 | 4.50k | crc = _mm_crc32_u32(crc, x.b); |
324 | 4.50k | crc = _mm_crc32_u64(crc, x.c); |
325 | 4.50k | return crc; |
326 | 4.50k | } |
327 | | }; |
328 | | |
329 | | template <> |
330 | | struct HashCRC32<doris::UInt136> { |
331 | 11.0k | size_t operator()(const doris::UInt136& x) const { |
332 | 11.0k | doris::UInt64 crc = -1ULL; |
333 | 11.0k | crc = _mm_crc32_u8(crc, x.a); |
334 | 11.0k | crc = _mm_crc32_u64(crc, x.b); |
335 | 11.0k | crc = _mm_crc32_u64(crc, x.c); |
336 | 11.0k | return crc; |
337 | 11.0k | } |
338 | | }; |
339 | | |
340 | | #include "common/compile_check_avoid_end.h" |