Change FNV1A Meiyan hash by FNV1A Jesteress
This commit is contained in:
1 parent
02be3b6d69
commit
b60cc58980
1 file changed
+22
-18
@@ -650,37 +650,41 @@ static inline uint32_t m_core_rotl32a (uint32_t x, uint32_t n)
|
|||||||
return (x<<n) | (x>>(32-n));
|
return (x<<n) | (x>>(32-n));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement Meiyan Hash
|
/* Implement FNV1A Jesteress Hash (very similar to FNV1A Meiyan Hash)
|
||||||
See https://www.strchr.com/hash_functions & http://www.sanmayce.com/Fastest_Hash/
|
See http://www.sanmayce.com/Fastest_Hash/ and
|
||||||
|
https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash
|
||||||
NOTE: A lot of cast. Not really type nor alignement safe.
|
NOTE: A lot of cast. Not really type nor alignement safe.
|
||||||
NOTE: Can be reduced to very few instructions if constant size argument.
|
NOTE: Can be reduced to very few instructions if constant size argument.
|
||||||
*/
|
*/
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
m_core_hash (const void *str, size_t wrdlen)
|
m_core_hash (const void *str, size_t length)
|
||||||
{
|
{
|
||||||
const uint32_t prime = 709607U;
|
const uint32_t prime = 709607U;
|
||||||
uint32_t hash32 = 2166136261U ^ M_HASH_SEED;
|
uint32_t hash32 = 2166136261U ^ M_HASH_SEED;
|
||||||
const uint8_t *p = (const uint8_t *)str;
|
const uint8_t *p = (const uint8_t *)str;
|
||||||
|
|
||||||
|
assert (str != NULL);
|
||||||
assert ( ( (uintptr_t)p & (sizeof(uint32_t)-1) ) == 0);
|
assert ( ( (uintptr_t)p & (sizeof(uint32_t)-1) ) == 0);
|
||||||
while (wrdlen >= 2*sizeof(uint32_t)) {
|
assert ( length > 0);
|
||||||
const uint32_t *pui = (const uint32_t *) (uintptr_t) p;
|
|
||||||
hash32 = (hash32 ^ (m_core_rotl32a(pui[0],5) ^ pui[1])) * prime;
|
while (length >= 2*sizeof(uint32_t)) {
|
||||||
wrdlen -= 2*sizeof(uint32_t);
|
const uint32_t *ptr = (const uint32_t *) (uintptr_t) p;
|
||||||
|
hash32 = (hash32 ^ (m_core_rotl32a(ptr[0],5) ^ ptr[1])) * prime;
|
||||||
|
length -= 2*sizeof(uint32_t);
|
||||||
p += 2*sizeof(uint32_t);
|
p += 2*sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
// Cases: 0,1,2,3,4,5,6,7
|
// Cases: 0,1,2,3,4,5,6,7
|
||||||
if (wrdlen & sizeof(uint32_t)) {
|
if (length & sizeof(uint32_t)) {
|
||||||
const uint16_t *pui = (const uint16_t *) (uintptr_t) p;
|
const uint32_t *ptr = (const uint32_t *) (uintptr_t) p;
|
||||||
hash32 = (hash32 ^ pui[0]) * prime;
|
hash32 = (hash32 ^ ptr[0]) * prime;
|
||||||
hash32 = (hash32 ^ pui[1]) * prime;
|
p += sizeof(uint32_t);
|
||||||
p += 2* sizeof(uint16_t);
|
|
||||||
}
|
}
|
||||||
if (wrdlen & sizeof(uint16_t)) {
|
if (length & sizeof(uint16_t)) {
|
||||||
const uint16_t *pui = (const uint16_t *) (uintptr_t) p;
|
const uint16_t *ptr = (const uint16_t *) (uintptr_t) p;
|
||||||
hash32 = (hash32 ^ pui[0]) * prime;
|
hash32 = (hash32 ^ ptr[0]) * prime;
|
||||||
p += sizeof(uint16_t);
|
p += sizeof(uint16_t);
|
||||||
}
|
}
|
||||||
if (wrdlen & 1)
|
if (length & 1)
|
||||||
hash32 = (hash32 ^ *p) * prime;
|
hash32 = (hash32 ^ *p) * prime;
|
||||||
return hash32 ^ (hash32 >> 16);
|
return hash32 ^ (hash32 >> 16);
|
||||||
}
|
}
|
||||||
@@ -690,8 +694,8 @@ m_core_hash (const void *str, size_t wrdlen)
|
|||||||
if the type is recognized.
|
if the type is recognized.
|
||||||
NOTE: Default case is not safe if the type is defined with the '[1]' trick. */
|
NOTE: Default case is not safe if the type is defined with the '[1]' trick. */
|
||||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||||
#define M_HASH_INT32(a) ( (a) ^ ((a) << 11) )
|
#define M_HASH_INT32(a) ( (a) ^ ((a) << 11) ^ M_HASH_SEED )
|
||||||
#define M_HASH_INT64(a) ( ( (a) >> 33 ) ^ (a) ^ ((a) << 11) )
|
#define M_HASH_INT64(a) ( ( (a) >> 33 ) ^ (a) ^ ((a) << 11) ^ M_HASH_SEED )
|
||||||
#define M_HASH_DEFAULT(a) \
|
#define M_HASH_DEFAULT(a) \
|
||||||
_Generic((a)+0, \
|
_Generic((a)+0, \
|
||||||
int32_t: M_HASH_INT32(M_AS_TYPE(int32_t, a)), \
|
int32_t: M_HASH_INT32(M_AS_TYPE(int32_t, a)), \
|
||||||
|
|||||||
Reference in new issue
Block a user