gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r26169 - gnunet/src/ats


From: gnunet
Subject: [GNUnet-SVN] r26169 - gnunet/src/ats
Date: Wed, 20 Feb 2013 18:53:31 +0100

Author: wachs
Date: 2013-02-20 18:53:31 +0100 (Wed, 20 Feb 2013)
New Revision: 26169

Modified:
   gnunet/src/ats/gnunet-service-ats_addresses_mlp.c
   gnunet/src/ats/gnunet-service-ats_addresses_mlp.h
Log:
 changes


Modified: gnunet/src/ats/gnunet-service-ats_addresses_mlp.c
===================================================================
--- gnunet/src/ats/gnunet-service-ats_addresses_mlp.c   2013-02-20 16:24:28 UTC 
(rev 26168)
+++ gnunet/src/ats/gnunet-service-ats_addresses_mlp.c   2013-02-20 17:53:31 UTC 
(rev 26169)
@@ -137,9 +137,8 @@
 
 #define WRITE_MLP GNUNET_NO
 #define DEBUG_ATS GNUNET_NO
-#define VERBOSE_GLPK GNUNET_YES
+#define VERBOSE_GLPK GNUNET_NO
 
-
 /**
  * Intercept GLPK terminal output
  * @param info the mlp handle
@@ -150,10 +149,13 @@
 mlp_term_hook (void *info, const char *s)
 {
   /* Not needed atm struct MLP_information *mlp = info; */
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s", s);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "%s", s);
   return 1;
 }
 
