From 88a9a5beab50429901faf8f196e785f39f4da8d7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 20 Feb 2019 13:05:01 +0100 Subject: port hashmap fixes to other maps, investigated #4905, clearly no longer possible, closing that one --- src/util/container_multihashmap32.c | 26 ++++++++++++++++++-------- src/util/container_multipeermap.c | 34 ++++++++++++++++++++++------------ src/util/container_multishortmap.c | 36 +++++++++++++++++++++++------------- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/src/util/container_multihashmap32.c b/src/util/container_multihashmap32.c index 4b19c7c10..a614c04ae 100644 --- a/src/util/container_multihashmap32.c +++ b/src/util/container_multihashmap32.c @@ -11,7 +11,7 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . @@ -146,8 +146,13 @@ GNUNET_CONTAINER_multihashmap32_create (unsigned int len) GNUNET_assert (len > 0); ret = GNUNET_new (struct GNUNET_CONTAINER_MultiHashMap32); - ret->map = GNUNET_new_array (len, - struct MapEntry *); + ret->map = GNUNET_malloc_large (len * + sizeof (struct MapEntry *)); + if (NULL == ret->map) + { + GNUNET_free (ret); + return NULL; + } ret->map_length = len; return ret; } @@ -268,7 +273,7 @@ GNUNET_CONTAINER_multihashmap32_iterate (struct GNUNET_CONTAINER_MultiHashMap32 e->key, e->value)) { - GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE); + GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE); return GNUNET_SYSERR; } } @@ -463,13 +468,18 @@ grow (struct GNUNET_CONTAINER_MultiHashMap32 *map) unsigned int new_len; unsigned int idx; - map->modification_counter++; - old_map = map->map; old_len = map->map_length; new_len = old_len * 2; - new_map = GNUNET_new_array (new_len, - struct MapEntry *); + if (0 == new_len) /* 2^31 * 2 == 0 */ + new_len = old_len; /* never use 0 */ + if (new_len == old_len) + return; /* nothing changed */ + new_map = GNUNET_malloc_large (new_len * + sizeof (struct MapEntry *)); + if (NULL == new_map) + return; /* grow not possible */ + map->modification_counter++; map->map_length = new_len; map->map = new_map; for (unsigned int i = 0; i < old_len; i++) diff --git a/src/util/container_multipeermap.c b/src/util/container_multipeermap.c index 8fa23df72..613efc0a9 100644 --- a/src/util/container_multipeermap.c +++ b/src/util/container_multipeermap.c @@ -11,7 +11,7 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . @@ -200,8 +200,13 @@ GNUNET_CONTAINER_multipeermap_create (unsigned int len, GNUNET_assert (len > 0); map = GNUNET_new (struct GNUNET_CONTAINER_MultiPeerMap); - map->map = GNUNET_new_array (len, - union MapEntry); + map->map = GNUNET_malloc_large (len * + sizeof (union MapEntry)); + if (NULL == map->map) + { + GNUNET_free (map); + return NULL; + } map->map_length = len; map->use_small_entries = do_not_copy_keys; return map; @@ -493,7 +498,7 @@ GNUNET_CONTAINER_multipeermap_remove (struct GNUNET_CONTAINER_MultiPeerMap *map, if (NULL == p) map->map[i].bme = bme->next; else - p->next = bme->next; + p->next = bme->next; update_next_cache_bme (map, bme); GNUNET_free (bme); @@ -685,18 +690,23 @@ grow (struct GNUNET_CONTAINER_MultiPeerMap *map) unsigned int old_len; unsigned int new_len; unsigned int idx; - unsigned int i; - - map->modification_counter++; old_map = map->map; old_len = map->map_length; + GNUNET_assert (0 != old_len); new_len = old_len * 2; - new_map = GNUNET_new_array (new_len, - union MapEntry); + if (0 == new_len) /* 2^31 * 2 == 0 */ + new_len = old_len; /* never use 0 */ + if (new_len == old_len) + return; /* nothing changed */ + new_map = GNUNET_malloc_large (new_len * + sizeof (union MapEntry)); + if (NULL == new_map) + return; /* grow not possible */ + map->modification_counter++; map->map_length = new_len; map->map = new_map; - for (i = 0; i < old_len; i++) + for (unsigned int i = 0; i < old_len; i++) { if (map->use_small_entries) { @@ -829,7 +839,7 @@ GNUNET_CONTAINER_multipeermap_get_multiple (struct GNUNET_CONTAINER_MultiPeerMap int count; union MapEntry me; union MapEntry *ce; - + ce = &map->next_cache[map->next_cache_off]; GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE); count = 0; @@ -903,7 +913,7 @@ GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPee { unsigned int off; union MapEntry me; - + if (0 == map->size) return 0; if (NULL == it) diff --git a/src/util/container_multishortmap.c b/src/util/container_multishortmap.c index a48581b6a..966e23d35 100644 --- a/src/util/container_multishortmap.c +++ b/src/util/container_multishortmap.c @@ -11,7 +11,7 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . @@ -183,8 +183,8 @@ struct GNUNET_CONTAINER_MultiShortmapIterator * Create a multi hash map. * * @param len initial size (map will grow as needed) - * @param do_not_copy_keys GNUNET_NO is always safe and should be used by default; - * GNUNET_YES means that on 'put', the 'key' does not have + * @param do_not_copy_keys #GNUNET_NO is always safe and should be used by default; + * #GNUNET_YES means that on 'put', the 'key' does not have * to be copied as the destination of the pointer is * guaranteed to be life as long as the value is stored in * the hashmap. This can significantly reduce memory @@ -202,8 +202,13 @@ GNUNET_CONTAINER_multishortmap_create (unsigned int len, GNUNET_assert (len > 0); map = GNUNET_new (struct GNUNET_CONTAINER_MultiShortmap); - map->map = GNUNET_new_array (len, - union MapEntry); + map->map = GNUNET_malloc_large (len * + sizeof (union MapEntry)); + if (NULL == map->map) + { + GNUNET_free (map); + return NULL; + } map->map_length = len; map->use_small_entries = do_not_copy_keys; return map; @@ -355,7 +360,7 @@ GNUNET_CONTAINER_multishortmap_iterate (struct GNUNET_CONTAINER_MultiShortmap *m if (map->use_small_entries) { struct SmallMapEntry *sme; - + ce->sme = me.sme; while (NULL != (sme = ce->sme)) { @@ -366,7 +371,7 @@ GNUNET_CONTAINER_multishortmap_iterate (struct GNUNET_CONTAINER_MultiShortmap *m sme->value)) ) { GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE); - return GNUNET_SYSERR; + return GNUNET_SYSERR; } count++; } @@ -458,7 +463,7 @@ GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *ma if (map->use_small_entries) { struct SmallMapEntry *p = NULL; - + for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) { if ((0 == memcmp (key, @@ -482,7 +487,7 @@ GNUNET_CONTAINER_multishortmap_remove (struct GNUNET_CONTAINER_MultiShortmap *ma else { struct BigMapEntry *p = NULL; - + for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) { if ((0 == memcmp (key, @@ -686,13 +691,18 @@ grow (struct GNUNET_CONTAINER_MultiShortmap *map) unsigned int new_len; unsigned int idx; - map->modification_counter++; - old_map = map->map; old_len = map->map_length; new_len = old_len * 2; - new_map = GNUNET_new_array (new_len, - union MapEntry); + if (0 == new_len) /* 2^31 * 2 == 0 */ + new_len = old_len; /* never use 0 */ + if (new_len == old_len) + return; /* nothing changed */ + new_map = GNUNET_malloc_large (new_len * + sizeof (union MapEntry)); + if (NULL == new_map) + return; /* grow not possible */ + map->modification_counter++; map->map_length = new_len; map->map = new_map; for (unsigned int i = 0; i < old_len; i++) -- cgit v1.2.3