fixing log level
[oweals/gnunet.git] / src / ats / gnunet-service-ats-solver_proportional.c
index 56603d12c4eb4099edb204e137b1c1a12ace8a34..ddd15eb1d4eae22955cd1cb5254d63b402f402aa 100644 (file)
@@ -27,7 +27,6 @@
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet-service-ats_addresses.h"
-#include "gnunet-service-ats_normalization.h"
 #include "gnunet_statistics_service.h"
 
 #define LOG(kind,...) GNUNET_log_from (kind, "ats-proportional",__VA_ARGS__)
@@ -222,9 +221,39 @@ struct GAS_PROPORTIONAL_Handle
   /**
    * Statistics handle
    */
-
   struct GNUNET_STATISTICS_Handle *stats;
 
+  /**
+   * Bandwidth changed callback
+   */
+  GAS_bandwidth_changed_cb bw_changed;
+
+  /**
+   * Bandwidth changed callback cls
+   */
+  void *bw_changed_cls;
+
+  /**
+   * ATS function to get preferences
+   */
+  GAS_get_preferences get_preferences;
+
+  /**
+   * Closure for ATS function to get preferences
+   */
+  void *get_preferences_cls;
+
+  /**
+   * Bulk lock
+   */
+  int bulk_lock;
+
+  /**
+   * Number of changes while solver was locked
+   */
+  int bulk_requests;
+
+
   /**
    * Total number of addresses for solver
    */
@@ -245,20 +274,6 @@ struct GAS_PROPORTIONAL_Handle
    */
   unsigned int networks;
 
-  /**
-   * Callback
-   */
-  GAS_bandwidth_changed_cb bw_changed;
-
-  /**
-   * Callback cls
-   */
-  void *bw_changed_cls;
-
-  struct GNUNET_CONTAINER_MultiHashMap *prefs;
-
-  struct PreferenceClient *pc_head;
-  struct PreferenceClient *pc_tail;
 };
 
 
