mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-06 18:20:17 +00:00
...
This commit is contained in:
parent
9164fc8e2f
commit
17fd51b967
@ -28,15 +28,17 @@ struct SmallNameDict{
|
|||||||
SmallNameDict(): _is_small(true), _size(0) {}
|
SmallNameDict(): _is_small(true), _size(0) {}
|
||||||
|
|
||||||
bool try_set(K key, V val){
|
bool try_set(K key, V val){
|
||||||
|
int slot = -1;
|
||||||
for(int i=0; i<kCapacity; i++){
|
for(int i=0; i<kCapacity; i++){
|
||||||
if(_keys[i] == key){
|
if(_keys[i] == key){
|
||||||
_values[i] = val;
|
_values[i] = val;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if(_keys[i].empty()) slot = i;
|
||||||
}
|
}
|
||||||
if(_size == kCapacity) return false;
|
if(slot == -1) return false;
|
||||||
_keys[_size] = key;
|
_keys[slot] = key;
|
||||||
_values[_size] = val;
|
_values[slot] = val;
|
||||||
_size++;
|
_size++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -45,7 +47,7 @@ struct SmallNameDict{
|
|||||||
for(int i=0; i<kCapacity; i++){
|
for(int i=0; i<kCapacity; i++){
|
||||||
if(_keys[i] == key) return _values[i];
|
if(_keys[i] == key) return _values[i];
|
||||||
}
|
}
|
||||||
throw std::out_of_range(fmt("SmallDict key not found: ", key));
|
throw std::out_of_range(fmt("SmallNameDict key not found: ", key));
|
||||||
}
|
}
|
||||||
|
|
||||||
V try_get(K key) const {
|
V try_get(K key) const {
|
||||||
@ -108,16 +110,21 @@ uint16_t _find_perfect_hash_seed(uint16_t capacity, const std::vector<StrName>&
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct LargeNameDict {
|
struct LargeNameDict {
|
||||||
|
PK_ALWAYS_PASS_BY_POINTER(LargeNameDict)
|
||||||
|
|
||||||
using Item = std::pair<StrName, T>;
|
using Item = std::pair<StrName, T>;
|
||||||
static constexpr uint16_t __Capacity = 32;
|
static constexpr uint16_t kInitialCapacity = 32;
|
||||||
static_assert(is_pod<T>::value);
|
static_assert(is_pod<T>::value);
|
||||||
|
|
||||||
bool _is_small;
|
bool _is_small;
|
||||||
float _load_factor;
|
float _load_factor;
|
||||||
uint16_t _capacity;
|
|
||||||
uint16_t _size;
|
uint16_t _size;
|
||||||
uint16_t _hash_seed;
|
uint16_t _hash_seed;
|
||||||
|
|
||||||
|
uint16_t _capacity;
|
||||||
|
uint16_t _critical_size;
|
||||||
uint16_t _mask;
|
uint16_t _mask;
|
||||||
|
|
||||||
Item* _items;
|
Item* _items;
|
||||||
|
|
||||||
#define HASH_PROBE_0(key, ok, i) \
|
#define HASH_PROBE_0(key, ok, i) \
|
||||||
@ -144,38 +151,26 @@ while(!_items[i].first.empty()) { \
|
|||||||
_items = (Item*)malloc(_capacity * sizeof(Item)); \
|
_items = (Item*)malloc(_capacity * sizeof(Item)); \
|
||||||
memset(_items, 0, _capacity * sizeof(Item)); \
|
memset(_items, 0, _capacity * sizeof(Item)); \
|
||||||
|
|
||||||
LargeNameDict(float load_factor=kInstAttrLoadFactor):
|
LargeNameDict(float load_factor=kInstAttrLoadFactor): _is_small(false), _load_factor(load_factor), _size(0), _hash_seed(kHashSeeds[0]) {
|
||||||
_is_small(false),
|
_set_capacity(kInitialCapacity);
|
||||||
_load_factor(load_factor), _capacity(__Capacity), _size(0),
|
|
||||||
_hash_seed(kHashSeeds[0]), _mask(__Capacity-1) {
|
|
||||||
NAMEDICT_ALLOC()
|
NAMEDICT_ALLOC()
|
||||||
}
|
}
|
||||||
|
|
||||||
LargeNameDict(const LargeNameDict& other) {
|
|
||||||
memcpy(this, &other, sizeof(LargeNameDict));
|
|
||||||
NAMEDICT_ALLOC()
|
|
||||||
for(int i=0; i<_capacity; i++) _items[i] = other._items[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
LargeNameDict& operator=(const LargeNameDict& other) {
|
|
||||||
free(_items);
|
|
||||||
memcpy(this, &other, sizeof(LargeNameDict));
|
|
||||||
NAMEDICT_ALLOC()
|
|
||||||
for(int i=0; i<_capacity; i++) _items[i] = other._items[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~LargeNameDict(){ free(_items); }
|
~LargeNameDict(){ free(_items); }
|
||||||
|
|
||||||
LargeNameDict(LargeNameDict&&) = delete;
|
|
||||||
LargeNameDict& operator=(LargeNameDict&&) = delete;
|
|
||||||
uint16_t size() const { return _size; }
|
uint16_t size() const { return _size; }
|
||||||
uint16_t capacity() const { return _capacity; }
|
uint16_t capacity() const { return _capacity; }
|
||||||
|
|
||||||
|
void _set_capacity(uint16_t val){
|
||||||
|
_capacity = val;
|
||||||
|
_critical_size = val * _load_factor;
|
||||||
|
_mask = val - 1;
|
||||||
|
}
|
||||||
|
|
||||||
T operator[](StrName key) const {
|
T operator[](StrName key) const {
|
||||||
bool ok; uint16_t i;
|
bool ok; uint16_t i;
|
||||||
HASH_PROBE_0(key, ok, i);
|
HASH_PROBE_0(key, ok, i);
|
||||||
if(!ok) throw std::out_of_range(fmt("NameDict key not found: ", key));
|
if(!ok) throw std::out_of_range(fmt("LargeNameDict key not found: ", key));
|
||||||
return _items[i].second;
|
return _items[i].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +179,7 @@ while(!_items[i].first.empty()) { \
|
|||||||
HASH_PROBE_1(key, ok, i);
|
HASH_PROBE_1(key, ok, i);
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
_size++;
|
_size++;
|
||||||
if(_size > _capacity*_load_factor){
|
if(_size > _critical_size){
|
||||||
_rehash(true);
|
_rehash(true);
|
||||||
HASH_PROBE_1(key, ok, i);
|
HASH_PROBE_1(key, ok, i);
|
||||||
}
|
}
|
||||||
@ -197,8 +192,7 @@ while(!_items[i].first.empty()) { \
|
|||||||
Item* old_items = _items;
|
Item* old_items = _items;
|
||||||
uint16_t old_capacity = _capacity;
|
uint16_t old_capacity = _capacity;
|
||||||
if(resize){
|
if(resize){
|
||||||
_capacity *= 2;
|
_set_capacity(_capacity * 2);
|
||||||
_mask = _capacity - 1;
|
|
||||||
}
|
}
|
||||||
NAMEDICT_ALLOC()
|
NAMEDICT_ALLOC()
|
||||||
for(uint16_t i=0; i<old_capacity; i++){
|
for(uint16_t i=0; i<old_capacity; i++){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user