From f74ce7519a91db5c3c1ffa782b4b12b41d80aadb Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 3 Aug 2019 01:55:36 -0300 Subject: [PATCH] Added update function for hashmap, treemap and multimap and added update_all for multimap --- TODO | 2 +- src/cmc/hashmap.h | 13 +++++++++++ src/cmc/treemap.h | 13 +++++++++++ src/ext/multimap.h | 55 ++++++++++++++++++++++++++++++++++++---------- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 033ea1b..e83ac73 100644 --- a/TODO +++ b/TODO @@ -12,7 +12,7 @@ TODO [X] Add IntervalHeap [ ] Add TreeHashMap [ ] Add functions - [ ] update {hashmap, treemap, multimap} + [X] update {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 45dc383..f550bfb 100644 --- a/src/cmc/hashmap.h +++ b/src/cmc/hashmap.h @@ -161,6 +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##_remove(SNAME *_map_, K key, V *value); \ /* Conditional Input and Output */ \ FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \ @@ -341,6 +342,18 @@ 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) \ + { \ + SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \ + \ + if (!entry) \ + return false; \ + \ + entry->value = new_value; \ + \ + return true; \ + } \ + \ FMOD bool PFX##_remove(SNAME *_map_, K key, V *value) \ { \ SNAME##_entry *result = PFX##_impl_get_entry(_map_, key); \ diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h index 76ab23a..a701863 100644 --- a/src/cmc/treemap.h +++ b/src/cmc/treemap.h @@ -114,6 +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##_remove(SNAME *_map_, K key, V *value); \ /* Conditional Input and Output */ \ FMOD bool PFX##_insert_if(SNAME *_map_, K key, V value, bool condition); \ @@ -320,6 +321,18 @@ return true; \ } \ \ + FMOD bool PFX##_update(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##_remove(SNAME *_map_, K key, V *value) \ { \ SNAME##_node *node = PFX##_impl_get_node(_map_, key); \ diff --git a/src/ext/multimap.h b/src/ext/multimap.h index 4d2b30a..837ba46 100644 --- a/src/ext/multimap.h +++ b/src/ext/multimap.h @@ -179,6 +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##_remove(SNAME *_map_, K key, V *value); \ FMOD size_t PFX##_remove_all(SNAME *_map_, K key); \ /* Conditional Input and Output */ \ @@ -354,6 +356,48 @@ 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) \ + { \ + size_t hash = _map_->hash(key); \ + \ + SNAME##_entry *entry = _map_->buffer[hash % _map_->capacity][0]; \ + \ + while (entry != NULL) \ + { \ + if (_map_->cmp(entry->key, key) == 0) \ + { \ + entry->value = new_value; \ + \ + return true; \ + } \ + \ + entry = entry->next; \ + } \ + \ + return false; \ + } \ + \ + FMOD size_t PFX##_update_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++; \ + } \ + } \ + \ + return total; \ + } \ + \ FMOD bool PFX##_remove(SNAME *_map_, K key, V *value) \ { \ size_t hash = _map_->hash(key); \ @@ -831,17 +875,6 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, \ SNAME##_entry *entry = _map_->buffer[hash % _map_->capacity][0]; \ \ - if (entry == NULL) \ - return NULL; \ - \ - if (entry->next == NULL && entry->prev == NULL) \ - { \ - if (_map_->cmp(entry->key, key) == 0) \ - return entry; \ - else \ - return NULL; \ - } \ - \ while (entry != NULL) \ { \ if (_map_->cmp(entry->key, key) == 0) \