fix vec2i.__hash__

This commit is contained in:
blueloveTH 2024-11-23 01:53:56 +08:00
parent 55b7db54a2
commit b31795bf83
3 changed files with 14 additions and 4 deletions

View File

@ -301,11 +301,12 @@ DEF_VECTOR_OPS(3)
} \ } \
static bool vec##D##i##__hash__(int argc, py_Ref argv) { \ static bool vec##D##i##__hash__(int argc, py_Ref argv) { \
PY_CHECK_ARGC(1); \ PY_CHECK_ARGC(1); \
const uint32_t C = 2654435761; \
c11_vec##D##i v = py_tovec##D##i(argv); \ c11_vec##D##i v = py_tovec##D##i(argv); \
py_i64 hash = 0; \ uint64_t hash = 0; \
for(int i = 0; i < D; i++) \ for(int i = 0; i < D; i++) \
hash = hash * 31 + v.data[i]; \ hash = hash * 31 + (uint32_t)v.data[i] * C; \
py_newint(py_retval(), hash); \ py_newint(py_retval(), (py_i64)hash); \
return true; \ return true; \
} }

View File

@ -74,7 +74,6 @@ static void Dict__rehash_2x(Dict* self) {
Dict old_dict = *self; Dict old_dict = *self;
int new_capacity = self->capacity * 2; int new_capacity = self->capacity * 2;
assert(new_capacity <= 1073741824);
do { do {
Dict__ctor(self, new_capacity); Dict__ctor(self, new_capacity);
@ -159,6 +158,9 @@ static bool Dict__set(Dict* self, py_TValue* key, py_TValue* val) {
if(res == -1) return false; // error if(res == -1) return false; // error
} }
// no empty slot found // no empty slot found
if(self->capacity >= self->entries.length * 8) {
return RuntimeError("dict has too much collision: %d/%d", self->entries.length, self->capacity);
}
Dict__rehash_2x(self); Dict__rehash_2x(self);
return Dict__set(self, key, val); return Dict__set(self, key, val);
} }

View File

@ -407,3 +407,10 @@ x, y = vec2(3.0, 4.0)
assert x == 3.0 and y == 4.0 assert x == 3.0 and y == 4.0
x, y, z = vec3(1.0, 2.0, 3.0) x, y, z = vec3(1.0, 2.0, 3.0)
assert x == 1.0 and y == 2.0 and z == 3.0 assert x == 1.0 and y == 2.0 and z == 3.0
d = {}
e = {}
for i in range(10000):
d[vec2i(i, 0)] = i
e[vec3i(i, 0, 0)] = i