- functionality for "for all peers" constraints
authorMatthias Wachs <wachs@net.in.tum.de>
Wed, 18 Jan 2012 14:42:15 +0000 (14:42 +0000)
committerMatthias Wachs <wachs@net.in.tum.de>
Wed, 18 Jan 2012 14:42:15 +0000 (14:42 +0000)
src/ats/gnunet-service-ats_addresses.c
src/ats/gnunet-service-ats_addresses.h
src/ats/gnunet-service-ats_addresses_mlp.c
src/ats/gnunet-service-ats_addresses_mlp.h
src/ats/test_ats_mlp.c

index 06eee9fb39040d55cae982e562eb51e576092391..ae78858e627b0ab77a53263cf4902f9b5bb1b7c3 100644 (file)
@@ -154,7 +154,9 @@ create_address (const struct GNUNET_PeerIdentity *peer,
   memcpy (&aa[1], plugin_addr, plugin_addr_len);
   aa->plugin = GNUNET_strdup (plugin_name);
   aa->session_id = session_id;
-
+  aa->mlp_information = NULL;
+  aa->next = NULL;
+  aa->prev = NULL;
   return aa;
 }
 
index a5230b4f3995990b297dd70f560ca9d28534bd9f..33ff5869dc18dcbfe88e4562afa3398408c6cbe0 100644 (file)
 
 struct ATS_Address
 {
+  struct ATS_Address *next;
+
+  struct ATS_Address *prev;
+
   struct GNUNET_PeerIdentity peer;
 
   size_t addr_len;
index c3a7cfb5c9d43e420db980815d1bc5050584949b..3899e126ad863ad1dcaf4cd925df45c4766932dc 100644 (file)
@@ -34,7 +34,7 @@
 #endif
 #include "float.h"
 
-#define DEBUG_ATS GNUNET_YES
+#define DEBUG_ATS GNUNET_NO
 
 /* A very big value */
 #define M DBL_MAX
@@ -325,12 +325,14 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
   double *ar= GNUNET_malloc (pi * sizeof (double));
   mlp->ar = ar;
 
-  /* Adding constraint rows */
-  /* Feasibility constraints */
-
-  /* c 1) bandwidth capping */
-  /* c 3) minimum bandwidth */
-  /* c 4) minimum number of connections */
+  /* Adding constraint rows
+   * This constraints are kind of "for all addresses"
+   * Feasibility constraints:
+   *
+   * c 1) bandwidth capping
+   * c 3) minimum bandwidth
+   * c 4) minimum number of connections
+   */
   mlp->r_c4 = glp_add_rows (mlp->prob, 1);
   glp_set_row_bnds (mlp->prob, mlp->r_c4, GLP_LO, mlp->n_min, 0.0);
 
@@ -811,6 +813,37 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
     address->mlp_information = mlpi;
     mlp->addr_in_problem ++;
 
+    /* Check for and add peer */
+    struct ATS_Peer *peer = mlp->peer_head;
+    while (peer != NULL)
+    {
+      if (0 == memcmp (&address->peer, &peer->id, sizeof (struct GNUNET_PeerIdentity)))
+        break;
+      peer = peer->next;
+    }
+    if (peer == NULL)
+    {
+#if DEBUG_ATS
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding new peer `%s'\n", GNUNET_i2s (&address->peer));
+#endif
+      peer = GNUNET_malloc (sizeof (struct ATS_Peer));
+      peer->head = NULL;
+      peer->tail = NULL;
+      memcpy (&peer->id, &address->peer, sizeof (struct GNUNET_PeerIdentity));
+      GNUNET_assert(address->prev == NULL);
+      GNUNET_assert(address->next == NULL);
+      GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address);
+      GNUNET_CONTAINER_DLL_insert (mlp->peer_head, mlp->peer_tail, peer);
+    }
+    else
+    {
+#if DEBUG_ATS
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding address to peer `%s'\n", GNUNET_i2s (&address->peer));
+#endif
+      GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address);
+    }
+
+
     /* Add bandwidth column */
     col = glp_add_cols (mlp->prob, 2);
     mlpi->c_b = col;
