diff --git a/autogen.py b/autogen.py index 2797375..c160e31 100644 --- a/autogen.py +++ b/autogen.py @@ -505,5 +505,5 @@ if __name__ == '__main__': require_file(f'{OUTPUT_DIR}/{SINGLE}.c') # TODO - if not args.notidy and has_target: + if not args.notidy and args.codecov: tidy() diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 587370b..747d516 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -461,25 +461,21 @@ return false; \ } \ \ + bool first = true; \ K max_key = (K){ 0 }; \ V max_val = (V){ 0 }; \ - size_t first = 0; \ \ - for (; first < _map_->capacity; first++) \ - { \ - if (_map_->buffer[first].state == CMC_ES_FILLED) \ - { \ - max_key = _map_->buffer[first].key; \ - max_val = _map_->buffer[first].value; \ - break; \ - } \ - } \ -\ - for (size_t i = first + 1; i < _map_->capacity; i++) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ if (_map_->buffer[i].state == CMC_ES_FILLED) \ { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ + if (first) \ + { \ + max_key = _map_->buffer[i].key; \ + max_val = _map_->buffer[i].value; \ + first = false; \ + } \ + else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ { \ max_key = _map_->buffer[i].key; \ max_val = _map_->buffer[i].value; \ @@ -505,25 +501,21 @@ return false; \ } \ \ + bool first = true; \ K min_key = (K){ 0 }; \ V min_val = (V){ 0 }; \ - size_t first = 0; \ \ - for (; first < _map_->capacity; first++) \ - { \ - if (_map_->buffer[first].state == CMC_ES_FILLED) \ - { \ - min_key = _map_->buffer[first].key; \ - min_val = _map_->buffer[first].value; \ - break; \ - } \ - } \ -\ - for (size_t i = first + 1; i < _map_->capacity; i++) \ + for (size_t i = 0; i < _map_->capacity; i++) \ { \ if (_map_->buffer[i].state == CMC_ES_FILLED) \ { \ - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ + if (first) \ + { \ + min_key = _map_->buffer[i].key; \ + min_val = _map_->buffer[i].value; \ + first = false; \ + } \ + else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ { \ min_key = _map_->buffer[i].key; \ min_val = _map_->buffer[i].value; \ @@ -780,7 +772,6 @@ if (_map_a_->buffer[i].state == CMC_ES_FILLED) \ { \ struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \ -\ struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \ \ if (!entry_b) \ diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h index b1dbd55..8371e5a 100644 --- a/src/cmc/hashmultimap.h +++ b/src/cmc/hashmultimap.h @@ -959,17 +959,17 @@ \ while (scan) \ { \ - K key;\ - V value;\ + K key; \ + V value; \ \ if (_map_->f_key->cpy) \ key = _map_->f_key->cpy(scan->key); \ - else\ - key = scan->key;\ + else \ + key = scan->key; \ if (_map_->f_val->cpy) \ value = _map_->f_val->cpy(scan->value); \ - else\ - value = scan->value;\ + else \ + value = scan->value; \ \ /* TODO check for errors */ \ CMC_(PFX, _insert)(result, key, value); \ @@ -1005,9 +1005,9 @@ \ while (scan) \ { \ - /* OPTIMIZE - This is calling key_count for repeating keys */\ - if (CMC_(PFX, _impl_key_count)(_map_a_, scan->key) != CMC_(PFX, _impl_key_count)(_map_b_, scan->key))\ - return false;\ + /* OPTIMIZE - This is calling key_count for repeating keys */ \ + if (CMC_(PFX, _impl_key_count)(_map_a_, scan->key) != CMC_(PFX, _impl_key_count)(_map_b_, scan->key)) \ + return false; \ \ scan = scan->next; \ } \ diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h index eaa3f08..8cfff7d 100644 --- a/src/cmc/hashmultiset.h +++ b/src/cmc/hashmultiset.h @@ -477,19 +477,23 @@ return false; \ } \ \ + bool first = true; \ V max_val = (V){ 0 }; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ - /* TODO transform this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - V result = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ -\ - if (index == 0) \ - max_val = result; \ - else if (_set_->f_val->cmp(result, max_val) > 0) \ - max_val = result; \ + if (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (first) \ + { \ + max_val = _set_->buffer[i].value; \ + first = false; \ + } \ + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) \ + { \ + max_val = _set_->buffer[i].value; \ + } \ + } \ } \ \ if (value) \ @@ -510,19 +514,23 @@ return false; \ } \ \ + bool first = true; \ V min_val = (V){ 0 }; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ - /* TODO transform this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - V result = CMC_(PFX, _iter_value)(&iter); \ - size_t index = CMC_(PFX, _iter_index)(&iter); \ -\ - if (index == 0) \ - min_val = result; \ - else if (_set_->f_val->cmp(result, min_val) < 0) \ - min_val = result; \ + if (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + if (first) \ + { \ + min_val = _set_->buffer[i].value; \ + first = false; \ + } \ + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) \ + { \ + min_val = _set_->buffer[i].value; \ + } \ + } \ } \ \ if (value) \ @@ -631,13 +639,19 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ -\ - /* TODO transform this into a normal loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _set_->capacity; i++) \ { \ - CMC_(PFX, _insert_many) \ - (_new_set_, CMC_(PFX, _iter_value)(&iter), CMC_(PFX, _iter_multiplicity)(&iter)); \ + if (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + V value = _set_->buffer[i].value; \ + size_t multiplicity = _set_->buffer[i].multiplicity; \ +\ + /* TODO check this for possible errors where entry == NULL */ \ + struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_new_set_, value, NULL); \ + \ + entry->multiplicity = multiplicity;\ + /* Setting cardinality not required, _new_set_ is temporary */\ + } \ } \ \ if (_set_->count != _new_set_->count) \ @@ -729,17 +743,26 @@ if (_set1_->count == 0) \ return true; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_set_a_; \ + struct SNAME *_set_b_; \ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; \ + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; \ +\ + for (size_t i = 0; i < _set_a_->capacity; i++) \ { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)); \ + if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_set_a_->buffer[i]); \ + struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_set_b_, entry_a->value); \ \ - if (!entry) \ - return false; \ + if (!entry_b) \ + return false; \ \ - if (entry->multiplicity != CMC_(PFX, _iter_multiplicity)(&iter)) \ - return false; \ + if (entry_a->multiplicity != entry_b->multiplicity) \ + return false; \ + } \ } \ \ return true; \ @@ -762,14 +785,16 @@ /* something with it. This function only guarantees that there is */ \ /* a valid entry for a given value */ \ \ - *new_node = false; \ + if (new_node)\ + *new_node = false; \ \ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ \ if (entry != NULL) \ return entry; \ \ - *new_node = true; \ + if (new_node)\ + *new_node = true; \ \ if (CMC_(PFX, _full)(_set_)) \ { \ diff --git a/tests/src/cmc/hashbidimap.c b/tests/src/cmc/hashbidimap.c index c7a1b70..1d853c5 100644 --- a/tests/src/cmc/hashbidimap.c +++ b/tests/src/cmc/hashbidimap.c @@ -177,7 +177,7 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) _map_->flag = CMC_FLAG_NOT_FOUND; return 0; } - if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) + if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) goto success; if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) { diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c index 20f99e5..d4eb005 100644 --- a/tests/src/cmc/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -201,23 +201,20 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 0; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; - size_t first = 0; - for (; first < _map_->capacity; first++) - { - if (_map_->buffer[first].state == CMC_ES_FILLED) - { - max_key = _map_->buffer[first].key; - max_val = _map_->buffer[first].value; - break; - } - } - for (size_t i = first + 1; i < _map_->capacity; i++) + for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { - if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) + if (first) + { + max_key = _map_->buffer[i].key; + max_val = _map_->buffer[i].value; + first = 0; + } + else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) { max_key = _map_->buffer[i].key; max_val = _map_->buffer[i].value; @@ -240,23 +237,20 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_key = (size_t){ 0 }; size_t min_val = (size_t){ 0 }; - size_t first = 0; - for (; first < _map_->capacity; first++) - { - if (_map_->buffer[first].state == CMC_ES_FILLED) - { - min_key = _map_->buffer[first].key; - min_val = _map_->buffer[first].value; - break; - } - } - for (size_t i = first + 1; i < _map_->capacity; i++) + for (size_t i = 0; i < _map_->capacity; i++) { if (_map_->buffer[i].state == CMC_ES_FILLED) { - if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) + if (first) + { + min_key = _map_->buffer[i].key; + min_val = _map_->buffer[i].value; + first = 0; + } + else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) { min_key = _map_->buffer[i].key; min_val = _map_->buffer[i].value; diff --git a/tests/src/cmc/hashmultiset.c b/tests/src/cmc/hashmultiset.c index 6aa25a2..64d656a 100644 --- a/tests/src/cmc/hashmultiset.c +++ b/tests/src/cmc/hashmultiset.c @@ -218,16 +218,22 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t max_val = (size_t){ 0 }; - struct hashmultiset_iter iter = hms_iter_start(_set_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hms_iter_value(&iter); - size_t index = hms_iter_index(&iter); - if (index == 0) - max_val = result; - else if (_set_->f_val->cmp(result, max_val) > 0) - max_val = result; + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + max_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) + { + max_val = _set_->buffer[i].value; + } + } } if (value) *value = max_val; @@ -244,16 +250,22 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_val = (size_t){ 0 }; - struct hashmultiset_iter iter = hms_iter_start(_set_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hms_iter_value(&iter); - size_t index = hms_iter_index(&iter); - if (index == 0) - min_val = result; - else if (_set_->f_val->cmp(result, min_val) < 0) - min_val = result; + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + if (first) + { + min_val = _set_->buffer[i].value; + first = 0; + } + else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) + { + min_val = _set_->buffer[i].value; + } + } } if (value) *value = min_val; @@ -335,10 +347,15 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity) _set_->flag = CMC_FLAG_ERROR; return 0; } - struct hashmultiset_iter iter = hms_iter_start(_set_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - hms_insert_many(_new_set_, hms_iter_value(&iter), hms_iter_multiplicity(&iter)); + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + size_t value = _set_->buffer[i].value; + size_t multiplicity = _set_->buffer[i].multiplicity; + struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); + entry->multiplicity = multiplicity; + } } if (_set_->count != _new_set_->count) { @@ -407,14 +424,21 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) return 0; if (_set1_->count == 0) return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) + struct hashmultiset *_set_a_; + struct hashmultiset *_set_b_; + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; + for (size_t i = 0; i < _set_a_->capacity; i++) { - struct hashmultiset_entry *entry = hms_impl_get_entry(_set2_, hms_iter_value(&iter)); - if (!entry) - return 0; - if (entry->multiplicity != hms_iter_multiplicity(&iter)) - return 0; + if (_set_a_->buffer[i].state == CMC_ES_FILLED) + { + struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); + struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); + if (!entry_b) + return 0; + if (entry_a->multiplicity != entry_b->multiplicity) + return 0; + } } return 1; } @@ -427,11 +451,13 @@ static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) } static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) { - *new_node = 0; + if (new_node) + *new_node = 0; struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); if (entry != ((void *)0)) return entry; - *new_node = 1; + if (new_node) + *new_node = 1; if (hms_full(_set_)) { if (!hms_resize(_set_, _set_->capacity + 1))