fix hash function

This commit is contained in:
blueloveTH 2025-06-29 22:10:59 +08:00
parent a1cdfb6739
commit eb52965aef
2 changed files with 9 additions and 22 deletions

View File

@ -61,7 +61,7 @@ static uint32_t Dict__next_cap(uint32_t cap) {
}
}
static uint64_t Dict__hash(uint64_t key) {
static uint64_t Dict__hash_2nd(uint64_t key) {
// https://gist.github.com/badboy/6267743
key = (~key) + (key << 21); // key = (key << 21) - key - 1
key = key ^ (key >> 24);
@ -143,7 +143,11 @@ static bool Dict__probe(Dict* self,
DictEntry** p_entry) {
py_i64 h_user;
if(!py_hash(key, &h_user)) return false;
*p_hash = Dict__hash((uint64_t)h_user);
if(py_isstr(key)) {
*p_hash = (uint64_t)h_user;
} else {
*p_hash = Dict__hash_2nd((uint64_t)h_user);
}
uint32_t mask = self->capacity - 1;
uint32_t idx = (*p_hash) % self->capacity;
while(true) {

View File

@ -245,24 +245,6 @@ static bool float__repr__(int argc, py_Ref argv) {
return true;
}
union c11_8bytes {
py_i64 _i64;
py_f64 _f64;
union {
uint32_t upper;
uint32_t lower;
} bits;
};
static py_i64 c11_8bytes__hash(union c11_8bytes u) {
// https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
const uint32_t C = 2654435761;
u.bits.upper *= C;
u.bits.lower *= C;
return u._i64;
}
static bool int__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
py_assign(py_retval(), argv);
@ -272,8 +254,9 @@ static bool int__hash__(int argc, py_Ref argv) {
static bool float__hash__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
py_f64 val = py_tofloat(&argv[0]);
union c11_8bytes u = {._f64 = val};
py_newint(py_retval(), c11_8bytes__hash(u));
py_i64 h_user;
memcpy(&h_user, &val, sizeof(py_f64));
py_newint(py_retval(), h_user);
return true;
}