blueloveTH hace 2 años
padre
commit
9f3d15ca51
Se han modificado 4 ficheros con 22 adiciones y 13 borrados
  1. 0 1
      include/pocketpy/namedict.h
  2. 2 2
      include/pocketpy/str.h
  3. 17 9
      src/str.cpp
  4. 3 1
      tests/80_linalg.py

+ 0 - 1
include/pocketpy/namedict.h

@@ -256,7 +256,6 @@ while(!_items[i].first.empty()) {           \
     }
 #undef HASH_PROBE_0
 #undef HASH_PROBE_1
-#undef _hash
 };
 
 template<typename V>

+ 2 - 2
include/pocketpy/str.h

@@ -3,7 +3,6 @@
 #include "common.h"
 #include "memory.h"
 #include "vector.h"
-#include <cstddef>
 
 namespace pkpy {
 
@@ -123,7 +122,8 @@ struct StrName {
     static bool is_valid(int index);
     static StrName get(std::string_view s);
     static std::map<std::string, uint16_t, std::less<>>& _interned();
-    static std::vector<std::string>& _r_interned();
+    static std::map<uint16_t, std::string>& _r_interned();
+    static uint32_t _pesudo_random_index;
 };
 
 struct FastStrStream{

+ 17 - 9
src/str.cpp

@@ -1,4 +1,7 @@
 #include "pocketpy/str.h"
+#include <_types/_uint16_t.h>
+#include <_types/_uint32_t.h>
+#include <stdexcept>
 
 namespace pkpy {
 
@@ -360,18 +363,24 @@ int utf8len(unsigned char c, bool suppress){
         return interned;
     }
 
-    std::vector<std::string>& StrName::_r_interned(){
-        static std::vector<std::string> r_interned;
+    std::map<uint16_t, std::string>& StrName::_r_interned(){
+        static std::map<uint16_t, std::string> r_interned;
         return r_interned;
     }
 
+    uint32_t StrName::_pesudo_random_index = 0;
+
     StrName StrName::get(std::string_view s){
         auto it = _interned().find(s);
         if(it != _interned().end()) return StrName(it->second);
-        uint16_t index = (uint16_t)(_r_interned().size() + 1);
-        std::string str(s);
-        _interned()[str] = index;
-        _r_interned().push_back(str);
+        // generate new index
+        // https://github.com/python/cpython/blob/3.12/Objects/dictobject.c#L175
+        uint16_t index = ((_pesudo_random_index*5) + 1) & 65535;
+        if(index == 0) throw std::runtime_error("StrName index overflow");
+        _interned()[std::string(s)] = index;
+        if(is_valid(index)) throw std::runtime_error("StrName index conflict");
+        _r_interned()[index] = std::string(s);
+        _pesudo_random_index = index;
         return StrName(index);
     }
 
@@ -380,8 +389,7 @@ int utf8len(unsigned char c, bool suppress){
     }
 
     bool StrName::is_valid(int index) {
-        // check _r_interned()[index-1] is valid
-        return index > 0 && index <= _r_interned().size();
+        return _r_interned().find(index) != _r_interned().end();
     }
 
     StrName::StrName(): index(0) {}
@@ -392,7 +400,7 @@ int utf8len(unsigned char c, bool suppress){
     }
 
     std::string_view StrName::sv() const {
-        const std::string& str = _r_interned()[index-1];
+        const std::string& str = _r_interned()[index];
         return std::string_view(str);
     }
 

+ 3 - 1
tests/80_linalg.py

@@ -85,7 +85,9 @@ assert str(static_test_vec4_int) == 'vec4(278, -1.39197e+13, 1.36422e+15, -37)'
 # test __getnewargs__
 element_name_list = [e for e in dir(test_vec4) if e in 'x,y,z,w']
 element_value_list = [getattr(test_vec4, attr) for attr in element_name_list]
-assert tuple(element_value_list) == test_vec4.__getnewargs__()
+_0 = tuple(element_value_list)
+_1 = test_vec4.__getnewargs__()
+assert (_0 == _1), (_0, _1)
 
 # test copy
 element_name_list = [e for e in dir(test_vec4) if e in 'x,y,z,w']