Fix murmurhash for s390x

This commit is contained in:
HarryLeeIBM 2023-02-28 10:08:57 -08:00
parent 866c318c12
commit 5f649542a3
4 changed files with 74 additions and 17 deletions

View File

@ -31,6 +31,40 @@
#define BIG_CONSTANT(x) (x##LLU) #define BIG_CONSTANT(x) (x##LLU)
#endif // !defined(_MSC_VER) #endif // !defined(_MSC_VER)
//
//-----------------------------------------------------------------------------
// Block read - on little-endian machines this is a single load,
// while on big-endian or unknown machines the byte accesses should
// still get optimized into the most efficient instruction.
static inline uint32_t getblock ( const uint32_t * p )
{
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
return *p;
#else
const uint8_t *c = (const uint8_t *)p;
return (uint32_t)c[0] |
(uint32_t)c[1] << 8 |
(uint32_t)c[2] << 16 |
(uint32_t)c[3] << 24;
#endif
}
static inline uint64_t getblock ( const uint64_t * p )
{
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
return *p;
#else
const uint8_t *c = (const uint8_t *)p;
return (uint64_t)c[0] |
(uint64_t)c[1] << 8 |
(uint64_t)c[2] << 16 |
(uint64_t)c[3] << 24 |
(uint64_t)c[4] << 32 |
(uint64_t)c[5] << 40 |
(uint64_t)c[6] << 48 |
(uint64_t)c[7] << 56;
#endif
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -52,7 +86,7 @@ uint32_t MurmurHash2 ( const void * key, size_t len, uint32_t seed )
while(len >= 4) while(len >= 4)
{ {
uint32_t k = *(uint32_t*)data; uint32_t k = getblock((const uint32_t *)data);
k *= m; k *= m;
k ^= k >> r; k ^= k >> r;
@ -105,7 +139,7 @@ uint64_t MurmurHash64A ( const void * key, size_t len, uint64_t seed )
while(data != end) while(data != end)
{ {
uint64_t k = *data++; uint64_t k = getblock(data++);
k *= m; k *= m;
k ^= k >> r; k ^= k >> r;
@ -151,12 +185,12 @@ uint64_t MurmurHash64B ( const void * key, size_t len, uint64_t seed )
while(len >= 8) while(len >= 8)
{ {
uint32_t k1 = *data++; uint32_t k1 = getblock(data++);
k1 *= m; k1 ^= k1 >> r; k1 *= m; k1 *= m; k1 ^= k1 >> r; k1 *= m;
h1 *= m; h1 ^= k1; h1 *= m; h1 ^= k1;
len -= 4; len -= 4;
uint32_t k2 = *data++; uint32_t k2 = getblock(data++);
k2 *= m; k2 ^= k2 >> r; k2 *= m; k2 *= m; k2 ^= k2 >> r; k2 *= m;
h2 *= m; h2 ^= k2; h2 *= m; h2 ^= k2;
len -= 4; len -= 4;
@ -164,7 +198,7 @@ uint64_t MurmurHash64B ( const void * key, size_t len, uint64_t seed )
if(len >= 4) if(len >= 4)
{ {
uint32_t k1 = *data++; uint32_t k1 = getblock(data++);
k1 *= m; k1 ^= k1 >> r; k1 *= m; k1 *= m; k1 ^= k1 >> r; k1 *= m;
h1 *= m; h1 ^= k1; h1 *= m; h1 ^= k1;
len -= 4; len -= 4;
@ -215,7 +249,7 @@ uint32_t MurmurHash2A ( const void * key, size_t len, uint32_t seed )
while(len >= 4) while(len >= 4)
{ {
uint32_t k = *(uint32_t*)data; uint32_t k = getblock((const uint32_t *)data);
mmix(h,k); mmix(h,k);
@ -278,7 +312,7 @@ public:
while(len >= 4) while(len >= 4)
{ {
uint32_t k = *(uint32_t*)data; uint32_t k = getblock((const uint32_t *)data);
mmix(m_hash,k); mmix(m_hash,k);
@ -427,7 +461,7 @@ uint32_t MurmurHashAligned2 ( const void * key, size_t len, uint32_t seed )
while(len >= 4) while(len >= 4)
{ {
d = *(uint32_t *)data; d = getblock((const uint32_t *)data);
t = (t >> sr) | (d << sl); t = (t >> sr) | (d << sl);
uint32_t k = t; uint32_t k = t;
@ -492,7 +526,7 @@ uint32_t MurmurHashAligned2 ( const void * key, size_t len, uint32_t seed )
{ {
while(len >= 4) while(len >= 4)
{ {
uint32_t k = *(uint32_t *)data; uint32_t k = getblock((const uint32_t *)data);
MIX(h,k,m); MIX(h,k,m);

View File

@ -55,14 +55,32 @@ inline uint64_t rotl64 ( uint64_t x, int8_t r )
FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i )
{ {
uint32_t res; #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
memcpy(&res, p + i, sizeof(res)); return p[i];
return res; #else
const uint8_t *c = (const uint8_t *)&p[i];
return (uint32_t)c[0] |
(uint32_t)c[1] << 8 |
(uint32_t)c[2] << 16 |
(uint32_t)c[3] << 24;
#endif
} }
FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i ) FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i )
{ {
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
return p[i]; return p[i];
#else
const uint8_t *c = (const uint8_t *)&p[i];
return (uint64_t)c[0] |
(uint64_t)c[1] << 8 |
(uint64_t)c[2] << 16 |
(uint64_t)c[3] << 24 |
(uint64_t)c[4] << 32 |
(uint64_t)c[5] << 40 |
(uint64_t)c[6] << 48 |
(uint64_t)c[7] << 56;
#endif
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -329,9 +347,13 @@ void MurmurHash3_x64_128 ( const void * key, const size_t len,
h1 += h2; h1 += h2;
h2 += h1; h2 += h1;
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
((uint64_t*)out)[0] = h1; ((uint64_t*)out)[0] = h1;
((uint64_t*)out)[1] = h2; ((uint64_t*)out)[1] = h2;
#else
((uint64_t*)out)[0] = h2;
((uint64_t*)out)[1] = h1;
#endif
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -25,5 +25,5 @@
9631199822919835226 9631199822919835226
4334672815104069193 4334672815104069193
4334672815104069193 4334672815104069193
6145F501578671E2877DBA2BE487AF7E 1
16FE7483905CCE7A85670E43E4678877 1

View File

@ -32,5 +32,6 @@ SELECT gccMurmurHash('foo');
SELECT gccMurmurHash('\x01'); SELECT gccMurmurHash('\x01');
SELECT gccMurmurHash(1); SELECT gccMurmurHash(1);
SELECT hex(murmurHash3_128('foo')); SELECT hex(murmurHash3_128('foo')) = hex(reverse(unhex('6145F501578671E2877DBA2BE487AF7E'))) or hex(murmurHash3_128('foo')) = '6145F501578671E2877DBA2BE487AF7E';
SELECT hex(murmurHash3_128('\x01'));
SELECT hex(murmurHash3_128('\x01')) = hex(reverse(unhex('16FE7483905CCE7A85670E43E4678877'))) or hex(murmurHash3_128('\x01')) = '16FE7483905CCE7A85670E43E4678877';