diff --git a/src/cmc/deque.h b/src/cmc/deque.h index 4ade839..af92d11 100644 --- a/src/cmc/deque.h +++ b/src/cmc/deque.h @@ -120,7 +120,6 @@ struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ void CMC_(PFX, _clear)(struct SNAME * _deque_); \ void CMC_(PFX, _free)(struct SNAME * _deque_); \ - void CMC_(PFX, _release)(struct SNAME _deque_); \ /* Customization of Allocation and Callbacks */ \ void CMC_(PFX, _customize)(struct SNAME * _deque_, \ struct cmc_alloc_node * alloc, \ @@ -234,21 +233,6 @@ _deque_->alloc->free(_deque_); \ } \ \ - void CMC_(PFX, _release)(struct SNAME _deque_) \ - { \ - if (_deque_.f_val->free) \ - { \ - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ - { \ - _deque_.f_val->free(_deque_.buffer[i]); \ - \ - i = (i + 1) % _deque_.capacity; \ - } \ - } \ - \ - _deque_.alloc->free(_deque_.buffer); \ - } \ - \ void CMC_(PFX, _customize)(struct SNAME * _deque_, \ struct cmc_alloc_node * alloc, \ struct cmc_callbacks * callbacks) \ diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index e768b2c..a122669 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -154,7 +154,6 @@ struct cmc_callbacks * callbacks); \ void CMC_(PFX, _clear)(struct SNAME * _map_); \ void CMC_(PFX, _free)(struct SNAME * _map_); \ - void CMC_(PFX, _release)(struct SNAME _map_); \ /* Customization of Allocation and Callbacks */ \ void CMC_(PFX, _customize)(struct SNAME * _map_, \ struct cmc_alloc_node * alloc, \ @@ -294,27 +293,6 @@ _map_->alloc->free(_map_); \ } \ \ - void CMC_(PFX, _release)(struct SNAME _map_) \ - { \ - if (_map_.f_key->free || _map_.f_val->free) \ - { \ - for (size_t i = 0; i < _map_.capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \ - \ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_.f_key->free) \ - _map_.f_key->free(entry->key); \ - if (_map_.f_val->free) \ - _map_.f_val->free(entry->value); \ - } \ - } \ - } \ - \ - _map_.alloc->free(_map_.buffer); \ - } \ - \ void CMC_(PFX, _customize)(struct SNAME * _map_, \ struct cmc_alloc_node * alloc, \ struct cmc_callbacks * callbacks) \ @@ -472,23 +450,29 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + K max_key; \ + V max_val; \ + size_t first = 0; \ \ - K max_key = CMC_(PFX, _iter_key)(&iter); \ - V max_val = CMC_(PFX, _iter_value)(&iter); \ - \ - CMC_(PFX, _iter_next)(&iter); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (; first < _map_->capacity; first++) \ { \ - K iter_key = CMC_(PFX, _iter_key)(&iter); \ - V iter_val = CMC_(PFX, _iter_value)(&iter); \ - \ - if (_map_->f_key->cmp(iter_key, max_key) > 0) \ + if (_map_->buffer[first].state == CMC_ES_FILLED) \ { \ - max_key = iter_key; \ - max_val = iter_val; \ + max_key = _map_->buffer[first].key; \ + max_val = _map_->buffer[first].value; \ + break; \ + } \ + } \ + \ + for (size_t i = first + 1; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ + { \ + max_key = _map_->buffer[first].key; \ + max_val = _map_->buffer[first].value; \ + } \ } \ } \ \ @@ -511,23 +495,29 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ + K min_key; \ + V min_val; \ + size_t first = 0; \ \ - K min_key = CMC_(PFX, _iter_key)(&iter); \ - V min_val = CMC_(PFX, _iter_value)(&iter); \ - \ - CMC_(PFX, _iter_next)(&iter); \ - \ - /* TODO Turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (; first < _map_->capacity; first++) \ { \ - K iter_key = CMC_(PFX, _iter_key)(&iter); \ - V iter_val = CMC_(PFX, _iter_value)(&iter); \ - \ - if (_map_->f_key->cmp(iter_key, min_key) < 0) \ + if (_map_->buffer[first].state == CMC_ES_FILLED) \ { \ - min_key = iter_key; \ - min_val = iter_val; \ + min_key = _map_->buffer[first].key; \ + min_val = _map_->buffer[first].value; \ + break; \ + } \ + } \ + \ + for (size_t i = first + 1; i < _map_->capacity; i++) \ + { \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) > 0) \ + { \ + min_key = _map_->buffer[first].key; \ + min_val = _map_->buffer[first].value; \ + } \ } \ } \ \ @@ -672,15 +662,16 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \ - \ - /* TODO turn this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ - K key = CMC_(PFX, _iter_key)(&iter); \ - V value = CMC_(PFX, _iter_value)(&iter); \ + if (_map_->buffer[i].state == CMC_ES_FILLED) \ + { \ + K key = _map_->buffer[i].key; \ + V value = _map_->buffer[i].value; \ \ - CMC_(PFX, _insert)(_new_map_, key, value); \ + /* TODO check this for possible errors */ \ + CMC_(PFX, _insert)(_new_map_, key, value); \ + } \ } \ \ /* Unlikely */ \ @@ -776,20 +767,28 @@ if (_map1_->count != _map2_->count) \ return false; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_map_a_; \ + struct SNAME *_map_b_; \ \ - /* TODO optimize this loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ + _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ + \ + for (size_t i = 0; i < _map_a_->capacity; i++) \ { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)( \ - _map2_, CMC_(PFX, _iter_key)(&iter)); \ + if (_map_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \ \ - if (entry == NULL) \ - return false; \ + struct CMC_DEF_ENTRY(SNAME) *entry_b = \ + CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \ \ - if (_map1_->f_val->cmp(entry->value, \ - CMC_(PFX, _iter_value)(&iter)) != 0) \ - return false; \ + if (!entry_b) \ + return false; \ + \ + if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \ + return false; \ + } \ } \ \ return true; \ diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h index 188a90c..b3e5e71 100644 --- a/src/ext/cmc/deque.h +++ b/src/ext/cmc/deque.h @@ -36,52 +36,68 @@ CMC_EXT_CMC_DEQUE_INIT_SOURCE_( \ CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) -#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); +#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ + \ + struct SNAME CMC_(PFX, _init)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val); \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _release)(struct SNAME _deque_); -#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ - \ - struct SNAME CMC_(PFX, _init)(size_t capacity, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ - } \ - \ - struct SNAME CMC_(PFX, _init_custom)( \ - size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ - { \ - struct SNAME _deque_ = { 0 }; \ - \ - if (capacity < 1) \ - return _deque_; \ - \ - if (!f_val) \ - return _deque_; \ - \ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ - \ - _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ - \ - if (!_deque_.buffer) \ - return _deque_; \ - \ - _deque_.capacity = capacity; \ - _deque_.count = 0; \ - _deque_.front = 0; \ - _deque_.back = 0; \ - _deque_.flag = CMC_FLAG_OK; \ - _deque_.f_val = f_val; \ - _deque_.alloc = alloc; \ - _deque_.callbacks = callbacks; \ - \ - return _deque_; \ +#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ + \ + struct SNAME CMC_(PFX, _init)(size_t capacity, \ + struct CMC_DEF_FVAL(SNAME) * f_val) \ + { \ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ + } \ + \ + struct SNAME CMC_(PFX, _init_custom)( \ + size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ + struct cmc_alloc_node * alloc, struct cmc_callbacks * callbacks) \ + { \ + struct SNAME _deque_ = { 0 }; \ + \ + if (capacity < 1) \ + return _deque_; \ + \ + if (!f_val) \ + return _deque_; \ + \ + if (!alloc) \ + alloc = &cmc_alloc_node_default; \ + \ + _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ + \ + if (!_deque_.buffer) \ + return _deque_; \ + \ + _deque_.capacity = capacity; \ + _deque_.count = 0; \ + _deque_.front = 0; \ + _deque_.back = 0; \ + _deque_.flag = CMC_FLAG_OK; \ + _deque_.f_val = f_val; \ + _deque_.alloc = alloc; \ + _deque_.callbacks = callbacks; \ + \ + return _deque_; \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _deque_) \ + { \ + if (_deque_.f_val->free) \ + { \ + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ + { \ + _deque_.f_val->free(_deque_.buffer[i]); \ + \ + i = (i + 1) % _deque_.capacity; \ + } \ + } \ + \ + _deque_.alloc->free(_deque_.buffer); \ } /** diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h index 10ba62b..44fea59 100644 --- a/src/ext/cmc/hashmap.h +++ b/src/ext/cmc/hashmap.h @@ -46,7 +46,8 @@ struct SNAME CMC_(PFX, _init_custom)( \ size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ struct CMC_DEF_FVAL(SNAME) * f_val, struct cmc_alloc_node * alloc, \ - struct cmc_callbacks * callbacks); + struct cmc_callbacks * callbacks); \ + void CMC_(PFX, _release)(struct SNAME _map_); #define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \ \ @@ -97,6 +98,27 @@ _map_.callbacks = callbacks; \ \ return _map_; \ + } \ + \ + void CMC_(PFX, _release)(struct SNAME _map_) \ + { \ + if (_map_.f_key->free || _map_.f_val->free) \ + { \ + for (size_t i = 0; i < _map_.capacity; i++) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \ + \ + if (entry->state == CMC_ES_FILLED) \ + { \ + if (_map_.f_key->free) \ + _map_.f_key->free(entry->key); \ + if (_map_.f_val->free) \ + _map_.f_val->free(entry->value); \ + } \ + } \ + } \ + \ + _map_.alloc->free(_map_.buffer); \ } /**