diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index 747d516..8b45349 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -487,6 +487,8 @@ *key = max_key; \ if (value) \ *value = max_val; \ +\ + _map_->flag = CMC_FLAG_OK; \ \ CMC_CALLBACKS_CALL(_map_, read); \ \ @@ -527,6 +529,8 @@ *key = min_key; \ if (value) \ *value = min_val; \ +\ + _map_->flag = CMC_FLAG_OK; \ \ CMC_CALLBACKS_CALL(_map_, read); \ \ diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h index 35b2fa9..5e22961 100644 --- a/src/cmc/hashset.h +++ b/src/cmc/hashset.h @@ -378,19 +378,23 @@ return false; \ } \ \ + bool first = true; \ V max_val = (V){ 0 }; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ - /* 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 < _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) \ @@ -411,19 +415,23 @@ return false; \ } \ \ + bool first = true; \ V min_val = (V){ 0 }; \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ \ - /* 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 < _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) \ @@ -513,15 +521,15 @@ return false; \ } \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ -\ - /* 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 < _set_->capacity; i++) \ { \ - V value = CMC_(PFX, _iter_value)(&iter); \ + if (_set_->buffer[i].state == CMC_ES_FILLED) \ + { \ + V value = _set_->buffer[i].value; \ \ - /* TODO check for error */ \ - CMC_(PFX, _insert)(_new_set_, value); \ + /* TODO check this for possible errors */ \ + CMC_(PFX, _insert)(_new_set_, value); \ + } \ } \ \ /* Unlikely */ \ @@ -606,16 +614,21 @@ if (_set1_->count != _set2_->count) \ return false; \ \ - if (_set1_->count == 0) \ - return true; \ + /* Optimize loop using the smallest hashtable */ \ + struct SNAME *_set_a_; \ + struct SNAME *_set_b_; \ \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ + _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; \ + _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; \ \ - /* TODO optimize this loop */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ + for (size_t i = 0; i < _set_a_->capacity; i++) \ { \ - if (CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ - return false; \ + if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ + { \ + \ + if (!CMC_(PFX, _impl_get_entry)(_set_b_, _set_a_->buffer[i].value))\ + return false;\ + } \ } \ \ return true; \ diff --git a/tests/src/cmc/hashmap.c b/tests/src/cmc/hashmap.c index d4eb005..abb8bf0 100644 --- a/tests/src/cmc/hashmap.c +++ b/tests/src/cmc/hashmap.c @@ -201,7 +201,7 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) _map_->flag = CMC_FLAG_EMPTY; return 0; } - _Bool first = 0; + _Bool first = 1; size_t max_key = (size_t){ 0 }; size_t max_val = (size_t){ 0 }; for (size_t i = 0; i < _map_->capacity; i++) @@ -225,6 +225,7 @@ _Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) *key = max_key; if (value) *value = max_val; + _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read(); ; @@ -261,6 +262,7 @@ _Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) *key = min_key; if (value) *value = min_val; + _map_->flag = CMC_FLAG_OK; if ((_map_)->callbacks && (_map_)->callbacks->read) (_map_)->callbacks->read(); ; diff --git a/tests/src/cmc/hashset.c b/tests/src/cmc/hashset.c index e0605f1..0594d98 100644 --- a/tests/src/cmc/hashset.c +++ b/tests/src/cmc/hashset.c @@ -164,16 +164,22 @@ _Bool hs_max(struct hashset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t max_val = (size_t){ 0 }; - struct hashset_iter iter = hs_iter_start(_set_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hs_iter_value(&iter); - size_t index = hs_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; @@ -190,16 +196,22 @@ _Bool hs_min(struct hashset *_set_, size_t *value) _set_->flag = CMC_FLAG_EMPTY; return 0; } + _Bool first = 1; size_t min_val = (size_t){ 0 }; - struct hashset_iter iter = hs_iter_start(_set_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t result = hs_iter_value(&iter); - size_t index = hs_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; @@ -266,11 +278,13 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity) _set_->flag = CMC_FLAG_ALLOC; return 0; } - struct hashset_iter iter = hs_iter_start(_set_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + for (size_t i = 0; i < _set_->capacity; i++) { - size_t value = hs_iter_value(&iter); - hs_insert(_new_set_, value); + if (_set_->buffer[i].state == CMC_ES_FILLED) + { + size_t value = _set_->buffer[i].value; + hs_insert(_new_set_, value); + } } if (_set_->count != _new_set_->count) { @@ -333,13 +347,17 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) _set2_->flag = CMC_FLAG_OK; if (_set1_->count != _set2_->count) return 0; - if (_set1_->count == 0) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) + struct hashset *_set_a_; + struct hashset *_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++) { - if (hs_impl_get_entry(_set2_, hs_iter_value(&iter)) == ((void *)0)) - return 0; + if (_set_a_->buffer[i].state == CMC_ES_FILLED) + { + if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) + return 0; + } } return 1; }