+
+
+
 /**
  * Delete the MLP problem and free the constrain matrix
  *
@@ -193,6 +195,41 @@
 }
 
 
+/**
+ * Translate ATS properties to text
+ * Just intended for debugging
+ *
+ * @param ats_index the ATS index
+ * @return string with result
+ */
+const char *
+mlp_ats_to_string (int ats_index)
+{
+  switch (ats_index) {
+    case GNUNET_ATS_ARRAY_TERMINATOR:
+      return "GNUNET_ATS_ARRAY_TERMINATOR";
+    case GNUNET_ATS_UTILIZATION_UP:
+      return "GNUNET_ATS_UTILIZATION_UP";
+    case GNUNET_ATS_UTILIZATION_DOWN:
+      return "GNUNET_ATS_UTILIZATION_DOWN";
+    case GNUNET_ATS_COST_LAN:
+      return "GNUNET_ATS_COST_LAN";
+    case GNUNET_ATS_COST_WAN:
+      return "GNUNET_ATS_COST_LAN";
+    case GNUNET_ATS_COST_WLAN:
+      return "GNUNET_ATS_COST_WLAN";
+    case GNUNET_ATS_NETWORK_TYPE:
+      return "GNUNET_ATS_NETWORK_TYPE";
+    case GNUNET_ATS_QUALITY_NET_DELAY:
+      return "GNUNET_ATS_QUALITY_NET_DELAY";
+    case GNUNET_ATS_QUALITY_NET_DISTANCE:
+      return "GNUNET_ATS_QUALITY_NET_DISTANCE";
+    default:
+      GNUNET_break (0);
+      return "unknown";
+  }
+}
+
 #if 0
 
 /**
@@ -276,40 +313,6 @@
   }
 }
 
-/**
- * Translate ATS properties to text
- * Just intended for debugging
- *
- * @param ats_index the ATS index
- * @return string with result
- */
-const char *
-mlp_ats_to_string (int ats_index)
-{
-  switch (ats_index) {
-    case GNUNET_ATS_ARRAY_TERMINATOR:
-      return "GNUNET_ATS_ARRAY_TERMINATOR";
-    case GNUNET_ATS_UTILIZATION_UP:
-      return "GNUNET_ATS_UTILIZATION_UP";
-    case GNUNET_ATS_UTILIZATION_DOWN:
-      return "GNUNET_ATS_UTILIZATION_DOWN";
-    case GNUNET_ATS_COST_LAN:
-      return "GNUNET_ATS_COST_LAN";
-    case GNUNET_ATS_COST_WAN:
-      return "GNUNET_ATS_COST_LAN";
-    case GNUNET_ATS_COST_WLAN:
-      return "GNUNET_ATS_COST_WLAN";
-    case GNUNET_ATS_NETWORK_TYPE:
-      return "GNUNET_ATS_NETWORK_TYPE";
-    case GNUNET_ATS_QUALITY_NET_DELAY:
-      return "GNUNET_ATS_QUALITY_NET_DELAY";
-    case GNUNET_ATS_QUALITY_NET_DISTANCE:
-      return "GNUNET_ATS_QUALITY_NET_DISTANCE";
-    default:
-      GNUNET_break (0);
-      return "unknown";
-  }
-}
 
 /**
  * Find a peer in the DLL
@@ -332,7 +335,391 @@
 }
 
 
+
+#if 0
 /**
+ * Find the required ATS information for an address
+ *
+ * @param addr the address
+ * @param ats_index the desired ATS index
+ *
+ * @return the index on success, otherwise GNUNET_SYSERR
+ */
+static int
+mlp_lookup_ats (struct ATS_Address *addr, int ats_index)
+{
+  struct GNUNET_ATS_Information * ats = addr->ats;
+  int c = 0;
+  int found = GNUNET_NO;
+  for (c = 0; c < addr->ats_count; c++)
+  {
+    if (ats[c].type == ats_index)
+    {
+      found = GNUNET_YES;
+      break;
+    }
+  }
+  if (found == GNUNET_YES)
+    return c;
+  else
+    return GNUNET_SYSERR;
+}
+#endif
+
+/**
+ * Solves the LP problem
+ *
+ * @param mlp the MLP Handle
+ * @param s_ctx context to return results
+ * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
+ */
+static int
+mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct 
GAS_MLP_SolutionContext *s_ctx)
+{
+  int res;
+  struct GNUNET_TIME_Relative duration;
+  struct GNUNET_TIME_Absolute end;
+  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
+
+  /* LP presolver?
+   * Presolver is required if the problem was modified and an existing
+   * valid basis is now invalid */
+  if (mlp->presolver_required == GNUNET_YES)
+    mlp->control_param_lp.presolve = GLP_ON;
+  else
+    mlp->control_param_lp.presolve = GLP_OFF;
+
+  /* Solve LP problem to have initial valid solution */
+lp_solv:
+  res = glp_simplex(mlp->prob, &mlp->control_param_lp);
+  if (res == 0)
+  {
+    /* The LP problem instance has been successfully solved. */
+  }
+  else if (res == GLP_EITLIM)
+  {
+    /* simplex iteration limit has been exceeded. */
+    // TODO Increase iteration limit?
+  }
+  else if (res == GLP_ETMLIM)
+  {
+    /* Time limit has been exceeded.  */
+    // TODO Increase time limit?
+  }
+  else
+  {
+    /* Problem was ill-defined, retry with presolver */
+    if (mlp->presolver_required == GNUNET_NO)
+    {
+      mlp->presolver_required = GNUNET_YES;
+      goto lp_solv;
+    }
+    else
+    {
+      /* Problem was ill-defined, no way to handle that */
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+          "ats-mlp",
+          "Solving LP problem failed: %i %s\n", res, mlp_solve_to_string(res));
+      return GNUNET_SYSERR;
+    }
+  }
+
+  end = GNUNET_TIME_absolute_get ();
+  duration = GNUNET_TIME_absolute_get_difference (start, end);
+  mlp->lp_solved++;
+  mlp->lp_total_duration += duration.rel_value;
+  s_ctx->lp_duration = duration;
+
+  GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", 
duration.rel_value, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)",
+                         mlp->lp_total_duration / mlp->lp_solved,  GNUNET_NO);
+
+  /* Analyze problem status  */
+  res = glp_get_status (mlp->prob);
+  switch (res) {
+    /* solution is optimal */
+    case GLP_OPT:
+    /* solution is feasible */
+    case GLP_FEAS:
+      break;
+
+    /* Problem was ill-defined, no way to handle that */
+    default:
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+          "ats-mlp",
+          "Solving LP problem failed, no solution: %s\n", 
mlp_status_to_string(res));
+      return GNUNET_SYSERR;
+      break;
+  }
+
+  /* solved sucessfully, no presolver required next time */
+  mlp->presolver_required = GNUNET_NO;
+
+  return GNUNET_OK;
+}
+
+
+/**
+ * Solves the MLP problem
+ *
+ * @param mlp the MLP Handle
+ * @param s_ctx context to return results
+ * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
+ */
+int
+mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct 
GAS_MLP_SolutionContext *s_ctx)
+{
+  int res;
+  struct GNUNET_TIME_Relative duration;
+  struct GNUNET_TIME_Absolute end;
+  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
+
+  /* solve MLP problem */
+  res = glp_intopt(mlp->prob, &mlp->control_param_mlp);
+
+  if (res == 0)
+  {
+    /* The MLP problem instance has been successfully solved. */
+  }
+  else if (res == GLP_EITLIM)
+  {
+    /* simplex iteration limit has been exceeded. */
+    // TODO Increase iteration limit?
+  }
+  else if (res == GLP_ETMLIM)
+  {
+    /* Time limit has been exceeded.  */
+    // TODO Increase time limit?
+  }
+  else
+  {
+    /* Problem was ill-defined, no way to handle that */
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+        "ats-mlp",
+        "Solving MLP problem failed:  %s\n", mlp_solve_to_string(res));
+    return GNUNET_SYSERR;
+  }
+
+  end = GNUNET_TIME_absolute_get ();
+  duration = GNUNET_TIME_absolute_get_difference (start, end);
+  mlp->mlp_solved++;
+  mlp->mlp_total_duration += duration.rel_value;
+  s_ctx->mlp_duration = duration;
+
+  GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", 
duration.rel_value, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)",
+                         mlp->mlp_total_duration / mlp->mlp_solved,  
GNUNET_NO);
+
+  /* Analyze problem status  */
+  res = glp_mip_status(mlp->prob);
+  switch (res) {
+    /* solution is optimal */
+    case GLP_OPT:
+    /* solution is feasible */
+    case GLP_FEAS:
+      break;
+
+    /* Problem was ill-defined, no way to handle that */
+    default:
+      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+          "ats-mlp",
+          "Solving MLP problem failed, %s\n\n", mlp_status_to_string(res));
+      return GNUNET_SYSERR;
+      break;
+  }
+
+  return GNUNET_OK;
+}
+
+int GAS_mlp_solve_problem (void *solver, struct GAS_MLP_SolutionContext *ctx);
+
+
+static void
+mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct GAS_MLP_Handle *mlp = cls;
+  struct GAS_MLP_SolutionContext ctx;
+
+  mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
+
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduled problem solving\n");
+
+  if (mlp->addr_in_problem != 0)
+    GAS_mlp_solve_problem(mlp, &ctx);
+}
+
+
+
+
+static void
+update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer 
`%s'\n",
+      GNUNET_i2s (&address->peer));
+
+  GNUNET_assert (NULL != address);
+  GNUNET_assert (NULL != address->solver_information);
+//  GNUNET_assert (NULL != address->ats);
+
+  struct MLP_information *mlpi = address->solver_information;
+  //struct GNUNET_ATS_Information *ats = address->ats;
+  GNUNET_assert (mlpi != NULL);
+
+  int c;
+  for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
+  {
+
+    /* FIXME int index = mlp_lookup_ats(address, mlp->q[c]); */
+    int index = GNUNET_SYSERR;
+
+    if (index == GNUNET_SYSERR)
+      continue;
+    /* FIXME
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value 
`%s': %f\n",
+        GNUNET_i2s (&address->peer),
+        mlp_ats_to_string(mlp->q[c]),
+        (double) ats[index].value);
+
+    int i = mlpi->q_avg_i[c];*/
+    double * qp = mlpi->q[c];
+    /* FIXME
+    qp[i] = (double) ats[index].value;
+    */
+
+    int t;
+    for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
+        GNUNET_i2s (&address->peer),
+        mlp_ats_to_string(mlp->q[c]),
+        t,
+        qp[t]);
+    }
+
+    if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
+      mlpi->q_avg_i[c] ++;
+    else
+      mlpi->q_avg_i[c] = 0;
+
+
+    int c2;
+    int c3;
+    double avg = 0.0;
+    switch (mlp->q[c])
+    {
+      case GNUNET_ATS_QUALITY_NET_DELAY:
+        c3 = 0;
+        for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
+        {
+          if (mlpi->q[c][c2] != -1)
+          {
+            double * t2 = mlpi->q[c] ;
+            avg += t2[c2];
+            c3 ++;
+          }
+        }
+        if ((c3 > 0) && (avg > 0))
+          /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
+          mlpi->q_averaged[c] = (double) c3 / avg;
+        else
+          mlpi->q_averaged[c] = 0.0;
+
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, 
average: %f, weight: %f\n",
+          GNUNET_i2s (&address->peer),
+          mlp_ats_to_string(mlp->q[c]),
+          avg,
+          avg / (double) c3,
+          mlpi->q_averaged[c]);
+
+        break;
+      case GNUNET_ATS_QUALITY_NET_DISTANCE:
+        c3 = 0;
+        for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
+        {
+          if (mlpi->q[c][c2] != -1)
+          {
+            double * t2 = mlpi->q[c] ;
+            avg += t2[c2];
+            c3 ++;
+          }
+        }
+        if ((c3 > 0) && (avg > 0))
+          /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
+          mlpi->q_averaged[c] = (double) c3 / avg;
+        else
+          mlpi->q_averaged[c] = 0.0;
+
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, 
average: %f, weight: %f\n",
+          GNUNET_i2s (&address->peer),
+          mlp_ats_to_string(mlp->q[c]),
+          avg,
+          avg / (double) c3,
+          mlpi->q_averaged[c]);
+
+        break;
+      default:
+        break;
+    }
+
+    if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0))
+    {
+
+      /* Get current number of columns */
+      int found = GNUNET_NO;
+      int cols = glp_get_num_cols(mlp->prob);
+      int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
+      double *val = GNUNET_malloc (cols * sizeof (double) + 1);
+
+      /* Get the matrix row of quality */
+      int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", 
cols, length, mlpi->c_b);
+      int c4;
+      /* Get the index if matrix row of quality */
+      for (c4 = 1; c4 <= length; c4++ )
+      {
+        if (mlpi->c_b == ind[c4])
+        {
+          /* Update the value */
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column 
`%s' row `%s' : %f -> %f\n",
+              mlp_ats_to_string(mlp->q[c]),
+              glp_get_col_name (mlp->prob, ind[c4]),
+              glp_get_row_name (mlp->prob, mlp->r_q[c]),
+              val[c4],
+              mlpi->q_averaged[c]);
+          val[c4] = mlpi->q_averaged[c];
+          found = GNUNET_YES;
+          break;
+        }
+      }
+
+      if (found == GNUNET_NO)
+        {
+
+          ind[length+1] = mlpi->c_b;
+          val[length+1] = mlpi->q_averaged[c];
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]:  %i %f\n", 
length+1,  length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]);
+          glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val);
+        }
+      else
+        {
+        /* Get the index if matrix row of quality */
+        glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
+        }
+
+      GNUNET_free (ind);
+      GNUNET_free (val);
+    }
+  }
+}
+
+#endif
+
+/**
  * Add constraints that are iterating over "forall addresses"
  * and collects all existing peers for "forall peers" constraints
  *
@@ -444,35 +831,6 @@
   return GNUNET_OK;
 }
 
-#if 0
-/**
- * Find the required ATS information for an address
- *
- * @param addr the address
- * @param ats_index the desired ATS index
- *
- * @return the index on success, otherwise GNUNET_SYSERR
- */
-static int
-mlp_lookup_ats (struct ATS_Address *addr, int ats_index)
-{
-  struct GNUNET_ATS_Information * ats = addr->ats;
-  int c = 0;
-  int found = GNUNET_NO;
-  for (c = 0; c < addr->ats_count; c++)
-  {
-    if (ats[c].type == ats_index)
-    {
-      found = GNUNET_YES;
-      break;
-    }
-  }
-  if (found == GNUNET_YES)
-    return c;
-  else
-    return GNUNET_SYSERR;
-}
-#endif
 
 /**
  * Adds the problem constraints for all addresses
@@ -648,7 +1006,6 @@
     glp_set_row_bnds (mlp->prob, peer->r_c2, GLP_FX, 1.0, 1.0);
 
     /* Adding rows for c 9) */
