port hashmap fixes to other maps, investigated #4905, clearly no longer possible...
authorChristian Grothoff <christian@grothoff.org>
Wed, 20 Feb 2019 12:05:01 +0000 (13:05 +0100)
committerChristian Grothoff <christian@grothoff.org>
Wed, 20 Feb 2019 12:05:01 +0000 (13:05 +0100)
src/util/container_multihashmap32.c
src/util/container_multipeermap.c
src/util/container_multishortmap.c

index 4b19c7c1026220a2f78b1cd95b2f8a29311a34a0..a614c04aef5442e3bd534ad68e5d2be124b75d7d 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
 
@@ -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++)
index 8fa23df723f9ddd8f6a4f8aeb0d4d0674c684cde..613efc0a9d4f67eb066b1ab372c9c2fd7c546556 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
 
@@ -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)
index a48581b6a2b8d6dfcdc6f5e8c5924bd27ef23bfb..966e23d35d7a948efed1e35f999fcd75dd91f78f 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
 
@@ -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++)