From 9f3d15ca515027f609cdc16e0e6f1e0da84d6850 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Fri, 13 Oct 2023 12:18:33 +0800 Subject: [PATCH] ... --- include/pocketpy/namedict.h | 1 - include/pocketpy/str.h | 4 ++-- src/str.cpp | 26 +++++++++++++++++--------- tests/80_linalg.py | 4 +++- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/include/pocketpy/namedict.h b/include/pocketpy/namedict.h index 4934a9b4..f042d327 100644 --- a/include/pocketpy/namedict.h +++ b/include/pocketpy/namedict.h @@ -256,7 +256,6 @@ while(!_items[i].first.empty()) { \ } #undef HASH_PROBE_0 #undef HASH_PROBE_1 -#undef _hash }; template diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index 2f387aa1..17e6b7c9 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -3,7 +3,6 @@ #include "common.h" #include "memory.h" #include "vector.h" -#include namespace pkpy { @@ -123,7 +122,8 @@ struct StrName { static bool is_valid(int index); static StrName get(std::string_view s); static std::map>& _interned(); - static std::vector& _r_interned(); + static std::map& _r_interned(); + static uint32_t _pesudo_random_index; }; struct FastStrStream{ diff --git a/src/str.cpp b/src/str.cpp index 0738487d..e82d8e25 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -1,4 +1,7 @@ #include "pocketpy/str.h" +#include <_types/_uint16_t.h> +#include <_types/_uint32_t.h> +#include namespace pkpy { @@ -360,18 +363,24 @@ int utf8len(unsigned char c, bool suppress){ return interned; } - std::vector& StrName::_r_interned(){ - static std::vector r_interned; + std::map& StrName::_r_interned(){ + static std::map 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); } diff --git a/tests/80_linalg.py b/tests/80_linalg.py index 77c2aee6..5f1b61ed 100644 --- a/tests/80_linalg.py +++ b/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']