tolerate additional IPv4 address now available for gnunet.org
[oweals/gnunet.git] / src / rps / gnunet-service-rps_view.c
index 26a0b22bcd673ba409608379a060d9f5a51c5ed1..8a0cae21eb54463935c829557b8b76b36a6b1355 100644 (file)
@@ -14,6 +14,8 @@
     
      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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 
 /**
 #include "gnunet-service-rps_view.h"
 #include <inttypes.h>
 
+struct View
+{
+  /**
+   * Array containing the peers
+   */
+  struct GNUNET_PeerIdentity *array;
 
-/**
- * Array containing the peers
- */
-static struct GNUNET_PeerIdentity *array;
-
-/**
- * (Maximum) length of the view
- */
-static uint32_t length;
+  /**
+   * (Maximum) length of the view
+   */
+  uint32_t length;
 
-/**
- * Multipeermap containing the peers
- */
-static struct GNUNET_CONTAINER_MultiPeerMap *mpm;
+  /**
+   * Multipeermap containing the peers
+   */
+  struct GNUNET_CONTAINER_MultiPeerMap *mpm;
+};
 
 
 /**
  * Create an empty view.
  *
  * @param len the maximum length for the view
+ * @return The newly created view
  */
-void
+struct View *
 View_create (uint32_t len)
 {
-  length = len;
-  array = GNUNET_new_array (len, struct GNUNET_PeerIdentity);
-  mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be
-                                                                * set to _YES */
+  struct View *view;
+
+  view = GNUNET_new (struct View);
+  view->length = len;
+  view->array = GNUNET_new_array (len, struct GNUNET_PeerIdentity);
+  view->mpm =
+    GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be
+                                                            * set to _YES */
+  return view;
 }
 
+
 /**
  * Change length of view
  *
  * If size is decreased, peers with higher indices are removed.
  *
+ * @param view The view that is changed
  * @param len the (maximum) length for the view
  */
 void
-View_change_len (uint32_t len)
+View_change_len (struct View *view,
+                 uint32_t len)
 {
   uint32_t i;
   uint32_t *index;
 
-  if (GNUNET_CONTAINER_multipeermap_size (mpm) < len)
+  if (GNUNET_CONTAINER_multipeermap_size (view->mpm) < len)
   { /* Simply shrink */
     /* We might simply clear and free the left over space */
-    GNUNET_array_grow (array, length, len);
+    GNUNET_array_grow (view->array, view->length, len);
   }
   else /* We have to remove elements */
   {
     /* TODO find a way to preserve indices */
     for (i = 0; i < len; i++)
     {
-      index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]);
+      index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
       GNUNET_assert (NULL != index);
       GNUNET_free (index);
     }
-    GNUNET_array_grow (array, length, len);
-    GNUNET_CONTAINER_multipeermap_destroy (mpm);
-    mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO);
+    GNUNET_array_grow (view->array, view->length, len);
+    GNUNET_CONTAINER_multipeermap_destroy (view->mpm);
+    view->mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO);
     for (i = 0; i < len; i++)
     {
       index = GNUNET_new (uint32_t);
       *index = i;
-      GNUNET_CONTAINER_multipeermap_put (mpm, &array[i], index,
+      GNUNET_CONTAINER_multipeermap_put (view->mpm, &view->array[i], index,
           GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
     }
   }
-  GNUNET_assert (length == len);
+  GNUNET_assert (view->length == len);
 }
 
+
 /**
  * Get the view as an array
  *
+ * @param view The view of which the array representation is of interest
  * @return the view in array representation
  */
 const struct GNUNET_PeerIdentity *
-View_get_as_array ()
+View_get_as_array (const struct View *view)
 {
-  return array;
+  return view->array;
 }
 
+
 /**
  * Get the size of the view
  *
+ * @param view The view of which the size should be returned
  * @return current number of actually contained peers
  */
 unsigned int
-View_size ()
+View_size (const struct View *view)
 {
-  return GNUNET_CONTAINER_multipeermap_size (mpm);
+  return GNUNET_CONTAINER_multipeermap_size (view->mpm);
 }
 
+
 /**
  * Insert peer into the view
  *
+ * @param view The view to put the peer into
  * @param peer the peer to insert
  *
  * @return GNUNET_OK if peer was actually inserted
  *         GNUNET_NO if peer was not inserted
  */
 int
