blueloveTH 2 лет назад
Родитель
Сommit
17fd51b967
1 измененных файлов с 24 добавлено и 30 удалено
  1. 24 30
      include/pocketpy/namedict.h

+ 24 - 30
include/pocketpy/namedict.h

@@ -28,15 +28,17 @@ struct SmallNameDict{
     SmallNameDict(): _is_small(true), _size(0) {}
 
     bool try_set(K key, V val){
+        int slot = -1;
         for(int i=0; i<kCapacity; i++){
             if(_keys[i] == key){
                 _values[i] = val;
                 return true;
             }
+            if(_keys[i].empty()) slot = i;
         }
-        if(_size == kCapacity) return false;
-        _keys[_size] = key;
-        _values[_size] = val;
+        if(slot == -1) return false;
+        _keys[slot] = key;
+        _values[slot] = val;
         _size++;
         return true;
     }
@@ -45,7 +47,7 @@ struct SmallNameDict{
         for(int i=0; i<kCapacity; 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 {
@@ -108,16 +110,21 @@ uint16_t _find_perfect_hash_seed(uint16_t capacity, const std::vector<StrName>&
 
 template<typename T>
 struct LargeNameDict {
+    PK_ALWAYS_PASS_BY_POINTER(LargeNameDict)
+
     using Item = std::pair<StrName, T>;
-    static constexpr uint16_t __Capacity = 32;
+    static constexpr uint16_t kInitialCapacity = 32;
     static_assert(is_pod<T>::value);
 
     bool _is_small;
     float _load_factor;
-    uint16_t _capacity;
     uint16_t _size;
     uint16_t _hash_seed;
+
+    uint16_t _capacity;
+    uint16_t _critical_size;
     uint16_t _mask;
+
     Item* _items;
 
 #define HASH_PROBE_0(key, ok, i)            \
@@ -144,38 +151,26 @@ while(!_items[i].first.empty()) {           \
     _items = (Item*)malloc(_capacity * sizeof(Item));    \
     memset(_items, 0, _capacity * sizeof(Item));                \
 
-    LargeNameDict(float load_factor=kInstAttrLoadFactor):
-        _is_small(false),
-        _load_factor(load_factor), _capacity(__Capacity), _size(0), 
-        _hash_seed(kHashSeeds[0]), _mask(__Capacity-1) {
-        NAMEDICT_ALLOC()
-    }
-
-    LargeNameDict(const LargeNameDict& other) {
-        memcpy(this, &other, sizeof(LargeNameDict));
+    LargeNameDict(float load_factor=kInstAttrLoadFactor): _is_small(false), _load_factor(load_factor), _size(0), _hash_seed(kHashSeeds[0]) {
+        _set_capacity(kInitialCapacity);
         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(LargeNameDict&&) = delete;
-    LargeNameDict& operator=(LargeNameDict&&) = delete;
     uint16_t size() const { return _size; }
     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 {
         bool ok; uint16_t 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;
     }
 
@@ -184,7 +179,7 @@ while(!_items[i].first.empty()) {           \
         HASH_PROBE_1(key, ok, i);
         if(!ok) {
             _size++;
-            if(_size > _capacity*_load_factor){
+            if(_size > _critical_size){
                 _rehash(true);
                 HASH_PROBE_1(key, ok, i);
             }
@@ -197,8 +192,7 @@ while(!_items[i].first.empty()) {           \
         Item* old_items = _items;
         uint16_t old_capacity = _capacity;
         if(resize){
-            _capacity *= 2;
-            _mask = _capacity - 1;
+            _set_capacity(_capacity * 2);
         }
         NAMEDICT_ALLOC()
         for(uint16_t i=0; i<old_capacity; i++){