From b31795bf83f01827ec617212e84fb7d96b3e6711 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 23 Nov 2024 01:53:56 +0800 Subject: [PATCH] fix `vec2i.__hash__` --- src/modules/linalg.c | 7 ++++--- src/public/py_dict.c | 4 +++- tests/80_linalg.py | 7 +++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/modules/linalg.c b/src/modules/linalg.c index 3dcc337d..d582e158 100644 --- a/src/modules/linalg.c +++ b/src/modules/linalg.c @@ -301,11 +301,12 @@ DEF_VECTOR_OPS(3) } \ static bool vec##D##i##__hash__(int argc, py_Ref argv) { \ PY_CHECK_ARGC(1); \ + const uint32_t C = 2654435761; \ 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++) \ - hash = hash * 31 + v.data[i]; \ - py_newint(py_retval(), hash); \ + hash = hash * 31 + (uint32_t)v.data[i] * C; \ + py_newint(py_retval(), (py_i64)hash); \ return true; \ } diff --git a/src/public/py_dict.c b/src/public/py_dict.c index 04619000..b45678fa 100644 --- a/src/public/py_dict.c +++ b/src/public/py_dict.c @@ -74,7 +74,6 @@ static void Dict__rehash_2x(Dict* self) { Dict old_dict = *self; int new_capacity = self->capacity * 2; - assert(new_capacity <= 1073741824); do { 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 } // 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); return Dict__set(self, key, val); } diff --git a/tests/80_linalg.py b/tests/80_linalg.py index 97a1bdb2..cb9da505 100644 --- a/tests/80_linalg.py +++ b/tests/80_linalg.py @@ -407,3 +407,10 @@ x, y = vec2(3.0, 4.0) assert x == 3.0 and y == 4.0 x, y, z = vec3(1.0, 2.0, 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 \ No newline at end of file