-#if ENABLE_C9
     peer->r_c9 = glp_add_rows (mlp->prob, 1);
     GNUNET_asprintf(&name, "c9_%s", GNUNET_i2s(&peer->id));
     glp_set_row_name (mlp->prob, peer->r_c9, name);
@@ -661,7 +1018,7 @@
     ja[mlp->ci] = mlp->c_r;
     ar[mlp->ci] = -peer->f;
     mlp->ci++;
-#endif
+
     /* For all addresses of this peer */
     while (addr != NULL)
     {
@@ -740,7 +1097,7 @@
  * @return GNUNET_OK to continue
  */
 static int
-create_columns_it (void *cls, const struct GNUNET_HashCode * key, void *value)
+mlp_create_address_columns_it (void *cls, const struct GNUNET_HashCode * key, 
void *value)
 {
   struct GAS_MLP_Handle *mlp = cls;
   struct ATS_Address *address = value;
@@ -748,9 +1105,22 @@
   unsigned int col;
   char *name;
 
-  GNUNET_assert (address->solver_information != NULL);
-  mlpi = address->solver_information;
+  if (NULL != address->solver_information)
+  {
+       GNUNET_free (address->solver_information);
+               address->solver_information = NULL;
+  }
 
+  /* Check if we have to add this peer due to a pending request */
+  if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(mlp->peers, key))
+       return GNUNET_OK;
+
+       LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding column for peer %s address %p\n",
+                       GNUNET_i2s(&address->peer), address);
+
+  mlpi = GNUNET_malloc (sizeof (struct MLP_information));
+  address->solver_information = mlpi;
+
   /* Add bandwidth column */
   col = glp_add_cols (mlp->prob, 2);
   mlpi->c_b = col;
