#include "pocketpy/dict.h" namespace pkpy{ Dict::Dict(VM* vm): vm(vm), _capacity(__Capacity), _mask(__Capacity-1), _size(0), _critical_size(__Capacity*__LoadFactor+0.5f), _head_idx(-1), _tail_idx(-1){ _items = (Item*)pool128.alloc(_capacity * sizeof(Item)); memset(_items, 0, _capacity * sizeof(Item)); _nodes = (ItemNode*)pool64.alloc(_capacity * sizeof(ItemNode)); memset(_nodes, -1, _capacity * sizeof(ItemNode)); } Dict::Dict(Dict&& other){ vm = other.vm; _capacity = other._capacity; _mask = other._mask; _size = other._size; _critical_size = other._critical_size; _head_idx = other._head_idx; _tail_idx = other._tail_idx; _items = other._items; _nodes = other._nodes; other._items = nullptr; other._nodes = nullptr; } Dict::Dict(const Dict& other){ vm = other.vm; _capacity = other._capacity; _mask = other._mask; _size = other._size; _critical_size = other._critical_size; _head_idx = other._head_idx; _tail_idx = other._tail_idx; _items = (Item*)pool128.alloc(_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(PyObject* key, PyObject* val){ // do possible rehash if(_size+1 > _critical_size) _rehash(); bool ok; int i; _probe(key, ok, i); if(!ok) { _size++; _items[i].first = key; // append to tail if(_size == 0+1){ _head_idx = i; _tail_idx = i; }else{ _nodes[i].prev = _tail_idx; _nodes[_tail_idx].next = i; _tail_idx = i; } } _items[i].second = val; } void Dict::_rehash(){ Item* old_items = _items; int old_capacity = _capacity; _capacity *= 2; _mask = _capacity - 1; _size = 0; _critical_size = _capacity*__LoadFactor+0.5f; _head_idx = -1; _tail_idx = -1; pool64.dealloc(_nodes); _items = (Item*)pool128.alloc(_capacity * sizeof(Item)); memset(_items, 0, _capacity * sizeof(Item)); _nodes = (ItemNode*)pool64.alloc(_capacity * sizeof(ItemNode)); memset(_nodes, -1, _capacity * sizeof(ItemNode)); for(int i=0; i