diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-05-02 01:01:57 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-05-02 01:01:57 +0200 |
commit | 857f8c009c4fde3d3ec9d6d0b4af48e93684fd84 (patch) | |
tree | 079b460ad7555b148720c74b3601429c662c4113 /src/util/container_multihashmap.c | |
parent | ffe43cb1e86f49ddff73554df200853248af012d (diff) | |
download | gnunet-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.c | 55 |
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 * | |||
175 | GNUNET_CONTAINER_multihashmap_create (unsigned int len, | 175 | GNUNET_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 | |||
196 | GNUNET_CONTAINER_multihashmap_destroy (struct GNUNET_CONTAINER_MultiHashMap | 218 | GNUNET_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 | */ |
259 | unsigned int | 280 | unsigned int |
260 | GNUNET_CONTAINER_multihashmap_size (const struct GNUNET_CONTAINER_MultiHashMap | 281 | GNUNET_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 | { |