aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-02-19 11:37:12 +0100
committerChristian Grothoff <christian@grothoff.org>2019-02-19 11:37:12 +0100
commitefe6acf1e46cec88bc49e233f2e0c4cce6dac47b (patch)
tree34a1440d1c8df8a43a5691df416cafa1e6056b0b /src/util
parentd76ca4e2e7e5c93ec92a4cf349ed62147a2b2148 (diff)
downloadgnunet-efe6acf1e46cec88bc49e233f2e0c4cce6dac47b.tar.gz
gnunet-efe6acf1e46cec88bc49e233f2e0c4cce6dac47b.zip
fix grow behavior of hash map for very large maps
Diffstat (limited to 'src/util')
-rw-r--r--src/util/container_multihashmap.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/src/util/container_multihashmap.c b/src/util/container_multihashmap.c
index cf5c2a334..7605ea151 100644
--- a/src/util/container_multihashmap.c
+++ b/src/util/container_multihashmap.c
@@ -11,7 +11,7 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
@@ -417,7 +417,7 @@ GNUNET_CONTAINER_multihashmap_iterate (struct GNUNET_CONTAINER_MultiHashMap *map
417 } 417 }
418 } 418 }
419 } 419 }
420 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE); 420 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
421 return count; 421 return count;
422} 422}
423 423
@@ -764,18 +764,19 @@ grow (struct GNUNET_CONTAINER_MultiHashMap *map)
764 unsigned int new_len; 764 unsigned int new_len;
765 unsigned int idx; 765 unsigned int idx;
766 766
767 map->modification_counter++;
768
769 old_map = map->map; 767 old_map = map->map;
770 old_len = map->map_length; 768 old_len = map->map_length;
769 GNUNET_assert (0 != old_len);
771 new_len = old_len * 2; 770 new_len = old_len * 2;
772 /* if we would exceed heap size limit for the _first_ time, 771 if (0 == new_len) /* 2^31 * 2 == 0 */
773 try staying just below the limit */ 772 new_len = old_len; /* never use 0 */
774 if ( (new_len * sizeof (union MapEntry) > GNUNET_MAX_MALLOC_CHECKED) && 773 if (new_len == old_len)
775 ((old_len+1) * sizeof (union MapEntry) < GNUNET_MAX_MALLOC_CHECKED) ) 774 return; /* nothing changed */
776 new_len = GNUNET_MAX_MALLOC_CHECKED / sizeof (union MapEntry); 775 new_map = GNUNET_malloc_large (new_len *
777 new_map = GNUNET_new_array (new_len, 776 sizeof (union MapEntry));
778 union MapEntry); 777 if (NULL == new_map)
778 return; /* grow not possible */
779 map->modification_counter++;
779 map->map_length = new_len; 780 map->map_length = new_len;
780 map->map = new_map; 781 map->map = new_map;
781 for (unsigned int i = 0; i < old_len; i++) 782 for (unsigned int i = 0; i < old_len; i++)