murmur3: streamline 128 bit hash round functions
clang was getting tripped up calculating the tail half-rounds for the 128 bit hashes, so we streamline the round functions so it copes a little better. plus, this is better code anyway.
This commit is contained in:
parent
ec42319224
commit
2469450ea9
@ -143,7 +143,7 @@ traits<uint64_t>::X[] = {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::array<T,traits<T>::COMPONENTS>
|
T
|
||||||
half_round (std::array<T,traits<T>::COMPONENTS> h,
|
half_round (std::array<T,traits<T>::COMPONENTS> h,
|
||||||
std::array<T,traits<T>::COMPONENTS> k,
|
std::array<T,traits<T>::COMPONENTS> k,
|
||||||
size_t i)
|
size_t i)
|
||||||
@ -155,8 +155,8 @@ half_round (std::array<T,traits<T>::COMPONENTS> h,
|
|||||||
k[i] *= CONSTANTS[i].c;
|
k[i] *= CONSTANTS[i].c;
|
||||||
k[i] = rotatel (k[i], CONSTANTS[i].Ks);
|
k[i] = rotatel (k[i], CONSTANTS[i].Ks);
|
||||||
k[i] *= CONSTANTS[i_].c;
|
k[i] *= CONSTANTS[i_].c;
|
||||||
h[i] ^= k[i];
|
|
||||||
return h;
|
return h[i] ^= k[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -164,18 +164,19 @@ half_round (std::array<T,traits<T>::COMPONENTS> h,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
std::array<T,traits<T>::COMPONENTS>
|
std::array<T,traits<T>::COMPONENTS>
|
||||||
full_round (std::array<T,traits<T>::COMPONENTS> h,
|
full_round (std::array<T,traits<T>::COMPONENTS> h,
|
||||||
std::array<T,traits<T>::COMPONENTS> k,
|
std::array<T,traits<T>::COMPONENTS> k)
|
||||||
size_t i)
|
|
||||||
{
|
{
|
||||||
auto COMPONENTS = traits<T>::COMPONENTS;
|
auto COMPONENTS = traits<T>::COMPONENTS;
|
||||||
auto CONSTANTS = traits<T>::X;
|
auto CONSTANTS = traits<T>::X;
|
||||||
|
|
||||||
h = half_round (h, k, i);
|
for (size_t i = 0; i < COMPONENTS; ++i) {
|
||||||
|
h[i] = half_round (h, k, i);
|
||||||
|
|
||||||
auto i_ = (i + 1) % COMPONENTS;
|
auto i_ = (i + 1) % COMPONENTS;
|
||||||
h[i] = rotatel (h[i], CONSTANTS[i].Hs);
|
h[i] = rotatel (h[i], CONSTANTS[i].Hs);
|
||||||
h[i] += h[i_];
|
h[i] += h[i_];
|
||||||
h[i] = h[i] * 5 + CONSTANTS[i].O;
|
h[i] = h[i] * 5 + CONSTANTS[i].O;
|
||||||
|
}
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@ -202,8 +203,7 @@ hash_128 (const void *restrict key,
|
|||||||
result_t k;
|
result_t k;
|
||||||
std::copy_n (cursor, traits<T>::COMPONENTS, k.begin ());
|
std::copy_n (cursor, traits<T>::COMPONENTS, k.begin ());
|
||||||
|
|
||||||
for (size_t i = 0; i < traits<T>::COMPONENTS; ++i)
|
h = full_round (h, k);
|
||||||
h = full_round (h, k, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// process the tail
|
// process the tail
|
||||||
@ -214,25 +214,21 @@ hash_128 (const void *restrict key,
|
|||||||
v = 0 ^ v;
|
v = 0 ^ v;
|
||||||
|
|
||||||
for (size_t i = 0; i < traits<T>::COMPONENTS; ++i)
|
for (size_t i = 0; i < traits<T>::COMPONENTS; ++i)
|
||||||
h = half_round (h, k, i);
|
h[i] = half_round (h, k, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalise the hash
|
// finalise the hash
|
||||||
for (auto &v: h)
|
for (auto &v: h)
|
||||||
v ^= len;
|
v ^= len;
|
||||||
|
|
||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i)
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[0] += h[i];
|
||||||
h[0] += h[i];
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[i] += h[0];
|
||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i)
|
|
||||||
h[i] += h[0];
|
|
||||||
|
|
||||||
for (auto &v: h)
|
for (auto &v: h)
|
||||||
v = util::hash::murmur3::mix (v);
|
v = util::hash::murmur3::mix (v);
|
||||||
|
|
||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i)
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[0] += h[i];
|
||||||
h[0] += h[i];
|
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i) h[i] += h[0];
|
||||||
for (size_t i = 1; i < traits<T>::COMPONENTS; ++i)
|
|
||||||
h[i] += h[0];
|
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user