12 #ifndef THRILL_COMMON_HASH_HEADER 13 #define THRILL_COMMON_HASH_HEADER 24 #include <type_traits> 26 #ifdef THRILL_HAVE_SSE4_2 27 #include <smmintrin.h> 38 template <
typename To,
typename From>
40 static_assert(
sizeof(To) ==
sizeof(From),
41 "Cannot cast types of different sizes");
48 template <
typename To,
typename From>
55 template <
typename To,
typename From>
64 static inline uint64_t
Hash128to64(
const uint64_t upper,
const uint64_t lower) {
66 const uint64_t k = 0x9DDFEA08EB382D69
ull;
67 uint64_t a = (lower ^ upper) * k;
69 uint64_t b = (upper ^ a) * k;
84 key = (~key) + (key << 18);
85 key = key ^ (key >> 31);
87 key = key ^ (key >> 11);
88 key = key + (key << 6);
89 key = key ^ (key >> 22);
102 {
return reinterpret_cast<const char*
>(&
x); }
103 static size_t size(
const T&) {
return sizeof(
T); }
112 #ifdef THRILL_HAVE_SSE4_2 119 template <
typename ValueType>
120 struct HashCrc32Sse42 {
125 uint32_t hash_bytes(
const void* data,
size_t length, uint32_t crc = 0xffffffff)
const {
126 const char* p_buf = (
const char*)data;
129 uint64_t crc_carry = crc;
130 for (
size_t i = 0; i < length /
sizeof(uint64_t); i++) {
131 crc_carry = _mm_crc32_u64(crc_carry, *(
const uint64_t*)p_buf);
132 p_buf +=
sizeof(uint64_t);
134 crc = (uint32_t)crc_carry;
140 crc = _mm_crc32_u8(crc, *p_buf++);
143 crc = _mm_crc32_u16(crc, *(
const uint16_t*)p_buf);
148 crc = _mm_crc32_u32(crc, *(
const uint32_t*)p_buf);
151 crc = _mm_crc32_u8(crc, *p_buf++);
154 crc = _mm_crc32_u16(crc, *(
const uint16_t*)p_buf);
157 crc = _mm_crc32_u32(crc, *(
const uint32_t*)p_buf);
161 crc = _mm_crc32_u8(crc, *p_buf);
171 uint32_t operator () (
const ValueType& val, uint32_t crc = 0xffffffff)
const {
174 return hash_bytes(ptr, size, crc);
189 template <
typename ValueType>
191 uint32_t operator () (
const ValueType& val, uint32_t crc = 0xffffffff)
const {
200 #ifdef THRILL_HAVE_SSE4_2 201 template <
typename T>
204 template <
typename T>
217 template <
size_t size,
typename hash_t = uint32_t,
218 typename prng_t = std::mt19937>
225 using Table = std::array<Subtable, size>;
232 for (
size_t i = 0; i < size; ++i) {
233 for (
size_t j = 0; j < 256; ++j) {
234 table_[i][j] = rng();
240 template <
typename T>
242 static_assert(
sizeof(
T) == size,
"Size mismatch with operand type");
245 const uint8_t* ptr =
reinterpret_cast<const uint8_t*
>(&
x);
246 for (
size_t i = 0; i < size; ++i) {
247 hash ^= table_[i][*(ptr + i)];
257 template <
typename T>
261 template <
typename T>
267 #endif // !THRILL_COMMON_HASH_HEADER Tabulation Hashing, see https://en.wikipedia.org/wiki/Tabulation_hashing.
void init(const size_t seed)
(re-)initialize the table by filling it with random values
TabulationHashing(size_t seed=0)
static size_t size(const T &)
#define TLX_ATTRIBUTE_FALLTHROUGH
std::array< hash_type, 256 > Subtable
static const char * ptr(const T &x)
std::array< Subtable, size > Table
static size_t size(const std::string &s)
Hashing helper that decides what is hashed.
static uint32_t Hash64to32(uint64_t key)
Returns a uint32_t hash of a uint64_t.
uint64_t ull() const
return the number as an uint64_t (unsigned long long)
static uint64_t Hash128to64(const uint64_t upper, const uint64_t lower)
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
HashCrc32< T > hash
Select a hashing method.
To & alias_cast(From &raw_data)
static const char * ptr(const std::string &s)
uint32_t crc32_slicing_by_8(uint32_t crc, const void *data, size_t length)