aboutsummaryrefslogtreecommitdiff
path: root/src/util/container_multihashmap.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-05-02 01:01:57 +0200
committerChristian Grothoff <christian@grothoff.org>2018-05-02 01:01:57 +0200
commit857f8c009c4fde3d3ec9d6d0b4af48e93684fd84 (patch)
tree079b460ad7555b148720c74b3601429c662c4113 /src/util/container_multihashmap.c
parentffe43cb1e86f49ddff73554df200853248af012d (diff)
downloadgnunet-857f8c009c4fde3d3ec9d6d0b4af48e93684fd84.tar.gz
gnunet-857f8c009c4fde3d3ec9d6d0b4af48e93684fd84.zip
misc improvements to statistics and large-scale behavior of zoneimport/zonemaster
Diffstat (limited to 'src/util/container_multihashmap.c')
-rw-r--r--src/util/container_multihashmap.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c
index ffeb4a71f..6001fc1df 100644
--- a/src/util/container_multihashmap.c
+++ b/src/util/container_multihashmap.c
@@ -175,14 +175,36 @@ struct GNUNET_CONTAINER_MultiHashMap *
175GNUNET_CONTAINER_multihashmap_create (unsigned int len, 175GNUNET_CONTAINER_multihashmap_create (unsigned int len,
176 int do_not_copy_keys) 176 int do_not_copy_keys)
177{ 177{
178 struct GNUNET_CONTAINER_MultiHashMap *map; 178 struct GNUNET_CONTAINER_MultiHashMap *hm;
179 179
180 GNUNET_assert (len > 0); 180 GNUNET_assert (len > 0);
181 map = GNUNET_new (struct GNUNET_CONTAINER_MultiHashMap); 181 hm = GNUNET_new (struct GNUNET_CONTAINER_MultiHashMap);
182 map->map = GNUNET_malloc (len * sizeof (union MapEntry)); 182 if (len * sizeof (union MapEntry) > GNUNET_MAX_MALLOC_CHECKED)
183 map->map_length = len; 183 {
184 map->use_small_entries = do_not_copy_keys; 184 size_t s;
185 return map; 185 /* application *explicitly* requested very large map, hopefully
186 it checks the return value... */
187 s = len * sizeof (union MapEntry);
188 if ( (s / sizeof (union MapEntry)) != len)
189 return NULL; /* integer overflow on multiplication */
190 if (NULL == (hm->map = GNUNET_malloc_large (s)))
191 {
192 /* out of memory */
193 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
194 "Out of memory allocating large hash map (%u entries)\n",
195 len);
196 GNUNET_free (hm);
197 return NULL;
198 }
199 }
200 else
201 {
202 hm->map = GNUNET_new_array (len,
203 union MapEntry);
204 }
205 hm->map_length = len;
206 hm->use_small_entries = do_not_copy_keys;
207 return hm;
186} 208}
187 209
188 210
@@ -196,11 +218,10 @@ void
196GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap 218GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap
197 *map) 219 *map)
198{ 220{
199 unsigned int i; 221 for (unsigned int i = 0; i < map->map_length; i++)
200 union MapEntry me;
201
202 for (i = 0; i < map->map_length; i++)
203 { 222 {
223 union MapEntry me;
224
204 me = map->map[i]; 225 me = map->map[i];
205 if (map->use_small_entries) 226 if (map->use_small_entries)
206 { 227 {
@@ -257,8 +278,7 @@ idx_of (const struct GNUNET_CONTAINER_MultiHashMap *map,
257 * @return the number of key value pairs 278 * @return the number of key value pairs
258 */ 279 */
259unsigned int 280unsigned int
260GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap 281GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap *map)
261 *map)
262{ 282{
263 return map->size; 283 return map->size;
264} 284}
@@ -656,17 +676,22 @@ grow (struct GNUNET_CONTAINER_MultiHashMap *map)
656 unsigned int old_len; 676 unsigned int old_len;
657 unsigned int new_len; 677 unsigned int new_len;
658 unsigned int idx; 678 unsigned int idx;
659 unsigned int i;
660 679
661 map->modification_counter++; 680 map->modification_counter++;
662 681
663 old_map = map->map; 682 old_map = map->map;
664 old_len = map->map_length; 683 old_len = map->map_length;
665 new_len = old_len * 2; 684 new_len = old_len * 2;
666 new_map = GNUNET_malloc (sizeof (union MapEntry) * new_len); 685 /* if we would exceed heap size limit for the _first_ time,
686 try staying just below the limit */
687 if ( (new_len * sizeof (union MapEntry) > GNUNET_MAX_MALLOC_CHECKED) &&
688 ((old_len+1) * sizeof (union MapEntry) < GNUNET_MAX_MALLOC_CHECKED) )
689 new_len = GNUNET_MAX_MALLOC_CHECKED / sizeof (union MapEntry);
690 new_map = GNUNET_new_array (new_len,
691 union MapEntry);
667 map->map_length = new_len; 692 map->map_length = new_len;
668 map->map = new_map; 693 map->map = new_map;
669 for (i = 0; i < old_len; i++) 694 for (unsigned int i = 0; i < old_len; i++)
670 { 695 {
671 if (map->use_small_entries) 696 if (map->use_small_entries)
672 { 697 {