@@ -351,6 +366,7 @@ struct AddressWrapper
 static int
 is_bandwidth_available_in_network (struct Network *net)
 {
+       GNUNET_assert (NULL != net);
   unsigned int na = net->active_addresses + 1;
   uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
   if (((net->total_quota_in / na) > min_bw) &&
@@ -400,6 +416,13 @@ distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
   unsigned long long assigned_quota_out = 0;
   struct AddressWrapper *cur;
 
+
+       if (GNUNET_YES == s->bulk_lock)
+       {
+               s->bulk_requests++;
+               return;
+       }
+
   LOG (GNUNET_ERROR_TYPE_DEBUG,
               "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
               net->desc, net->active_addresses, net->total_quota_in, net->total_quota_in);
@@ -432,24 +455,18 @@ distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
   {
       if (GNUNET_YES == cur->addr->active)
       {
-        t = GAS_normalization_get_preferences (&cur->addr->peer);
-        if (NULL == t)
-        {
-               total_prefs += DEFAULT_REL_PREFERENCE;
-        }
-        else
-        {
-               peer_prefs = 0.0;
-               for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
-               {
-                       if (c != GNUNET_ATS_PREFERENCE_END)
-                       {
-                               //fprintf (stderr, "VALUE[%u] %s %.3f \n", c, GNUNET_i2s (&cur->addr->peer), t[c]);
-                               peer_prefs += t[c];
-                       }
-               }
-               total_prefs += (peer_prefs / (GNUNET_ATS_PreferenceCount -1));
-        }
+        GNUNET_assert (NULL != (t = s->get_preferences (s->get_preferences_cls, &cur->addr->peer)));
+
+                               peer_prefs = 0.0;
+                               for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
+                               {
+                                       if (c != GNUNET_ATS_PREFERENCE_END)
+                                       {
+                                               //fprintf (stderr, "VALUE[%u] %s %.3f \n", c, GNUNET_i2s (&cur->addr->peer), t[c]);
+                                               peer_prefs += t[c];
+                                       }
+                               }
+                               total_prefs += (peer_prefs / (GNUNET_ATS_PreferenceCount -1));
       }
   }
   for (cur = net->head; NULL != cur; cur = cur->next)
@@ -457,20 +474,14 @@ distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
      if (GNUNET_YES == cur->addr->active)
      {
        cur_pref = 0.0;
-       t = GAS_normalization_get_preferences (&cur->addr->peer);
-       if (NULL != t)
-       {
-        for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
-        {
-                if (c != GNUNET_ATS_PREFERENCE_END)
-                        cur_pref += t[c];
-        }
-        cur_pref /= 2;
-       }
-       else
-       {
-        cur_pref = DEFAULT_REL_PREFERENCE;
-       }
+       GNUNET_assert (NULL != (t = s->get_preferences (s->get_preferences_cls, &cur->addr->peer)));
+
+                        for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
+                        {
+                                if (c != GNUNET_ATS_PREFERENCE_END)
+                                        cur_pref += t[c];
+                        }
+                        cur_pref /= 2;
 
        assigned_quota_in = min_bw + ((cur_pref / total_prefs) * remaining_quota_in);
        assigned_quota_out = min_bw + ((cur_pref / total_prefs) * remaining_quota_out);
@@ -650,6 +661,7 @@ static void
 distribute_bandwidth_in_all_networks (struct GAS_PROPORTIONAL_Handle *s)
 {
        int i;
+
        for (i = 0; i < s->networks; i++)
                distribute_bandwidth_in_network (s, &s->network_entries[i], NULL);
 
@@ -671,6 +683,7 @@ get_network (struct GAS_PROPORTIONAL_Handle *s, uint32_t type)
   {
       if (s->network_entries[c].type == type)
         return &s->network_entries[c];
+
   }
   return NULL;
 }
@@ -844,26 +857,23 @@ get_performance_info (struct ATS_Address *address, uint32_t type)
  * Changes the preferences for a peer in the problem
  *
  * @param solver the solver handle
- * @param client the client with this preference
+ * @param addresses the address hashmap
  * @param peer the peer to change the preference for
  * @param kind the kind to change the preference
  * @param pref_rel the normalized preference value for this kind over all clients
- * @param score the score
  */
 void
 GAS_proportional_address_change_preference (void *solver,
-                                                                 void *client,
-                                                                 const struct GNUNET_PeerIdentity *peer,
-                                                                 enum GNUNET_ATS_PreferenceKind kind,
-                                                                 double pref_rel)
+                                                                                       struct GNUNET_CONTAINER_MultiHashMap *addresses,
+                                                                                       const struct GNUNET_PeerIdentity *peer,
+                                                                                       enum GNUNET_ATS_PreferenceKind kind,
+                                                                                       double pref_rel)
 {
   struct GAS_PROPORTIONAL_Handle *s = solver;
   GNUNET_assert (NULL != solver);
-  GNUNET_assert (NULL != client);
   GNUNET_assert (NULL != peer);
 
-  distribute_bandwidth_in_all_networks (s);
-
+       distribute_bandwidth_in_all_networks (s);
 }
 
 /**
@@ -899,6 +909,13 @@ GAS_proportional_get_preferred_address (void *solver,
       (GNUNET_NO == cur->active) ? "inactive" : "active",
       cur, GNUNET_i2s (peer));
   net_cur = (struct Network *) cur->solver_information;
+  if (NULL == cur)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR, "Trying to suggesting unknown address peer `%s'\n",
+        GNUNET_i2s (peer));
+    GNUNET_break (0);
+    return NULL;
+  }
   if (GNUNET_YES == cur->active)
   {
       /* This address was selected previously, so no need to update quotas */
@@ -922,7 +939,7 @@ GAS_proportional_get_preferred_address (void *solver,
       s->bw_changed (s->bw_changed_cls, prev); /* notify about bw change, REQUIRED? */
       if (GNUNET_SYSERR == addresse_decrement (s, net_prev, GNUNET_NO, GNUNET_YES))
         GNUNET_break (0);
-      distribute_bandwidth_in_network (s, net_prev, NULL);
+       distribute_bandwidth_in_network (s, net_prev, NULL);
   }
 
   if (GNUNET_NO == (is_bandwidth_available_in_network (cur->solver_information)))
@@ -934,7 +951,6 @@ GAS_proportional_get_preferred_address (void *solver,
   cur->active = GNUNET_YES;
   addresse_increment(s, net_cur, GNUNET_NO, GNUNET_YES);
   distribute_bandwidth_in_network (s, net_cur, cur);
-
   return cur;
 }
 
@@ -1029,6 +1045,47 @@ GAS_proportional_address_delete (void *solver,
 }
 
 
+/**
+ * Start a bulk operation
+ *
+ * @param solver the solver
+ */
+void
+GAS_proportional_bulk_start (void *solver)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Locking solver for bulk operation ...\n");
+  struct GAS_PROPORTIONAL_Handle *s = (struct GAS_PROPORTIONAL_Handle *) solver;
+
+  GNUNET_assert (NULL != solver);
+  s->bulk_lock ++;
+}
+
+/**
+ * Bulk operation done
+ */
+void
+GAS_proportional_bulk_stop (void *solver)
+{
+       LOG (GNUNET_ERROR_TYPE_DEBUG, "Unlocking solver from bulk operation ...\n");
+
+  struct GAS_PROPORTIONAL_Handle *s = (struct GAS_PROPORTIONAL_Handle *) solver;
+  GNUNET_assert (NULL != solver);
+
+  if (s->bulk_lock < 1)
+  {
+       GNUNET_break (0);
+       return;
+  }
+  s->bulk_lock --;
+  if ((0 == s->bulk_lock) && (0 < s->bulk_requests))
+  {
+       LOG (GNUNET_ERROR_TYPE_ERROR, "No lock pending, recalculating\n");
+       distribute_bandwidth_in_all_networks (s);
+       s->bulk_requests = 0;
+  }
+}
+
+
 /**
  * Add a new single address to a network
  *
@@ -1110,6 +1167,16 @@ GAS_proportional_address_update (void *solver,
 
         /* set new network type */
         new_net = get_network (solver, addr_net);
+        if (NULL == new_net)
+        {
+          /* Address changed to invalid network... */
+          LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot find network of type `%u' %s\n"),
+                       addr_net, GNUNET_ATS_print_network_type (addr_net));
+          address->assigned_bw_in = GNUNET_BANDWIDTH_value_init (0);
+          address->assigned_bw_out = GNUNET_BANDWIDTH_value_init (0);
+          s->bw_changed  (s->bw_changed_cls, address);
+          return;
+        }
         address->solver_information = new_net;
 
         /* Add to new network and update*/
@@ -1232,6 +1299,8 @@ GAS_proportional_address_add (void *solver,
  * @param dest_length array length for quota arrays
  * @param bw_changed_cb callback for changed bandwidth amounts
  * @param bw_changed_cb_cls cls for callback
+ * @param get_preference callback to get relative preferences for a peer
+ * @param get_preference_cls cls for callback to get relative preferences
  * @return handle for the solver on success, NULL on fail
  */
 void *
@@ -1242,7 +1311,9 @@ GAS_proportional_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
                        unsigned long long *in_quota,
                        int dest_length,
                        GAS_bandwidth_changed_cb bw_changed_cb,
-                       void *bw_changed_cb_cls)
+                       void *bw_changed_cb_cls,
+                       GAS_get_preferences get_preference,
+                       void *get_preference_cls)
 {
   int c;
   struct GAS_PROPORTIONAL_Handle *s = GNUNET_malloc (sizeof (struct GAS_PROPORTIONAL_Handle));
@@ -1253,11 +1324,13 @@ GAS_proportional_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
   s->stats = (struct GNUNET_STATISTICS_Handle *) stats;
   s->bw_changed = bw_changed_cb;
   s->bw_changed_cls = bw_changed_cb_cls;
+  s->get_preferences = get_preference;
+  s->get_preferences_cls = get_preference_cls;
   s->networks = dest_length;
   s->network_entries = GNUNET_malloc (dest_length * sizeof (struct Network));
   s->active_addresses = 0;
   s->total_addresses = 0;
-  s->prefs = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
+  s->bulk_lock = GNUNET_NO;
 
   for (c = 0; c < dest_length; c++)
   {