From 613392ae762679e41c67bfd4b0ef600036505139 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 5 Aug 2019 23:28:12 -0300 Subject: [PATCH] Changed how _update works and added _set _update: retrieves old value _set: ignores old value --- TODO | 1 + src/cmc/hashmap.h | 18 ++++++++- src/cmc/treemap.h | 18 ++++++++- src/ext/multimap.h | 93 +++++++++++++++++++++++++++++++++++----------- 4 files changed, 105 insertions(+), 25 deletions(-) diff --git a/TODO b/TODO index e83ac73..73408ec 100644 --- a/TODO +++ b/TODO @@ -13,6 +13,7 @@ TODO [ ] Add TreeHashMap [ ] Add functions [X] update {hashmap, treemap, multimap} + [X] set {hashmap, treemap, multimap} [/] to_string {all} [ ] iter_advance {all} (iterators) [ ] iter_rewind {all} (iterators) diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h index f550bfb..464774f 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -161,7 +161,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD void PFX##_free(SNAME *_map_); \ /* Collection Input and Output */ \ FMOD bool PFX##_insert(SNAME *_map_, K key, V value); \ - FMOD bool PFX##_update(SNAME *_map_, K key, V new_value); \ + FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \ FMOD bool PFX##_remove(SNAME *_map_, K key, V *value); \ /* Conditional Input and Output */ \ FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \ @@ -171,6 +171,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \ FMOD V PFX##_get(SNAME *_map_, K key); \ FMOD V *PFX##_get_ref(SNAME *_map_, K key); \ + FMOD bool PFX##_set(SNAME *_map_, K key, V new_value); \ /* Collection State */ \ FMOD bool PFX##_contains(SNAME *_map_, K key); \ FMOD bool PFX##_empty(SNAME *_map_); \ @@ -342,13 +343,14 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return true; \ } \ \ - FMOD bool PFX##_update(SNAME *_map_, K key, V new_value) \ + FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value) \ { \ SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ \ if (!entry) \ return false; \ \ + *old_value = entry->value; \ entry->value = new_value; \ \ return true; \ @@ -465,6 +467,18 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return &(entry->value); \ } \ \ + FMOD bool PFX##_set(SNAME *_map_, K key, V new_value) \ + { \ + SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ + \ + if (!entry) \ + return false; \ + \ + entry->value = new_value; \ + \ + return true; \ + } \ + \ FMOD bool PFX##_contains(SNAME *_map_, K key) \ { \ return PFX##_impl_get_entry(_map_, key) != NULL; \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index a701863..c076731 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -114,7 +114,7 @@ FMOD void PFX##_free(SNAME *_map_); \ /* Collection Input and Output */ \ FMOD bool PFX##_insert(SNAME *_map_, K key, V value); \ - FMOD bool PFX##_update(SNAME *_map_, K key, V new_value); \ + FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \ FMOD bool PFX##_remove(SNAME *_map_, K key, V *value); \ /* Conditional Input and Output */ \ FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \ @@ -124,6 +124,7 @@ FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \ FMOD V PFX##_get(SNAME *_map_, K key); \ FMOD V *PFX##_get_ref(SNAME *_map_, K key); \ + FMOD bool PFX##_set(SNAME *_map_, K key, V new_value); \ /* Collection State */ \ FMOD bool PFX##_contains(SNAME *_map_, K key); \ FMOD bool PFX##_empty(SNAME *_map_); \ @@ -321,13 +322,14 @@ return true; \ } \ \ - FMOD bool PFX##_update(SNAME *_map_, K key, V new_value) \ + FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value) \ { \ SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ \ if (!node) \ return false; \ \ + *old_value = node->value; \ node->value = new_value; \ \ return true; \ @@ -526,6 +528,18 @@ return &(node->value); \ } \ \ + FMOD bool PFX##_set(SNAME *_map_, K key, V new_value) \ + { \ + SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ + \ + if (!node) \ + return false; \ + \ + node->value = new_value; \ + \ + return true; \ + } \ + \ FMOD bool PFX##_contains(SNAME *_map_, K key) \ { \ SNAME##_node *scan = _map_->root; \ diff --git a/src/ext/multimap.h b/src/ext/multimap.h index 837ba46..d500040 100644 --- a/src/ext/multimap.h +++ b/src/ext/multimap.h @@ -179,8 +179,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD void PFX##_free(SNAME *_map_); \ /* Collection Input and Output */ \ FMOD bool PFX##_insert(SNAME *_map_, K key, V value); \ - FMOD bool PFX##_update(SNAME *_map_, K key, V new_value); \ - FMOD size_t PFX##_update_all(SNAME *_map_, K key, V new_value); \ + FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value); \ + FMOD size_t PFX##_update_all(SNAME *_map_, K key, V new_value, V **old_values); \ FMOD bool PFX##_remove(SNAME *_map_, K key, V *value); \ FMOD size_t PFX##_remove_all(SNAME *_map_, K key); \ /* Conditional Input and Output */ \ @@ -191,6 +191,8 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \ FMOD V PFX##_get(SNAME *_map_, K key); \ FMOD V *PFX##_get_ref(SNAME *_map_, K key); \ + FMOD bool PFX##_set(SNAME *_map_, K key, V new_value); \ + FMOD size_t PFX##_set_all(SNAME *_map_, K key, V new_value); \ /* Collection State */ \ FMOD bool PFX##_contains(SNAME *_map_, K key); \ FMOD bool PFX##_empty(SNAME *_map_); \ @@ -356,43 +358,57 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return true; \ } \ \ - FMOD bool PFX##_update(SNAME *_map_, K key, V new_value) \ + FMOD bool PFX##_update(SNAME *_map_, K key, V new_value, V *old_value) \ { \ - size_t hash = _map_->hash(key); \ + SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ \ - SNAME##_entry *entry = _map_->buffer[hash % _map_->capacity][0]; \ + if (!entry) \ + return false; \ \ - while (entry != NULL) \ - { \ - if (_map_->cmp(entry->key, key) == 0) \ - { \ - entry->value = new_value; \ - \ - return true; \ - } \ - \ - entry = entry->next; \ - } \ + *old_value = entry->value; \ + entry->value = new_value; \ \ return false; \ } \ \ - FMOD size_t PFX##_update_all(SNAME *_map_, K key, V new_value) \ + FMOD size_t PFX##_update_all(SNAME *_map_, K key, V new_value, V **old_values) \ { \ size_t hash = _map_->hash(key); \ \ - SNAME##_entry *entry = _map_->buffer[hash % _map_->capacity][0]; \ + SNAME##_entry *bucket = _map_->buffer[hash % _map_->capacity][0]; \ + SNAME##_entry *entry = bucket; \ \ size_t total = 0; \ \ while (entry != NULL) \ { \ if (_map_->cmp(entry->key, key) == 0) \ - { \ - entry->value = new_value; \ - \ total++; \ + \ + entry = entry->next; \ + } \ + \ + if (total == 0) \ + return total; \ + \ + *old_values = malloc(sizeof(V) * total); \ + \ + if (!(*old_values)) \ + return false; \ + \ + entry = bucket; \ + size_t index = 0; \ + \ + while (entry != NULL) \ + { \ + if (_map_->cmp(entry->key, key) == 0) \ + { \ + (*old_values)[index++] = entry->value; \ + \ + entry->value = new_value; \ } \ + \ + entry = entry->next; \ } \ \ return total; \ @@ -607,6 +623,41 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return &(entry->value); \ } \ \ + FMOD bool PFX##_set(SNAME *_map_, K key, V new_value) \ + { \ + SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ + \ + if (!entry) \ + return false; \ + \ + entry->value = new_value; \ + \ + return false; \ + } \ + \ + FMOD size_t PFX##_set_all(SNAME *_map_, K key, V new_value) \ + { \ + size_t hash = _map_->hash(key); \ + \ + SNAME##_entry *entry = _map_->buffer[hash % _map_->capacity][0]; \ + \ + size_t total = 0; \ + \ + while (entry != NULL) \ + { \ + if (_map_->cmp(entry->key, key) == 0) \ + { \ + entry->value = new_value; \ + \ + total++; \ + } \ + \ + entry = entry->next; \ + } \ + \ + return total; \ + } \ + \ FMOD bool PFX##_contains(SNAME *_map_, K key) \ { \ return PFX##_impl_get_entry(_map_, key) != NULL; \