mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
hash.c, string.c: improve hash function quality
Use FNV-1a (xor-then-multiply) instead of FNV-1 for better avalanche in byte hashing. Strengthen the hash finalizer in mrb_obj_hash_code() with multiply-xorshift to improve distribution for integer and symbol keys with power-of-two table sizes. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
+4
-1
@@ -361,7 +361,10 @@ mrb_obj_hash_code(mrb_state *mrb, mrb_value key)
|
||||
hash_code = U32(tt) ^ U32(mrb_integer(hash_code_obj));
|
||||
break;
|
||||
}
|
||||
return hash_code ^ (hash_code << 2) ^ (hash_code >> 2);
|
||||
hash_code ^= hash_code >> 16;
|
||||
hash_code *= 0x45d9f3b;
|
||||
hash_code ^= hash_code >> 16;
|
||||
return hash_code;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
||||
+4
-4
@@ -2014,18 +2014,18 @@ mrb_byte_hash_step(const uint8_t *s, mrb_int len, uint32_t hval)
|
||||
const uint8_t *send = s + len;
|
||||
|
||||
/*
|
||||
* FNV-1 hash each octet in the buffer
|
||||
* FNV-1a hash each octet in the buffer
|
||||
*/
|
||||
while (s < send) {
|
||||
/* xor the bottom with the current octet */
|
||||
hval ^= (uint32_t)*s++;
|
||||
|
||||
/* multiply by the 32-bit FNV magic prime mod 2^32 */
|
||||
#if defined(NO_FNV_GCC_OPTIMIZATION)
|
||||
hval *= FNV_32_PRIME;
|
||||
#else
|
||||
hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
|
||||
#endif
|
||||
|
||||
/* xor the bottom with the current octet */
|
||||
hval ^= (uint32_t)*s++;
|
||||
}
|
||||
|
||||
/* return our new hash value */
|
||||
|
||||
Reference in New Issue
Block a user