diff --git a/src/MurmurHash2.cpp b/src/MurmurHash2.cpp index cd1e53a..0b6bd4c 100644 --- a/src/MurmurHash2.cpp +++ b/src/MurmurHash2.cpp @@ -12,6 +12,11 @@ // 1. It will not work incrementally. // 2. It will not produce the same results on little-endian and big-endian // machines. +// +//changes for MurmurHash64A - small key hashes optimizations +//Copyright (C) <2021> Intel Corporation +//SPDX-License-Identifier: MIT + #include "MurmurHash2.h" @@ -97,6 +102,7 @@ uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed ) { const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995); const int r = 47; + unsigned int c = 0; uint64_t h = seed ^ (len * m); @@ -107,35 +113,39 @@ uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed ) { uint64_t k = *data++; - k *= m; - k ^= k >> r; - k *= m; - + k *= m; + k ^= k >> r; + k *= m; + h ^= k; - h *= m; + h *= m; } - + const unsigned char * data2 = (const unsigned char*)data; - - switch(len & 7) + uint64_t pIntData; + c = len & 7; + if (c!=0) { - case 7: h ^= uint64_t(data2[6]) << 48; - case 6: h ^= uint64_t(data2[5]) << 40; - case 5: h ^= uint64_t(data2[4]) << 32; - case 4: h ^= uint64_t(data2[3]) << 24; - case 3: h ^= uint64_t(data2[2]) << 16; - case 2: h ^= uint64_t(data2[1]) << 8; - case 1: h ^= uint64_t(data2[0]); - h *= m; - }; - + pIntData = *((uint64_t*)data2); + pIntData &= (1ULL<<(c*8))-1; + h ^= pIntData; + h *= m; + + } + + h ^= h >> r; h *= m; h ^= h >> r; return h; -} +} + + +/////////////////////////////////////////// +// +/////////////////////////////////////////// // 64-bit hash for 32-bit platforms diff --git a/src/MurmurHash3.cpp b/src/MurmurHash3.cpp index aa7982d..7054c8d 100644 --- a/src/MurmurHash3.cpp +++ b/src/MurmurHash3.cpp @@ -6,6 +6,10 @@ // algorithms are optimized for their respective platforms. You can still // compile and run any of them on any platform, but your performance with the // non-native version will be less than optimal. +// +//changes for MurmurHash3_x64_128 - small key hashes optimizations +//Copyright (C) <2021> Intel Corporation +//SPDX-License-Identifier: MIT #include "MurmurHash3.h" @@ -258,6 +262,8 @@ void MurmurHash3_x64_128 ( const void * key, const int len, const uint8_t * data = (const uint8_t*)key; const int nblocks = len / 16; + unsigned int c = 0; + uint64_t h1 = seed; uint64_t h2 = seed; @@ -288,34 +294,23 @@ void MurmurHash3_x64_128 ( const void * key, const int len, const uint8_t * tail = (const uint8_t*)(data + nblocks*16); - uint64_t k1 = 0; - uint64_t k2 = 0; + uint64_t k1_02 = 0; + uint64_t k2_02 = 0; - switch(len & 15) + c = len & 15; + if (c!=0) { - case 15: k2 ^= ((uint64_t)tail[14]) << 48; - case 14: k2 ^= ((uint64_t)tail[13]) << 40; - case 13: k2 ^= ((uint64_t)tail[12]) << 32; - case 12: k2 ^= ((uint64_t)tail[11]) << 24; - case 11: k2 ^= ((uint64_t)tail[10]) << 16; - case 10: k2 ^= ((uint64_t)tail[ 9]) << 8; - case 9: k2 ^= ((uint64_t)tail[ 8]) << 0; - k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; - - case 8: k1 ^= ((uint64_t)tail[ 7]) << 56; - case 7: k1 ^= ((uint64_t)tail[ 6]) << 48; - case 6: k1 ^= ((uint64_t)tail[ 5]) << 40; - case 5: k1 ^= ((uint64_t)tail[ 4]) << 32; - case 4: k1 ^= ((uint64_t)tail[ 3]) << 24; - case 3: k1 ^= ((uint64_t)tail[ 2]) << 16; - case 2: k1 ^= ((uint64_t)tail[ 1]) << 8; - case 1: k1 ^= ((uint64_t)tail[ 0]) << 0; - k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; - }; + uint64_t pIntData = *(const uint64_t *)(data + nblocks * 16 + 8); + pIntData &= (1ULL<<(((c>>3)*(c%8))*8))-1; + k2_02 ^= pIntData; k2_02 *= c2; k2_02 = ROTL64(k2_02,33); k2_02 *= c1; h2 ^= k2_02; + + uint64_t pIntData2 = *(const uint64_t *)(data + nblocks * 16); + pIntData2 &= (1ULL<<(c*8))-1; + k1_02 ^= pIntData2; k1_02 *= c1; k1_02 = ROTL64(k1_02,31);k1_02 *= c2; h1 ^= k1_02; + } //---------- // finalization - h1 ^= len; h2 ^= len; h1 += h2;