-fix
[oweals/gnunet.git] / src / util / container_multihashmap.c
index bd22732be68cfd7441762ec49c0a38b69c765a66..567ee12516dde93f97081103944d4c614856f25c 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -24,9 +24,7 @@
  */
 
 #include "platform.h"
  */
 
 #include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_container_lib.h"
-#include "gnunet_crypto_lib.h"
+#include "gnunet_util_lib.h"
 
 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
 
 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
 
@@ -69,7 +67,7 @@ struct SmallMapEntry
    * If there is a hash collision, we create a linked list.
    */
   struct SmallMapEntry *next;
    * If there is a hash collision, we create a linked list.
    */
   struct SmallMapEntry *next;
-  
+
   /**
    * Key for the entry.
    */
   /**
    * Key for the entry.
    */
@@ -116,8 +114,8 @@ struct GNUNET_CONTAINER_MultiHashMap
   unsigned int map_length;
 
   /**
   unsigned int map_length;
 
   /**
-   * GNUNET_NO if the map entries are of type 'struct BigMapEntry',
-   * GNUNET_YES if the map entries are of type 'struct SmallMapEntry'.
+   * #GNUNET_NO if the map entries are of type 'struct BigMapEntry',
+   * #GNUNET_YES if the map entries are of type 'struct SmallMapEntry'.
    */
   int use_small_entries;
 
    */
   int use_small_entries;
 
@@ -162,12 +160,12 @@ struct GNUNET_CONTAINER_MultiHashMapIterator
  * Create a multi hash map.
  *
  * @param len initial size (map will grow as needed)
  * 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
- *                         to be copied as the destination of the pointer is 
+ * @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
  *                         guaranteed to be life as long as the value is stored in
- *                         the hashmap.  This can significantly reduce memory 
- *                         consumption, but of course is also a recipie for 
+ *                         the hashmap.  This can significantly reduce memory
+ *                         consumption, but of course is also a recipie for
  *                         heap corruption if the assumption is not true.  Only
  *                         use this if (1) memory use is important in this case and
  *                         (2) you have triple-checked that the invariant holds
  *                         heap corruption if the assumption is not true.  Only
  *                         use this if (1) memory use is important in this case and
  *                         (2) you have triple-checked that the invariant holds
@@ -180,7 +178,7 @@ GNUNET_CONTAINER_multihashmap_create (unsigned int len,
   struct GNUNET_CONTAINER_MultiHashMap *map;
 
   GNUNET_assert (len > 0);
   struct GNUNET_CONTAINER_MultiHashMap *map;
 
   GNUNET_assert (len > 0);
-  map = GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_MultiHashMap));
+  map = GNUNET_new (struct GNUNET_CONTAINER_MultiHashMap);
   map->map = GNUNET_malloc (len * sizeof (union MapEntry));
   map->map_length = len;
   map->use_small_entries = do_not_copy_keys;
   map->map = GNUNET_malloc (len * sizeof (union MapEntry));
   map->map_length = len;
   map->use_small_entries = do_not_copy_keys;
