Coverage Report

Created: 2026-08-21 12:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
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
}
_Z14default_hash64IhEmT_
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
}
_Z14default_hash64IaEmT_
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
}
_Z14default_hash64IsEmT_
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
}
_Z14default_hash64IiEmT_
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
}
_Z14default_hash64IlEmT_
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
}
_Z14default_hash64InEmT_
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
}
_Z14default_hash64IfEmT_
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
}
_Z14default_hash64IdEmT_
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
}
_Z14default_hash64IjEmT_
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
}
_Z14default_hash64IoEmT_
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
}
_Z10hash_crc32IlEmT_
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
}
_Z10hash_crc32ImEmT_
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
}
_Z10hash_crc32IjEmT_
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
}
_Z10hash_crc32IhEmT_
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
}
_Z10hash_crc32ItEmT_
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
}
_Z10hash_crc32IaEmT_
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
}
_Z10hash_crc32IsEmT_
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
}
_Z10hash_crc32IiEmT_
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_
_Z10hash_crc32IdEmT_
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
        }                                \
_ZNK9HashCRC32IhEclEh
Line
Count
Source
190
97.4k
        size_t operator()(T key) const { \
191
97.4k
            return hash_crc32<T>(key);   \
192
97.4k
        }                                \
_ZNK9HashCRC32ItEclEt
Line
Count
Source
190
22.0k
        size_t operator()(T key) const { \
191
22.0k
            return hash_crc32<T>(key);   \
192
22.0k
        }                                \
_ZNK9HashCRC32IjEclEj
Line
Count
Source
190
15.4M
        size_t operator()(T key) const { \
191
15.4M
            return hash_crc32<T>(key);   \
192
15.4M
        }                                \
_ZNK9HashCRC32ImEclEm
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
        }                                \
_ZNK9HashCRC32IaEclEa
Line
Count
Source
190
8.90k
        size_t operator()(T key) const { \
191
8.90k
            return hash_crc32<T>(key);   \
192
8.90k
        }                                \
_ZNK9HashCRC32IsEclEs
Line
Count
Source
190
8.50k
        size_t operator()(T key) const { \
191
8.50k
            return hash_crc32<T>(key);   \
192
8.50k
        }                                \
_ZNK9HashCRC32IiEclEi
Line
Count
Source
190
159k
        size_t operator()(T key) const { \
191
159k
            return hash_crc32<T>(key);   \
192
159k
        }                                \
_ZNK9HashCRC32IlEclEl
Line
Count
Source
190
146k
        size_t operator()(T key) const { \
191
146k
            return hash_crc32<T>(key);   \
192
146k
        }                                \
_ZNK9HashCRC32InEclEn
Line
Count
Source
190
262
        size_t operator()(T key) const { \
191
262
            return hash_crc32<T>(key);   \
192
262
        }                                \
Unexecuted instantiation: _ZNK9HashCRC32IfEclEf
_ZNK9HashCRC32IdEclEd
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
        }                                \
_ZNK9HashCRC32IoEclEo
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"