Coverage Report

Created: 2026-03-16 12:03

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