@@ -782,362 +1152,7 @@
   return GNUNET_OK;
 }
 
-
-
 /**
- * Solves the LP problem
- *
- * @param mlp the MLP Handle
- * @param s_ctx context to return results
- * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
- */
-static int
-mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct 
GAS_MLP_SolutionContext *s_ctx)
-{
-  int res;
-  struct GNUNET_TIME_Relative duration;
-  struct GNUNET_TIME_Absolute end;
-  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
-
-  /* LP presolver?
-   * Presolver is required if the problem was modified and an existing
-   * valid basis is now invalid */
-  if (mlp->presolver_required == GNUNET_YES)
-    mlp->control_param_lp.presolve = GLP_ON;
-  else
-    mlp->control_param_lp.presolve = GLP_OFF;
-
-  /* Solve LP problem to have initial valid solution */
-lp_solv:
-  res = glp_simplex(mlp->prob, &mlp->control_param_lp);
-  if (res == 0)
-  {
-    /* The LP problem instance has been successfully solved. */
-  }
-  else if (res == GLP_EITLIM)
-  {
-    /* simplex iteration limit has been exceeded. */
-    // TODO Increase iteration limit?
-  }
-  else if (res == GLP_ETMLIM)
-  {
-    /* Time limit has been exceeded.  */
-    // TODO Increase time limit?
-  }
-  else
-  {
-    /* Problem was ill-defined, retry with presolver */
-    if (mlp->presolver_required == GNUNET_NO)
-    {
-      mlp->presolver_required = GNUNET_YES;
-      goto lp_solv;
-    }
-    else
-    {
-      /* Problem was ill-defined, no way to handle that */
-      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-          "ats-mlp",
-          "Solving LP problem failed: %i %s\n", res, mlp_solve_to_string(res));
-      return GNUNET_SYSERR;
-    }
-  }
-
-  end = GNUNET_TIME_absolute_get ();
-  duration = GNUNET_TIME_absolute_get_difference (start, end);
-  mlp->lp_solved++;
-  mlp->lp_total_duration += duration.rel_value;
-  s_ctx->lp_duration = duration;
-
-  GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO);
-  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", 
duration.rel_value, GNUNET_NO);
-  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)",
-                         mlp->lp_total_duration / mlp->lp_solved,  GNUNET_NO);
-
-  /* Analyze problem status  */
-  res = glp_get_status (mlp->prob);
-  switch (res) {
-    /* solution is optimal */
-    case GLP_OPT:
-    /* solution is feasible */
-    case GLP_FEAS:
-      break;
-
-    /* Problem was ill-defined, no way to handle that */
-    default:
-      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-          "ats-mlp",
-          "Solving LP problem failed, no solution: %s\n", 
mlp_status_to_string(res));
-      return GNUNET_SYSERR;
-      break;
-  }
-
-  /* solved sucessfully, no presolver required next time */
-  mlp->presolver_required = GNUNET_NO;
-
-  return GNUNET_OK;
-}
-
-
-/**
- * Solves the MLP problem
- *
- * @param mlp the MLP Handle
- * @param s_ctx context to return results
- * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
- */
-int
-mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct 
GAS_MLP_SolutionContext *s_ctx)
-{
-  int res;
-  struct GNUNET_TIME_Relative duration;
-  struct GNUNET_TIME_Absolute end;
-  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
-
-  /* solve MLP problem */
-  res = glp_intopt(mlp->prob, &mlp->control_param_mlp);
-
-  if (res == 0)
-  {
-    /* The MLP problem instance has been successfully solved. */
-  }
-  else if (res == GLP_EITLIM)
-  {
-    /* simplex iteration limit has been exceeded. */
-    // TODO Increase iteration limit?
-  }
-  else if (res == GLP_ETMLIM)
-  {
-    /* Time limit has been exceeded.  */
-    // TODO Increase time limit?
-  }
-  else
-  {
-    /* Problem was ill-defined, no way to handle that */
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-        "ats-mlp",
-        "Solving MLP problem failed:  %s\n", mlp_solve_to_string(res));
-    return GNUNET_SYSERR;
-  }
-
-  end = GNUNET_TIME_absolute_get ();
-  duration = GNUNET_TIME_absolute_get_difference (start, end);
-  mlp->mlp_solved++;
-  mlp->mlp_total_duration += duration.rel_value;
-  s_ctx->mlp_duration = duration;
-
-  GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO);
-  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", 
duration.rel_value, GNUNET_NO);
-  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)",
-                         mlp->mlp_total_duration / mlp->mlp_solved,  
GNUNET_NO);
-
-  /* Analyze problem status  */
-  res = glp_mip_status(mlp->prob);
-  switch (res) {
-    /* solution is optimal */
-    case GLP_OPT:
-    /* solution is feasible */
-    case GLP_FEAS:
-      break;
-
-    /* Problem was ill-defined, no way to handle that */
-    default:
-      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
-          "ats-mlp",
-          "Solving MLP problem failed, %s\n\n", mlp_status_to_string(res));
-      return GNUNET_SYSERR;
-      break;
-  }
-
-  return GNUNET_OK;
-}
-
-int GAS_mlp_solve_problem (void *solver, struct GAS_MLP_SolutionContext *ctx);
-
-
-static void
-mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct GAS_MLP_Handle *mlp = cls;
-  struct GAS_MLP_SolutionContext ctx;
-
-  mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
-
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduled problem solving\n");
-
-  if (mlp->addr_in_problem != 0)
-    GAS_mlp_solve_problem(mlp, &ctx);
-}
-
-
-
-
-static void
-update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer 
`%s'\n",
-      GNUNET_i2s (&address->peer));
-
-  GNUNET_assert (NULL != address);
-  GNUNET_assert (NULL != address->solver_information);
-//  GNUNET_assert (NULL != address->ats);
-
-  struct MLP_information *mlpi = address->solver_information;
-  //struct GNUNET_ATS_Information *ats = address->ats;
-  GNUNET_assert (mlpi != NULL);
-
-  int c;
-  for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
-  {
-
-    /* FIXME int index = mlp_lookup_ats(address, mlp->q[c]); */
-    int index = GNUNET_SYSERR;
-
-    if (index == GNUNET_SYSERR)
-      continue;
-    /* FIXME
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value 
`%s': %f\n",
-        GNUNET_i2s (&address->peer),
-        mlp_ats_to_string(mlp->q[c]),
-        (double) ats[index].value);
-
-    int i = mlpi->q_avg_i[c];*/
-    double * qp = mlpi->q[c];
-    /* FIXME
-    qp[i] = (double) ats[index].value;
-    */
-
-    int t;
-    for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
-        GNUNET_i2s (&address->peer),
-        mlp_ats_to_string(mlp->q[c]),
-        t,
-        qp[t]);
-    }
-
-    if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
-      mlpi->q_avg_i[c] ++;
-    else
-      mlpi->q_avg_i[c] = 0;
-
-
-    int c2;
-    int c3;
-    double avg = 0.0;
-    switch (mlp->q[c])
-    {
-      case GNUNET_ATS_QUALITY_NET_DELAY:
-        c3 = 0;
-        for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
-        {
-          if (mlpi->q[c][c2] != -1)
-          {
-            double * t2 = mlpi->q[c] ;
-            avg += t2[c2];
-            c3 ++;
-          }
-        }
-        if ((c3 > 0) && (avg > 0))
-          /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
-          mlpi->q_averaged[c] = (double) c3 / avg;
-        else
-          mlpi->q_averaged[c] = 0.0;
-
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, 
average: %f, weight: %f\n",
-          GNUNET_i2s (&address->peer),
-          mlp_ats_to_string(mlp->q[c]),
-          avg,
-          avg / (double) c3,
-          mlpi->q_averaged[c]);
-
-        break;
-      case GNUNET_ATS_QUALITY_NET_DISTANCE:
-        c3 = 0;
-        for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
-        {
-          if (mlpi->q[c][c2] != -1)
-          {
-            double * t2 = mlpi->q[c] ;
-            avg += t2[c2];
-            c3 ++;
-          }
-        }
-        if ((c3 > 0) && (avg > 0))
-          /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
-          mlpi->q_averaged[c] = (double) c3 / avg;
-        else
-          mlpi->q_averaged[c] = 0.0;
-
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, 
average: %f, weight: %f\n",
-          GNUNET_i2s (&address->peer),
-          mlp_ats_to_string(mlp->q[c]),
-          avg,
-          avg / (double) c3,
-          mlpi->q_averaged[c]);
-
-        break;
-      default:
-        break;
-    }
-
-    if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0))
-    {
-
-      /* Get current number of columns */
-      int found = GNUNET_NO;
-      int cols = glp_get_num_cols(mlp->prob);
-      int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
-      double *val = GNUNET_malloc (cols * sizeof (double) + 1);
-
-      /* Get the matrix row of quality */
-      int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", 
cols, length, mlpi->c_b);
-      int c4;
-      /* Get the index if matrix row of quality */
-      for (c4 = 1; c4 <= length; c4++ )
-      {
-        if (mlpi->c_b == ind[c4])
-        {
-          /* Update the value */
-          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column 
`%s' row `%s' : %f -> %f\n",
-              mlp_ats_to_string(mlp->q[c]),
-              glp_get_col_name (mlp->prob, ind[c4]),
-              glp_get_row_name (mlp->prob, mlp->r_q[c]),
-              val[c4],
-              mlpi->q_averaged[c]);
-          val[c4] = mlpi->q_averaged[c];
-          found = GNUNET_YES;
-          break;
-        }
-      }
-
-      if (found == GNUNET_NO)
-        {
-
-          ind[length+1] = mlpi->c_b;
-          val[length+1] = mlpi->q_averaged[c];
-          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]:  %i %f\n", 
length+1,  length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]);
-          glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val);
-        }
-      else
-        {
-        /* Get the index if matrix row of quality */
-        glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
-        }
-
-      GNUNET_free (ind);
-      GNUNET_free (val);
-    }
-  }
-}
-
-#endif
-
-/**
  * Create the MLP problem
  *
  * @param mlp the MLP handle
@@ -1211,10 +1226,10 @@
   }
 
   /* Add columns for addresses */
