mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some refactor
This commit is contained in:
parent
2616c8378b
commit
ac82f6f33f
@ -11,17 +11,12 @@ struct Dict{
|
|||||||
struct Item{
|
struct Item{
|
||||||
PyVar first;
|
PyVar first;
|
||||||
PyVar second;
|
PyVar second;
|
||||||
};
|
|
||||||
|
|
||||||
struct ItemNode{
|
|
||||||
int prev;
|
int prev;
|
||||||
int next;
|
int next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int __Capacity = 4;
|
static constexpr int __Capacity = 8;
|
||||||
static constexpr float __LoadFactor = 0.67f;
|
static constexpr float __LoadFactor = 0.67f;
|
||||||
static_assert(sizeof(Item) * __Capacity <= 128);
|
|
||||||
static_assert(sizeof(ItemNode) * __Capacity <= 64);
|
|
||||||
|
|
||||||
int _capacity;
|
int _capacity;
|
||||||
int _mask;
|
int _mask;
|
||||||
@ -30,7 +25,6 @@ struct Dict{
|
|||||||
int _head_idx; // for order preserving
|
int _head_idx; // for order preserving
|
||||||
int _tail_idx; // for order preserving
|
int _tail_idx; // for order preserving
|
||||||
Item* _items;
|
Item* _items;
|
||||||
ItemNode* _nodes; // for order preserving
|
|
||||||
|
|
||||||
Dict();
|
Dict();
|
||||||
Dict(Dict&& other);
|
Dict(Dict&& other);
|
||||||
@ -49,7 +43,7 @@ struct Dict{
|
|||||||
PyVar try_get(VM* vm, PyVar key) const;
|
PyVar try_get(VM* vm, PyVar key) const;
|
||||||
|
|
||||||
bool contains(VM* vm, PyVar key) const;
|
bool contains(VM* vm, PyVar key) const;
|
||||||
bool erase(VM* vm, PyVar key);
|
bool del(VM* vm, PyVar key);
|
||||||
void update(VM* vm, const Dict& other);
|
void update(VM* vm, const Dict& other);
|
||||||
|
|
||||||
template<typename __Func>
|
template<typename __Func>
|
||||||
@ -57,7 +51,7 @@ struct Dict{
|
|||||||
int i = _head_idx;
|
int i = _head_idx;
|
||||||
while(i != -1){
|
while(i != -1){
|
||||||
f(_items[i].first, _items[i].second);
|
f(_items[i].first, _items[i].second);
|
||||||
i = _nodes[i].next;
|
i = _items[i].next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +60,8 @@ struct Dict{
|
|||||||
void clear();
|
void clear();
|
||||||
~Dict();
|
~Dict();
|
||||||
|
|
||||||
|
void __alloc_items();
|
||||||
|
|
||||||
void _gc_mark(VM*) const;
|
void _gc_mark(VM*) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,17 +4,8 @@
|
|||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
void* pool64_alloc(size_t) noexcept;
|
|
||||||
void pool64_dealloc(void*) noexcept;
|
|
||||||
|
|
||||||
void* pool128_alloc(size_t) noexcept;
|
void* pool128_alloc(size_t) noexcept;
|
||||||
void pool128_dealloc(void*) noexcept;
|
void pool128_dealloc(void*) noexcept;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void* pool64_alloc() noexcept{
|
|
||||||
return pool64_alloc(sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void* pool128_alloc() noexcept{
|
void* pool128_alloc() noexcept{
|
||||||
return pool128_alloc(sizeof(T));
|
return pool128_alloc(sizeof(T));
|
||||||
|
72
src/dict.cpp
72
src/dict.cpp
@ -5,10 +5,17 @@ namespace pkpy{
|
|||||||
Dict::Dict(): _capacity(__Capacity),
|
Dict::Dict(): _capacity(__Capacity),
|
||||||
_mask(__Capacity-1),
|
_mask(__Capacity-1),
|
||||||
_size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){
|
_size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){
|
||||||
_items = (Item*)pool128_alloc(_capacity * sizeof(Item));
|
__alloc_items();
|
||||||
memset(_items, 0, _capacity * sizeof(Item));
|
}
|
||||||
_nodes = (ItemNode*)pool64_alloc(_capacity * sizeof(ItemNode));
|
|
||||||
memset(_nodes, -1, _capacity * sizeof(ItemNode));
|
void Dict::__alloc_items(){
|
||||||
|
_items = (Item*)malloc(_capacity * sizeof(Item));
|
||||||
|
for(int i=0; i<_capacity; i++){
|
||||||
|
_items[i].first = nullptr;
|
||||||
|
_items[i].second = nullptr;
|
||||||
|
_items[i].prev = -1;
|
||||||
|
_items[i].next = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dict::Dict(Dict&& other){
|
Dict::Dict(Dict&& other){
|
||||||
@ -19,9 +26,7 @@ namespace pkpy{
|
|||||||
_head_idx = other._head_idx;
|
_head_idx = other._head_idx;
|
||||||
_tail_idx = other._tail_idx;
|
_tail_idx = other._tail_idx;
|
||||||
_items = other._items;
|
_items = other._items;
|
||||||
_nodes = other._nodes;
|
|
||||||
other._items = nullptr;
|
other._items = nullptr;
|
||||||
other._nodes = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Dict::Dict(const Dict& other){
|
Dict::Dict(const Dict& other){
|
||||||
@ -31,10 +36,9 @@ namespace pkpy{
|
|||||||
_critical_size = other._critical_size;
|
_critical_size = other._critical_size;
|
||||||
_head_idx = other._head_idx;
|
_head_idx = other._head_idx;
|
||||||
_tail_idx = other._tail_idx;
|
_tail_idx = other._tail_idx;
|
||||||
_items = (Item*)pool128_alloc(_capacity * sizeof(Item));
|
// copy items
|
||||||
|
_items = (Item*)malloc(_capacity * sizeof(Item));
|
||||||
memcpy(_items, other._items, _capacity * sizeof(Item));
|
memcpy(_items, other._items, _capacity * sizeof(Item));
|
||||||
_nodes = (ItemNode*)pool64_alloc(_capacity * sizeof(ItemNode));
|
|
||||||
memcpy(_nodes, other._nodes, _capacity * sizeof(ItemNode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dict::set(VM* vm, PyVar key, PyVar val){
|
void Dict::set(VM* vm, PyVar key, PyVar val){
|
||||||
@ -51,8 +55,8 @@ namespace pkpy{
|
|||||||
_head_idx = i;
|
_head_idx = i;
|
||||||
_tail_idx = i;
|
_tail_idx = i;
|
||||||
}else{
|
}else{
|
||||||
_nodes[i].prev = _tail_idx;
|
_items[i].prev = _tail_idx;
|
||||||
_nodes[_tail_idx].next = i;
|
_items[_tail_idx].next = i;
|
||||||
_tail_idx = i;
|
_tail_idx = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,7 +65,6 @@ namespace pkpy{
|
|||||||
|
|
||||||
void Dict::_rehash(VM* vm){
|
void Dict::_rehash(VM* vm){
|
||||||
Item* old_items = _items;
|
Item* old_items = _items;
|
||||||
ItemNode* old_nodes = _nodes;
|
|
||||||
int old_head_idx = _head_idx;
|
int old_head_idx = _head_idx;
|
||||||
|
|
||||||
_capacity *= 4;
|
_capacity *= 4;
|
||||||
@ -71,19 +74,16 @@ namespace pkpy{
|
|||||||
_head_idx = -1;
|
_head_idx = -1;
|
||||||
_tail_idx = -1;
|
_tail_idx = -1;
|
||||||
|
|
||||||
_items = (Item*)pool128_alloc(_capacity * sizeof(Item));
|
__alloc_items();
|
||||||
memset(_items, 0, _capacity * sizeof(Item));
|
|
||||||
_nodes = (ItemNode*)pool64_alloc(_capacity * sizeof(ItemNode));
|
|
||||||
memset(_nodes, -1, _capacity * sizeof(ItemNode));
|
|
||||||
|
|
||||||
// copy old items to new dict
|
// copy old items to new dict
|
||||||
int i = old_head_idx;
|
int i = old_head_idx;
|
||||||
while(i != -1){
|
while(i != -1){
|
||||||
set(vm, old_items[i].first, old_items[i].second);
|
set(vm, old_items[i].first, old_items[i].second);
|
||||||
i = old_nodes[i].next;
|
i = old_items[i].next;
|
||||||
}
|
}
|
||||||
pool128_dealloc(old_items);
|
|
||||||
pool64_dealloc(old_nodes);
|
free(old_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ namespace pkpy{
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dict::erase(VM* vm, PyVar key){
|
bool Dict::del(VM* vm, PyVar key){
|
||||||
bool ok; int i;
|
bool ok; int i;
|
||||||
_probe_0(vm, key, ok, i);
|
_probe_0(vm, key, ok, i);
|
||||||
if(!ok) return false;
|
if(!ok) return false;
|
||||||
@ -113,18 +113,18 @@ namespace pkpy{
|
|||||||
_tail_idx = -1;
|
_tail_idx = -1;
|
||||||
}else{
|
}else{
|
||||||
if(_head_idx == i){
|
if(_head_idx == i){
|
||||||
_head_idx = _nodes[i].next;
|
_head_idx = _items[i].next;
|
||||||
_nodes[_head_idx].prev = -1;
|
_items[_head_idx].prev = -1;
|
||||||
}else if(_tail_idx == i){
|
}else if(_tail_idx == i){
|
||||||
_tail_idx = _nodes[i].prev;
|
_tail_idx = _items[i].prev;
|
||||||
_nodes[_tail_idx].next = -1;
|
_items[_tail_idx].next = -1;
|
||||||
}else{
|
}else{
|
||||||
_nodes[_nodes[i].prev].next = _nodes[i].next;
|
_items[_items[i].prev].next = _items[i].next;
|
||||||
_nodes[_nodes[i].next].prev = _nodes[i].prev;
|
_items[_items[i].next].prev = _items[i].prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_nodes[i].prev = -1;
|
_items[i].prev = -1;
|
||||||
_nodes[i].next = -1;
|
_items[i].next = -1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ namespace pkpy{
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
while(i != -1){
|
while(i != -1){
|
||||||
t[j++] = _items[i].first;
|
t[j++] = _items[i].first;
|
||||||
i = _nodes[i].next;
|
i = _items[i].next;
|
||||||
}
|
}
|
||||||
PK_ASSERT(j == _size);
|
PK_ASSERT(j == _size);
|
||||||
return t;
|
return t;
|
||||||
@ -150,7 +150,7 @@ namespace pkpy{
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
while(i != -1){
|
while(i != -1){
|
||||||
t[j++] = _items[i].second;
|
t[j++] = _items[i].second;
|
||||||
i = _nodes[i].next;
|
i = _items[i].next;
|
||||||
}
|
}
|
||||||
PK_ASSERT(j == _size);
|
PK_ASSERT(j == _size);
|
||||||
return t;
|
return t;
|
||||||
@ -160,13 +160,15 @@ namespace pkpy{
|
|||||||
_size = 0;
|
_size = 0;
|
||||||
_head_idx = -1;
|
_head_idx = -1;
|
||||||
_tail_idx = -1;
|
_tail_idx = -1;
|
||||||
memset(_items, 0, _capacity * sizeof(Item));
|
for(int i=0; i<_capacity; i++){
|
||||||
memset(_nodes, -1, _capacity * sizeof(ItemNode));
|
_items[i].first = nullptr;
|
||||||
|
_items[i].second = nullptr;
|
||||||
|
_items[i].prev = -1;
|
||||||
|
_items[i].next = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dict::~Dict(){
|
Dict::~Dict(){
|
||||||
if(_items==nullptr) return;
|
if(_items) free(_items);
|
||||||
pool128_dealloc(_items);
|
|
||||||
pool64_dealloc(_nodes);
|
|
||||||
}
|
}
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -118,7 +118,7 @@ namespace pkpy{
|
|||||||
if(self.i == -1) return 0;
|
if(self.i == -1) return 0;
|
||||||
vm->s_data.push(d._items[self.i].first);
|
vm->s_data.push(d._items[self.i].first);
|
||||||
vm->s_data.push(d._items[self.i].second);
|
vm->s_data.push(d._items[self.i].second);
|
||||||
self.i = d._nodes[self.i].next;
|
self.i = d._items[self.i].next;
|
||||||
return 2;
|
return 2;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -267,21 +267,17 @@ struct MemoryPool{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static MemoryPool<64> pool64;
|
|
||||||
static MemoryPool<128> pool128;
|
static MemoryPool<128> pool128;
|
||||||
|
|
||||||
void* pool64_alloc(size_t size) noexcept { return pool64.alloc(size); }
|
|
||||||
void pool64_dealloc(void* p) noexcept { pool64.dealloc(p); }
|
|
||||||
|
|
||||||
void* pool128_alloc(size_t size) noexcept { return pool128.alloc(size); }
|
void* pool128_alloc(size_t size) noexcept { return pool128.alloc(size); }
|
||||||
void pool128_dealloc(void* p) noexcept { pool128.dealloc(p); }
|
void pool128_dealloc(void* p) noexcept { pool128.dealloc(p); }
|
||||||
|
|
||||||
void pools_shrink_to_fit() noexcept {
|
void pools_shrink_to_fit() noexcept {
|
||||||
pool64.shrink_to_fit();
|
|
||||||
pool128.shrink_to_fit();
|
pool128.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pool64_info() noexcept { return pool64.info(); }
|
std::string pool64_info() noexcept { return "unavailable"; }
|
||||||
std::string pool128_info() noexcept { return pool128.info(); }
|
std::string pool128_info() noexcept { return pool128.info(); }
|
||||||
|
|
||||||
}
|
}
|
@ -1345,7 +1345,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
_vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
|
_vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
|
||||||
Dict& self = _CAST(Dict&, _0);
|
Dict& self = _CAST(Dict&, _0);
|
||||||
bool ok = self.erase(vm, _1);
|
bool ok = self.del(vm, _1);
|
||||||
if(!ok) vm->KeyError(_1);
|
if(!ok) vm->KeyError(_1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1362,7 +1362,7 @@ void __init_builtins(VM* _vm) {
|
|||||||
return args[2];
|
return args[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.erase(vm, args[1]);
|
self.del(vm, args[1]);
|
||||||
return value;
|
return value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user