@@ -308,9 +306,9 @@ GNUNET_CONTAINER_multihashmap_get (const struct GNUNET_CONTAINER_MultiHashMap
  *
  * @param map the map
  * @param it function to call on each entry
  *
  * @param map the map
  * @param it function to call on each entry
- * @param it_cls extra argument to it
+ * @param it_cls extra argument to @a it
  * @return the number of key value pairs processed,
  * @return the number of key value pairs processed,
- *         GNUNET_SYSERR if it aborted iteration
+ *         #GNUNET_SYSERR if it aborted iteration
  */
 int
 GNUNET_CONTAINER_multihashmap_iterate (const struct
  */
 int
 GNUNET_CONTAINER_multihashmap_iterate (const struct
@@ -333,7 +331,7 @@ GNUNET_CONTAINER_multihashmap_iterate (const struct
       struct SmallMapEntry *sme;
       struct SmallMapEntry *nxt;
 
       struct SmallMapEntry *sme;
       struct SmallMapEntry *nxt;
 
-      nxt = me.sme; 
+      nxt = me.sme;
       while (NULL != (sme = nxt))
       {
        nxt = sme->next;
       while (NULL != (sme = nxt))
       {
        nxt = sme->next;
@@ -350,7 +348,7 @@ GNUNET_CONTAINER_multihashmap_iterate (const struct
       struct BigMapEntry *bme;
       struct BigMapEntry *nxt;
 
       struct BigMapEntry *bme;
       struct BigMapEntry *nxt;
 
-      nxt = me.bme; 
+      nxt = me.bme;
       while (NULL != (bme = nxt))
       {
        nxt = bme->next;
       while (NULL != (bme = nxt))
       {
        nxt = bme->next;
@@ -376,12 +374,12 @@ GNUNET_CONTAINER_multihashmap_iterate (const struct
  * @param map the map
  * @param key key of the key-value pair
  * @param value value of the key-value pair
  * @param map the map
  * @param key key of the key-value pair
  * @param value value of the key-value pair
- * @return GNUNET_YES on success, GNUNET_NO if the key-value pair
+ * @return #GNUNET_YES on success, #GNUNET_NO if the key-value pair
  *  is not in the map
  */
 int
 GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
  *  is not in the map
  */
 int
 GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
-                                      const struct GNUNET_HashCode *key, 
+                                      const struct GNUNET_HashCode *key,
                                      const void *value)
 {
   union MapEntry me;
                                      const void *value)
 {
   union MapEntry me;
@@ -392,7 +390,7 @@ GNUNET_CONTAINER_multihashmap_remove (struct GNUNET_CONTAINER_MultiHashMap *map,
   i = idx_of (map, key);
   me = map->map[i];
   if (map->use_small_entries)
   i = idx_of (map, key);
   me = map->map[i];
   if (map->use_small_entries)
-  {  
+  {
     struct SmallMapEntry *sme;
     struct SmallMapEntry *p;
 
     struct SmallMapEntry *sme;
     struct SmallMapEntry *p;
 
@@ -461,7 +459,7 @@ GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap
   i = idx_of (map, key);
   me = map->map[i];
   if (map->use_small_entries)
   i = idx_of (map, key);
   me = map->map[i];
   if (map->use_small_entries)
-  {  
+  {
     struct SmallMapEntry *sme;
     struct SmallMapEntry *p;
 
     struct SmallMapEntry *sme;
     struct SmallMapEntry *p;
 
@@ -481,7 +479,7 @@ GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap
          sme = map->map[i].sme;
        else
          sme = p->next;
          sme = map->map[i].sme;
        else
          sme = p->next;
-       ret++;  
+       ret++;
       }
       else
       {
       }
       else
       {
@@ -530,8 +528,8 @@ GNUNET_CONTAINER_multihashmap_remove_all (struct GNUNET_CONTAINER_MultiHashMap
  *
  * @param map the map
  * @param key the key to test if a value exists for it
  *
  * @param map the map
  * @param key the key to test if a value exists for it
- * @return GNUNET_YES if such a value exists,
- *         GNUNET_NO if not
+ * @return #GNUNET_YES if such a value exists,
+ *         #GNUNET_NO if not
  */
 int
 GNUNET_CONTAINER_multihashmap_contains (const struct
  */
 int
 GNUNET_CONTAINER_multihashmap_contains (const struct
@@ -568,8 +566,8 @@ GNUNET_CONTAINER_multihashmap_contains (const struct
  * @param map the map
  * @param key the key to test if a value exists for it
  * @param value value to test for
  * @param map the map
  * @param key the key to test if a value exists for it
  * @param value value to test for
- * @return GNUNET_YES if such a value exists,
- *         GNUNET_NO if not
+ * @return #GNUNET_YES if such a value exists,
+ *         #GNUNET_NO if not
  */
 int
 GNUNET_CONTAINER_multihashmap_contains_value (const struct
  */
 int
 GNUNET_CONTAINER_multihashmap_contains_value (const struct
@@ -644,7 +642,7 @@ grow (struct GNUNET_CONTAINER_MultiHashMap *map)
       struct BigMapEntry *bme;
 
       while (NULL != (bme = old_map[i].bme))
       struct BigMapEntry *bme;
 
       while (NULL != (bme = old_map[i].bme))
-      {        
+      {
        old_map[i].bme = bme->next;
        idx = idx_of (map, &bme->key);
        bme->next = new_map[idx].bme;
        old_map[i].bme = bme->next;
        idx = idx_of (map, &bme->key);
        bme->next = new_map[idx].bme;
@@ -663,14 +661,14 @@ grow (struct GNUNET_CONTAINER_MultiHashMap *map)
  * @param key key to use
  * @param value value to use
  * @param opt options for put
  * @param key key to use
  * @param value value to use
  * @param opt options for put
- * @return GNUNET_OK on success,
- *         GNUNET_NO if a value was replaced (with REPLACE)
- *         GNUNET_SYSERR if UNIQUE_ONLY was the option and the
+ * @return #GNUNET_OK on success,
+ *         #GNUNET_NO if a value was replaced (with REPLACE)
+ *         #GNUNET_SYSERR if UNIQUE_ONLY was the option and the
  *                       value already exists
  */
 int
 GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
  *                       value already exists
  */
 int
 GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
-                                   const struct GNUNET_HashCode *key, 
+                                   const struct GNUNET_HashCode *key,
                                   void *value,
                                    enum GNUNET_CONTAINER_MultiHashMapOption opt)
 {
                                   void *value,
                                    enum GNUNET_CONTAINER_MultiHashMapOption opt)
 {
@@ -686,7 +684,7 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
     {
       struct SmallMapEntry *sme;
 
     {
       struct SmallMapEntry *sme;
 
-      for (sme = me.sme; NULL != sme; sme = sme->next)      
+      for (sme = me.sme; NULL != sme; sme = sme->next)
        if (0 == memcmp (key, sme->key, sizeof (struct GNUNET_HashCode)))
        {
          if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
        if (0 == memcmp (key, sme->key, sizeof (struct GNUNET_HashCode)))
        {
          if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
@@ -699,7 +697,7 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
     {
       struct BigMapEntry *bme;
 
     {
       struct BigMapEntry *bme;
 
-      for (bme = me.bme; NULL != bme; bme = bme->next)      
+      for (bme = me.bme; NULL != bme; bme = bme->next)
        if (0 == memcmp (key, &bme->key, sizeof (struct GNUNET_HashCode)))
        {
          if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
        if (0 == memcmp (key, &bme->key, sizeof (struct GNUNET_HashCode)))
        {
          if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
@@ -717,8 +715,8 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
   if (map->use_small_entries)
   {
     struct SmallMapEntry *sme;
   if (map->use_small_entries)
   {
     struct SmallMapEntry *sme;
-    
-    sme = GNUNET_malloc (sizeof (struct SmallMapEntry));
+
+    sme = GNUNET_new (struct SmallMapEntry);
     sme->key = key;
     sme->value = value;
     sme->next = map->map[i].sme;
     sme->key = key;
     sme->value = value;
     sme->next = map->map[i].sme;
@@ -727,8 +725,8 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
   else
   {
     struct BigMapEntry *bme;
   else
   {
     struct BigMapEntry *bme;
-    
-    bme = GNUNET_malloc (sizeof (struct BigMapEntry));
+
+    bme = GNUNET_new (struct BigMapEntry);
     bme->key = *key;
     bme->value = value;
     bme->next = map->map[i].bme;
     bme->key = *key;
     bme->value = value;
     bme->next = map->map[i].bme;
@@ -747,7 +745,7 @@ GNUNET_CONTAINER_multihashmap_put (struct GNUNET_CONTAINER_MultiHashMap *map,
  * @param it function to call on each entry
  * @param it_cls extra argument to it
  * @return the number of key value pairs processed,
  * @param it function to call on each entry
  * @param it_cls extra argument to it
  * @return the number of key value pairs processed,
- *         GNUNET_SYSERR if it aborted iteration
+ *         #GNUNET_SYSERR if it aborted iteration
  */
 int
 GNUNET_CONTAINER_multihashmap_get_multiple (const struct
  */
 int
 GNUNET_CONTAINER_multihashmap_get_multiple (const struct
@@ -763,9 +761,9 @@ GNUNET_CONTAINER_multihashmap_get_multiple (const struct
   me = map->map[idx_of (map, key)];
   if (map->use_small_entries)
   {
   me = map->map[idx_of (map, key)];
   if (map->use_small_entries)
   {
-    struct SmallMapEntry *sme;  
+    struct SmallMapEntry *sme;
     struct SmallMapEntry *nxt;
     struct SmallMapEntry *nxt;
-  
+
     nxt = me.sme;
     while (NULL != (sme = nxt))
     {
     nxt = me.sme;
     while (NULL != (sme = nxt))
     {
@@ -779,9 +777,9 @@ GNUNET_CONTAINER_multihashmap_get_multiple (const struct
   }
   else
   {
   }
   else
   {
-    struct BigMapEntry *bme;  
+    struct BigMapEntry *bme;
     struct BigMapEntry *nxt;
     struct BigMapEntry *nxt;
-  
+
     nxt = me.bme;
     while (NULL != (bme = nxt))
     {
     nxt = me.bme;
     while (NULL != (bme = nxt))
     {
@@ -801,7 +799,7 @@ GNUNET_CONTAINER_multihashmap_get_multiple (const struct
  * Create an iterator for a multihashmap.
  * The iterator can be used to retrieve all the elements in the multihashmap
  * one by one, without having to handle all elements at once (in contrast to
  * Create an iterator for a multihashmap.
  * The iterator can be used to retrieve all the elements in the multihashmap
  * one by one, without having to handle all elements at once (in contrast to
- * 'GNUNET_CONTAINER_multihashmap_iterate').  Note that the iterator can not be
+ * GNUNET_CONTAINER_multihashmap_iterate()).  Note that the iterator can not be
  * used anymore if elements have been removed from 'map' after the creation of
  * the iterator, or 'map' has been destroyed.  Adding elements to 'map' may
  * result in skipped or repeated elements.
  * used anymore if elements have been removed from 'map' after the creation of
  * the iterator, or 'map' has been destroyed.  Adding elements to 'map' may
  * result in skipped or repeated elements.
@@ -833,14 +831,15 @@ GNUNET_CONTAINER_multihashmap_iterator_create (const struct GNUNET_CONTAINER_Mul
  * @param iter the iterator to get the next element from
  * @param key pointer to store the key in, can be NULL
  * @param value pointer to store the value in, can be NULL
  * @param iter the iterator to get the next element from
  * @param key pointer to store the key in, can be NULL
  * @param value pointer to store the value in, can be NULL
- * @return GNUNET_YES we returned an element,
- *         GNUNET_NO if we are out of elements
+ * @return #GNUNET_YES we returned an element,
+ *         #GNUNET_NO if we are out of elements
  */
 int
 GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
  */
 int
 GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMapIterator *iter,
-                                             struct GNUNET_HashCode *key, void **value)
+                                             struct GNUNET_HashCode *key,
+                                             const void **value)
 {
 {
-  /* make sure nobody modified the map */
+  /* make sure the map has not been modified */
   GNUNET_assert (iter->modification_counter == iter->map->modification_counter);
 
   /* look for the next entry, skipping empty buckets */
   GNUNET_assert (iter->modification_counter == iter->map->modification_counter);
 
   /* look for the next entry, skipping empty buckets */
@@ -872,7 +871,9 @@ GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMa
         return GNUNET_YES;
       }
     }
         return GNUNET_YES;
       }
     }
-    iter->idx++;
+    iter->idx += 1;
+    if (iter->idx < iter->map->map_length)
+      iter->me = iter->map->map[iter->idx];
   }
 }
 
   }
 }
 
@@ -883,7 +884,7 @@ GNUNET_CONTAINER_multihashmap_iterator_next (struct GNUNET_CONTAINER_MultiHashMa
  * @param iter the iterator to destroy
  */
 void
  * @param iter the iterator to destroy
  */
 void
-GNUNET_CONTAINER_multihashmap_enumerator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
+GNUNET_CONTAINER_multihashmap_iterator_destroy (struct GNUNET_CONTAINER_MultiHashMapIterator *iter)
 {
   GNUNET_free (iter);
 }
 {
   GNUNET_free (iter);
 }