-  //GNUNET_CONTAINER_multihashmap_iterate (addresses, create_columns_it, mlp);
+  GNUNET_CONTAINER_multihashmap_iterate (addresses, 
mlp_create_address_columns_it, mlp);
 
   /* Add constraints */
-  //mlp_add_constraints_all_addresses (mlp, addresses);
+  mlp_add_constraints_all_addresses (mlp, addresses);
 
   /* Load the matrix */
   glp_load_matrix(mlp->prob, elements /*(mlp->ci-1)*/, mlp->ia, mlp->ja, 
mlp->ar);
@@ -1227,11 +1242,11 @@
  * Solves the MLP problem
  *
  * @param solver the MLP Handle
- * @param ctx solution context
+ * @param addresses the address hashmap
  * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
  */
 int
-GAS_mlp_solve_problem (void *solver)
+GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * 
addresses)
 {
        struct GAS_MLP_Handle *mlp = solver;
        int res = 0;
@@ -1248,7 +1263,7 @@
        {
                        LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem size changed, 
rebuilding\n");
                        mlp_delete_problem (mlp);
-                       mlp_create_problem (mlp, NULL);
+                       mlp_create_problem (mlp, addresses);
        }
        else
        {
@@ -1416,10 +1431,15 @@
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address for peer `%s' without 
address request \n", GNUNET_i2s(&address->peer));
        return;
   }
+  if (NULL != address->solver_information)
+  {
+               GNUNET_break (0);
+  }
+
        LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address for peer `%s' with 
address request \n", GNUNET_i2s(&address->peer));
        /* Problem size changed: new address for peer with pending request */
        mlp->mlp_prob_changed = GNUNET_YES;
-       GAS_mlp_solve_problem (solver);
+       GAS_mlp_solve_problem (solver, addresses);
 }
 
 /**
@@ -1468,7 +1488,7 @@
 
        /* Problem size changed: new address for peer with pending request */
        mlp->mlp_prob_updated = GNUNET_YES;
-       GAS_mlp_solve_problem (solver);
+       GAS_mlp_solve_problem (solver, addresses);
   return;
 
 #if 0
@@ -1584,6 +1604,11 @@
        GNUNET_assert (NULL != address);
 
        /* TODO Delete address here */
+       if (NULL != address->solver_information)
+       {
+                       GNUNET_free (address->solver_information);
+                       address->solver_information = NULL;
+       }
 
   /* Is this peer included in the problem? */
   if (NULL == (p = GNUNET_CONTAINER_multihashmap_get (mlp->peers, 
&address->peer.hashPubKey)))
@@ -1595,7 +1620,7 @@
 
        /* Problem size changed: new address for peer with pending request */
        mlp->mlp_prob_changed = GNUNET_YES;
-       GAS_mlp_solve_problem (solver);
+       GAS_mlp_solve_problem (solver, addresses);
   return;
 
 #if 0
@@ -1715,7 +1740,7 @@
          /* Added new peer, we have to rebuild problem before solving */
          mlp->mlp_prob_changed = GNUNET_YES;
   }
