mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some refactor
This commit is contained in:
parent
9f3d15ca51
commit
92e4416c4e
@ -23,7 +23,6 @@ namespace pkpy {
|
||||
} \
|
||||
PyObject* type = vm->new_type_object(mod, #name, base); \
|
||||
T::_register(vm, mod, type); \
|
||||
type->attr()._try_perfect_rehash(); \
|
||||
return type; \
|
||||
}
|
||||
|
||||
|
@ -96,14 +96,6 @@ struct SmallNameDict{
|
||||
uint16_t capacity() const { return PK_SMALL_NAME_DICT_CAPACITY; }
|
||||
};
|
||||
|
||||
inline const uint16_t kHashSeeds[] = {9629, 43049, 13267, 59509, 39251, 1249, 27689, 9719, 19913};
|
||||
|
||||
inline uint16_t _hash(StrName key, uint16_t mask, uint16_t hash_seed){
|
||||
return ( (key).index * (hash_seed) >> 8 ) & (mask);
|
||||
}
|
||||
|
||||
uint16_t _find_perfect_hash_seed(uint16_t capacity, const std::vector<StrName>& keys);
|
||||
|
||||
template<typename T>
|
||||
struct LargeNameDict {
|
||||
PK_ALWAYS_PASS_BY_POINTER(LargeNameDict)
|
||||
@ -115,7 +107,6 @@ struct LargeNameDict {
|
||||
bool _is_small;
|
||||
float _load_factor;
|
||||
uint16_t _size;
|
||||
uint16_t _hash_seed;
|
||||
|
||||
uint16_t _capacity;
|
||||
uint16_t _critical_size;
|
||||
@ -125,7 +116,7 @@ struct LargeNameDict {
|
||||
|
||||
#define HASH_PROBE_1(key, ok, i) \
|
||||
ok = false; \
|
||||
i = _hash(key, _mask, _hash_seed); \
|
||||
i = key.index & _mask; \
|
||||
while(!_items[i].first.empty()) { \
|
||||
if(_items[i].first == (key)) { ok = true; break; } \
|
||||
i = (i + 1) & _mask; \
|
||||
@ -133,9 +124,8 @@ while(!_items[i].first.empty()) { \
|
||||
|
||||
#define HASH_PROBE_0 HASH_PROBE_1
|
||||
|
||||
LargeNameDict(float load_factor=kInstAttrLoadFactor): _is_small(false), _load_factor(load_factor), _size(0), _hash_seed(kHashSeeds[0]) {
|
||||
_set_capacity(kInitialCapacity);
|
||||
_alloc_items();
|
||||
LargeNameDict(float load_factor=kInstAttrLoadFactor): _is_small(false), _load_factor(load_factor), _size(0) {
|
||||
_set_capacity_and_alloc_items(kInitialCapacity);
|
||||
}
|
||||
|
||||
~LargeNameDict(){ free(_items); }
|
||||
@ -143,13 +133,11 @@ while(!_items[i].first.empty()) { \
|
||||
uint16_t size() const { return _size; }
|
||||
uint16_t capacity() const { return _capacity; }
|
||||
|
||||
void _set_capacity(uint16_t val){
|
||||
void _set_capacity_and_alloc_items(uint16_t val){
|
||||
_capacity = val;
|
||||
_critical_size = val * _load_factor;
|
||||
_mask = val - 1;
|
||||
}
|
||||
|
||||
void _alloc_items(){
|
||||
_items = (Item*)malloc(_capacity * sizeof(Item));
|
||||
memset(_items, 0, _capacity * sizeof(Item));
|
||||
}
|
||||
@ -160,7 +148,7 @@ while(!_items[i].first.empty()) { \
|
||||
if(!ok) {
|
||||
_size++;
|
||||
if(_size > _critical_size){
|
||||
_rehash(true);
|
||||
_rehash_2x();
|
||||
HASH_PROBE_1(key, ok, i);
|
||||
}
|
||||
_items[i].first = key;
|
||||
@ -168,13 +156,10 @@ while(!_items[i].first.empty()) { \
|
||||
_items[i].second = val;
|
||||
}
|
||||
|
||||
void _rehash(bool resize){
|
||||
void _rehash_2x(){
|
||||
Item* old_items = _items;
|
||||
uint16_t old_capacity = _capacity;
|
||||
if(resize){
|
||||
_set_capacity(_capacity * 2);
|
||||
}
|
||||
_alloc_items();
|
||||
_set_capacity_and_alloc_items(_capacity * 2);
|
||||
for(uint16_t i=0; i<old_capacity; i++){
|
||||
if(old_items[i].first.empty()) continue;
|
||||
bool ok; uint16_t j;
|
||||
@ -185,11 +170,6 @@ while(!_items[i].first.empty()) { \
|
||||
free(old_items);
|
||||
}
|
||||
|
||||
void _try_perfect_rehash(){
|
||||
_hash_seed = _find_perfect_hash_seed(_capacity, keys());
|
||||
_rehash(false); // do not resize
|
||||
}
|
||||
|
||||
T try_get(StrName key) const{
|
||||
bool ok; uint16_t i;
|
||||
HASH_PROBE_0(key, ok, i);
|
||||
@ -221,7 +201,7 @@ while(!_items[i].first.empty()) { \
|
||||
uint16_t pre_z = i;
|
||||
uint16_t z = (i + 1) & _mask;
|
||||
while(!_items[z].first.empty()){
|
||||
uint16_t h = _hash(_items[z].first, _mask, _hash_seed);
|
||||
uint16_t h = _items[z].first.index & _mask;
|
||||
if(h != i) break;
|
||||
std::swap(_items[pre_z], _items[z]);
|
||||
pre_z = z;
|
||||
@ -318,11 +298,6 @@ struct NameDictImpl{
|
||||
else _large.apply(func);
|
||||
}
|
||||
|
||||
void _try_perfect_rehash(){
|
||||
if(is_small()) return;
|
||||
_large._try_perfect_rehash();
|
||||
}
|
||||
|
||||
std::vector<StrName> keys() const{
|
||||
std::vector<StrName> v;
|
||||
apply([&](StrName key, V val){
|
||||
|
@ -660,7 +660,6 @@ __NEXT_STEP:;
|
||||
DISPATCH();
|
||||
TARGET(END_CLASS)
|
||||
_0 = POPX();
|
||||
_0->attr()._try_perfect_rehash();
|
||||
DISPATCH();
|
||||
TARGET(STORE_CLASS_ATTR){
|
||||
_name = StrName(byte.arg);
|
||||
|
@ -1,23 +1,4 @@
|
||||
#include "pocketpy/namedict.h"
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
uint16_t _find_perfect_hash_seed(uint16_t capacity, const std::vector<StrName>& keys){
|
||||
if(keys.empty()) return kHashSeeds[0];
|
||||
static std::set<uint16_t> indices;
|
||||
indices.clear();
|
||||
std::pair<uint16_t, float> best_score = {kHashSeeds[0], 0.0f};
|
||||
const int kHashSeedsSize = sizeof(kHashSeeds) / sizeof(kHashSeeds[0]);
|
||||
for(int i=0; i<kHashSeedsSize; i++){
|
||||
indices.clear();
|
||||
for(auto key: keys){
|
||||
uint16_t index = _hash(key, capacity-1, kHashSeeds[i]);
|
||||
indices.insert(index);
|
||||
}
|
||||
float score = indices.size() / (float)keys.size();
|
||||
if(score > best_score.second) best_score = {kHashSeeds[i], score};
|
||||
}
|
||||
return best_score.first;
|
||||
}
|
||||
|
||||
} // namespace pkpy
|
@ -295,7 +295,6 @@ namespace pkpy{
|
||||
path_cpnts.pop_back();
|
||||
PyObject* new_mod = new_module(name_cpnt, f_join(path_cpnts));
|
||||
_exec(code, new_mod);
|
||||
new_mod->attr()._try_perfect_rehash();
|
||||
return new_mod;
|
||||
}
|
||||
|
||||
@ -693,10 +692,6 @@ void VM::init_builtin_types(){
|
||||
builtins->attr().set("slice", _t(tp_slice));
|
||||
|
||||
post_init();
|
||||
for(int i=0; i<_all_types.size(); i++){
|
||||
_all_types[i].obj->attr()._try_perfect_rehash();
|
||||
}
|
||||
for(auto [k, v]: _modules.items()) v->attr()._try_perfect_rehash();
|
||||
this->_main = new_module("__main__");
|
||||
}
|
||||
|
||||
|
@ -83,14 +83,14 @@ assert str(static_test_vec4_float) == 'vec4(3.1887, -1.0984e+06, 9, 4.5654e+12)'
|
||||
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_name_list = ['x', 'y', 'z', 'w']
|
||||
element_value_list = [getattr(test_vec4, attr) for attr in element_name_list]
|
||||
_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']
|
||||
element_name_list = ['x', 'y', 'z', 'w']
|
||||
element_value_list = [getattr(test_vec4, attr) for attr in element_name_list]
|
||||
copy_element_value_list = [getattr(test_vec4.copy(), attr) for attr in element_name_list]
|
||||
assert element_value_list == copy_element_value_list
|
||||
|
Loading…
x
Reference in New Issue
Block a user