@@ -836,8 +869,12 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
     glp_set_col_kind (mlp->prob, mlpi->c_n, GLP_IV);
     /* Objective function coefficient == 0 */
     glp_set_obj_coef (mlp->prob, mlpi->c_n, 0);
-
-    /* Add */
+  }
+  else
+  {
+#if DEBUG_ATS
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating existing address to peer `%s'\n", GNUNET_i2s (&address->peer));
+#endif
   }
 
   /* Recalculate */
@@ -869,6 +906,30 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
     mlp->addr_in_problem --;
   }
 
+  /* Remove from peer list */
+  struct ATS_Peer *head = mlp->peer_head;
+  while (head != NULL)
+  {
+    if (0 == memcmp (&address->peer, &head->id, sizeof (struct GNUNET_PeerIdentity)))
+      break;
+    head = head->next;
+  }
+  GNUNET_assert (head != NULL);
+#if DEBUG_ATS
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting address for `%s'\n", GNUNET_i2s (&address->peer));
+#endif
+  GNUNET_CONTAINER_DLL_remove (head->head, head->tail, address);
+
+  if ((head->head == NULL) && (head->tail == NULL))
+  {
+    /* No address for peer left, remove peer */
+#if DEBUG_ATS
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting peer `%s'\n", GNUNET_i2s (&address->peer));
+#endif
+    GNUNET_CONTAINER_DLL_remove (mlp->peer_head, mlp->peer_tail, head);
+    GNUNET_free (head);
+  }
+
   /* Update problem */
 
   /* Recalculate */
index 3878b0f5f85824e28bd6739fb70db57910ca91de..2383f24ef65972dc22aacdc435728bd87da55daf 100644 (file)
 #define MLP_MAX_EXEC_DURATION   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3)
 #define MLP_MAX_ITERATIONS      INT_MAX
 
+struct ATS_Peer
+{
+  struct ATS_Peer *next;
+  struct ATS_Peer *prev;
+
+  struct GNUNET_PeerIdentity id;
+
+  struct ATS_Address *head;
+  struct ATS_Address *tail;
+};
+
 /**
  * MLP Handle
  */
@@ -135,6 +146,9 @@ struct GAS_MLP_Handle
 
   /* Information about the problem */
 
+  struct ATS_Peer *peer_head;
+  struct ATS_Peer *peer_tail;
+
   /* current problem matrix */
   /* row index array */
   int *ia;
index 48916d2d93e630530ade9d080f6be1d53cc2ee2d..94009ee4e1531e5adfb596770accc5136c47ecdf 100644 (file)
@@ -60,14 +60,26 @@ check (void *cls, char *const *args, const char *cfgfile,
   addresses = GNUNET_CONTAINER_multihashmap_create (10);
 
   GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &addr.peer.hashPubKey);
+  addr.mlp_information = NULL;
+  addr.next = NULL;
+  addr.prev = NULL;
   addr.plugin = strdup ("dummy");
   GNUNET_CONTAINER_multihashmap_put(addresses, &addr.peer.hashPubKey, &addr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 
   mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
 
-  GAS_mlp_address_update(mlp, addresses, &addr);
+  /* Add a new address */
+  GAS_mlp_address_update (mlp, addresses, &addr);
 
   GNUNET_assert (mlp != NULL);
+  GNUNET_assert (mlp->addr_in_problem == 1);
+
+  /* Update an new address */
+  GAS_mlp_address_update (mlp, addresses, &addr);
+  GNUNET_assert (mlp->addr_in_problem == 1);
+
+  /* Delete an address */
+  GAS_mlp_address_delete (mlp, addresses, &addr);
 
   GAS_mlp_done (mlp);