-  GAS_mlp_solve_problem (mlp);
+  GAS_mlp_solve_problem (mlp, addresses);
 
   /* Get prefered address */
   GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
@@ -2081,7 +2106,7 @@
 
   /* Setup GLPK */
   /* Redirect GLPK output to GNUnet logging */
-  glp_error_hook((void *) mlp, &mlp_term_hook);
+  glp_term_hook (&mlp_term_hook, (void *) mlp);
 
   /* Init LP solving parameters */
   glp_init_smcp(&mlp->control_param_lp);

Modified: gnunet/src/ats/gnunet-service-ats_addresses_mlp.h
===================================================================
--- gnunet/src/ats/gnunet-service-ats_addresses_mlp.h   2013-02-20 16:24:28 UTC 
(rev 26168)
+++ gnunet/src/ats/gnunet-service-ats_addresses_mlp.h   2013-02-20 17:53:31 UTC 
(rev 26169)
@@ -350,11 +350,11 @@
  * Solves the MLP problem
  *
  * @param solver the MLP Handle
- * @param ctx solution context
+ * @param addresses the address hashmap
  * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
  */
 int
-GAS_mlp_solve_problem (void *solver);
+GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * 
addresses);
 
 
 /**




reply via email to

[Prev in Thread] Current Thread [Next in Thread]