blueloveTH 1 год назад
Родитель
Сommit
b31795bf83
3 измененных файлов с 14 добавлено и 4 удалено
  1. 4 3
      src/modules/linalg.c
  2. 3 1
      src/public/py_dict.c
  3. 7 0
      tests/80_linalg.py

+ 4 - 3
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;                                                                               \
     }
 

+ 3 - 1
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);
 }

+ 7 - 0
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