-View_put (const struct GNUNET_PeerIdentity *peer)
+View_put (struct View *view,
+          const struct GNUNET_PeerIdentity *peer)
 {
   uint32_t *index;
 
-  if ((length <= View_size ()) || /* If array is 'full' */
-      (GNUNET_YES == View_contains_peer (peer)))
+  if ((view->length <= View_size (view)) || /* If array is 'full' */
+      (GNUNET_YES == View_contains_peer (view, peer)))
   {
     return GNUNET_NO;
   }
   else
   {
     index = GNUNET_new (uint32_t);
-    *index = (uint32_t) View_size ();
-    array[*index] = *peer;
-    GNUNET_CONTAINER_multipeermap_put (mpm, peer, index,
+    *index = (uint32_t) View_size (view);
+    view->array[*index] = *peer;
+    GNUNET_CONTAINER_multipeermap_put (view->mpm, peer, index,
         GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
     return GNUNET_OK;
   }
 }
 
+
 /**
  * Check whether view contains a peer
  *
+ * @param view The which is checked for a peer
  * @param peer the peer to check for
  *
  * @return GNUNET_OK if view contains peer
  *         GNUNET_NO otherwise
  */
 int
-View_contains_peer (const struct GNUNET_PeerIdentity *peer)
+View_contains_peer (const struct View *view,
+                    const struct GNUNET_PeerIdentity *peer)
 {
-  return GNUNET_CONTAINER_multipeermap_contains (mpm, peer);
+  return GNUNET_CONTAINER_multipeermap_contains (view->mpm, peer);
 }
 
+
 /**
  * Remove peer from view
  *
+ * @param view The view of which to remove the peer
  * @param peer the peer to remove
  *
  * @return GNUNET_OK if view contained peer and removed it successfully
  *         GNUNET_NO if view does not contain peer
  */
 int
-View_remove_peer (const struct GNUNET_PeerIdentity *peer)
+View_remove_peer (struct View *view,
+                  const struct GNUNET_PeerIdentity *peer)
 {
   uint32_t *index;
   uint32_t *swap_index;
   uint32_t last_index;
 
-  if (GNUNET_NO == View_contains_peer (peer))
+  if (GNUNET_NO == View_contains_peer (view, peer))
   {
     return GNUNET_NO;
   }
-  index = GNUNET_CONTAINER_multipeermap_get (mpm, peer);
+  index = GNUNET_CONTAINER_multipeermap_get (view->mpm, peer);
   GNUNET_assert (NULL != index);
-  last_index = View_size () - 1;
+  last_index = View_size (view) - 1;
   if (*index < last_index)
   { /* Fill the 'gap' in the array with the last peer */
-    array[*index] = array[last_index];
-    GNUNET_assert (GNUNET_YES == View_contains_peer (&array[last_index]));
-    swap_index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[last_index]);
+    view->array[*index] = view->array[last_index];
+    GNUNET_assert (GNUNET_YES == View_contains_peer (view,
+                                                     &view->array[last_index]));
+    swap_index = GNUNET_CONTAINER_multipeermap_get (view->mpm,
+                                                    &view->array[last_index]);
     GNUNET_assert (NULL != swap_index);
     *swap_index = *index;
     GNUNET_free (index);
   }
-  GNUNET_CONTAINER_multipeermap_remove_all (mpm, peer);
+  GNUNET_CONTAINER_multipeermap_remove_all (view->mpm, peer);
   return GNUNET_OK;
 }
 
+
 /**
  * Get a peer by index
  *
+ * @param view the view of which to get the peer
  * @param index the index of the peer to get
  *
  * @return peer to the corresponding index.
  *         NULL if this index is not known
  */
 const struct GNUNET_PeerIdentity *
-View_get_peer_by_index (uint32_t index)
+View_get_peer_by_index (const struct View *view,
+                        uint32_t index)
 {
-  if (index < GNUNET_CONTAINER_multipeermap_size (mpm))
+  if (index < GNUNET_CONTAINER_multipeermap_size (view->mpm))
   {
-    return &array[index];
+    return &view->array[index];
   }
   else
   {
@@ -219,42 +250,43 @@ View_get_peer_by_index (uint32_t index)
   }
 }
 
+
 /**
- * Clear the custom peer map
- *
- * @param c_peer_map the custom peer map to look in
+ * Clear the view
  *
- * @return size of the map
+ * @param view The view to clear
  */
 void
-View_clear ()
+View_clear (struct View *view)
 {
-  for (uint32_t i = 0; 0 < View_size (); i++)
+  for (uint32_t i = 0; 0 < View_size (view); i++)
   { /* Need to free indices stored at peers */
     uint32_t *index;
 
     GNUNET_assert (GNUNET_YES ==
-        GNUNET_CONTAINER_multipeermap_contains (mpm, &array[i]));
-    index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]);
+        GNUNET_CONTAINER_multipeermap_contains (view->mpm, &view->array[i]));
+    index = GNUNET_CONTAINER_multipeermap_get (view->mpm, &view->array[i]);
     GNUNET_assert (NULL != index);
     GNUNET_free (index);
-    GNUNET_CONTAINER_multipeermap_remove_all (mpm, &array[i]);
+    GNUNET_CONTAINER_multipeermap_remove_all (view->mpm, &view->array[i]);
   }
-  GNUNET_assert (0 == View_size ());
+  GNUNET_assert (0 == View_size (view));
 }
 
 
 /**
- * Destroy peermap.
+ * Destroy view.
  *
- * @param c_peer_map the map to destroy
+ * @param view the view to destroy
  */
 void
-View_destroy ()
+View_destroy (struct View *view)
 {
-  View_clear ();
-  GNUNET_free (array);
-  GNUNET_CONTAINER_multipeermap_destroy (mpm);
+  View_clear (view);
+  GNUNET_free (view->array);
+  view->array = NULL;
+  GNUNET_CONTAINER_multipeermap_destroy (view->mpm);
+  GNUNET_free (view);
 }
 
 /* end of gnunet-service-rps_view.c */