2 This file is part of GNUnet.
3 (C) 2011 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file ats/gnunet-service-ats-solver_ril.c
23 * @brief ATS reinforcement learning solver
24 * @author Fabian Oehlmann
25 * @author Matthias Wachs
29 #include "gnunet_util_lib.h"
30 #include "gnunet-service-ats_addresses.h"
31 #include "gnunet_statistics_service.h"
33 #define RIL_DEFAULT_STEP_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 3000)
34 #define RIL_DEFAULT_DISCOUNT_FACTOR 0.5
35 #define RIL_DEFAULT_GRADIENT_STEP_SIZE 0.4
36 #define RIL_DEFAULT_TRACE_DECAY 0.6
37 #define RIL_EXPLORE_RATIO 0.1
40 * ATS reinforcement learning solver
47 RIL_ACTION_BW_IN_DBL = 0,
48 RIL_ACTION_BW_OUT_DBL = 1,
49 RIL_ACTION_BW_IN_HLV = 2,
50 RIL_ACTION_BW_OUT_HLV = 3,
51 RIL_ACTION_TYPE_NUM = 4
53 //TODO! add the rest of the actions
61 enum RIL_E_Modification
70 * Global learning parameters
72 struct RIL_Learning_Parameters
75 * The TD-algorithm to use
77 enum RIL_Algorithm algorithm;
80 * Learning discount factor in the TD-update
85 * Gradient-descent step-size
90 * Trace-decay factor for eligibility traces
98 * Next agent in solver's linked list
100 struct RIL_Peer_Agent *next;
103 * Previous agent in solver's linked list
105 struct RIL_Peer_Agent *prev;
110 struct GAS_RIL_Handle *envi;
115 struct GNUNET_PeerIdentity peer;
118 * Whether the agent is active or not
123 * Number of performed time-steps
125 unsigned long long step_count;
128 * Experience matrix W
133 * Number of rows of W / Number of state-vector features
138 * Number of columns of W / Number of actions
143 * Last perceived state feature vector
153 * Eligibility trace vector
160 struct ATS_Address * address;
163 * Inbound bandwidth assigned by the agent
165 unsigned long long bw_in;
168 * Outbound bandwidth assigned by the agent
170 unsigned long long bw_out;
178 enum GNUNET_ATS_Network_Type type;
181 * Total available inbound bandwidth
183 unsigned long long bw_in_available;
186 * Total assigned outbound bandwidth
188 unsigned long long bw_in_assigned;
191 * Total available outbound bandwidth
193 unsigned long long bw_out_available;
196 * Total assigned outbound bandwidth
198 unsigned long long bw_out_assigned;
204 * Bandwidth changed callback
206 GAS_bandwidth_changed_cb bw_changed;
209 * Bandwidth changed callback cls
211 void *bw_changed_cls;
214 * ATS function to get preferences
216 GAS_get_preferences get_preferences;
219 * Closure for ATS function to get preferences
221 void *get_preferences_cls;
224 * ATS function to get properties
226 GAS_get_properties get_properties;
229 * Closure for ATS function to get properties
231 void *get_properties_cls;
235 * A handle for the reinforcement learning solver
237 struct GAS_RIL_Handle
242 struct GNUNET_STATISTICS_Handle *stats;
245 * Hashmap containing all valid addresses
247 const struct GNUNET_CONTAINER_MultiHashMap *addresses;
250 * Callbacks for the solver
252 struct RIL_Callbacks *callbacks;
260 * Number of changes while solver was locked
265 * Number of performed time-steps
267 unsigned long long step_count;
270 * Interval time between steps in milliseconds //TODO? put in agent
272 struct GNUNET_TIME_Relative step_time;
275 * Task identifier of the next time-step to be executed //TODO? put in agent
277 GNUNET_SCHEDULER_TaskIdentifier next_step;
280 * Learning parameters
282 struct RIL_Learning_Parameters parameters;
285 * Array of networks with global assignment state
287 struct RIL_Network * network_entries;
292 unsigned int networks_count;
295 * List of active peer-agents
297 struct RIL_Peer_Agent * agents_head;
298 struct RIL_Peer_Agent * agents_tail;
303 * ---------------------------
307 * Estimate the current action-value for state s and action a
308 * @param agent agent performing the estimation
311 * @return estimation value
314 agent_estimate_q (struct RIL_Peer_Agent *agent,
321 for (i = 0; i < agent->m; i++)
323 result += state[i] * (agent->W)[agent->m][action];
330 * Decide whether to do exploration (i.e. taking a new action) or exploitation (i.e. taking the
331 * currently estimated best action) in the current step
332 * @param agent agent performing the step
333 * @return yes, if exploring
336 agent_decide_exploration (struct RIL_Peer_Agent *agent)
338 double r = (double) GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX) / (double) UINT32_MAX;
340 if (r < RIL_EXPLORE_RATIO)
348 * Gets the action, with the maximal estimated Q-value (i.e. the one currently estimated to bring the
349 * most reward in the future)
350 * @param agent agent performing the calculation
351 * @param state the state from which to take the action
352 * @return the action promising most future reward
355 agent_get_action_best (struct RIL_Peer_Agent *agent,
361 double max_q = DBL_MIN;
363 for (i = 0; i < agent->n; i++)
365 cur_q = agent_estimate_q (agent, state, i);
373 GNUNET_assert(-1 != max_i);
379 * Gets any action, to explore the action space from that state
380 * @param agent agent performing the calculation
381 * @param state the state from which to take the action
385 agent_get_action_explore (struct RIL_Peer_Agent *agent,
388 return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, agent->n);
392 * Updates the weights (i.e. coefficients) of the weight vector in matrix W for action a
393 * @param agent the agent performing the update
394 * @param reward the reward received for the last action
395 * @param s_next the new state, the last step got the agent into
396 * @param a_prime the new
399 agent_update_weights (struct RIL_Peer_Agent *agent,
406 double *theta = (agent->W)[agent->a_old];
408 delta = reward + agent_estimate_q (agent, s_next, a_prime) -
409 agent_estimate_q (agent, agent->s_old, agent->a_old);
410 for (i = 0; i < agent->m; i++)
412 theta[i] += agent->envi->parameters.alpha * delta * (agent->e)[i];
417 * Changes the eligibility trace vector e in various manners:
418 * RIL_E_ACCUMULATE - adds 1 to each component as in accumulating eligibility traces
419 * RIL_E_REPLACE - resets each component to 1 as in replacing traces
420 * RIL_E_SET - multiplies e with gamma and lambda as in the update rule
421 * RIL_E_ZERO - sets e to 0 as in Watkin's Q-learning algorithm when exploring and when initializing
426 agent_modify_eligibility (struct RIL_Peer_Agent *agent,
427 enum RIL_E_Modification mod)
430 double *e = agent->e;
431 double gamma = agent->envi->parameters.gamma;
432 double lambda = agent->envi->parameters.lambda;
434 for (i = 0; i < agent->m; i++)
438 case RIL_E_ACCUMULATE:
445 e[i] = gamma * lambda;
455 * Allocates a state vector and fills it with the features present
456 * @param solver the solver handle
457 * @return pointer to the state vector
460 envi_get_state (struct GAS_RIL_Handle *solver)
463 struct RIL_Network *net;
464 double *state = GNUNET_malloc (sizeof (double) * solver->networks_count * 4);
466 for (i = 0; i < solver->networks_count; i += 4)
468 net = (&solver->network_entries)[i];
469 state[i] = (double) net->bw_in_assigned;
470 state[i+1] = (double) net->bw_in_available;
471 state[i+2] = (double) net->bw_out_assigned;
472 state[i+3] = (double) net->bw_out_available;
479 * Gets the reward of the last performed step
480 * @param solver solver handle
484 envi_get_reward (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
486 //TODO! implement reward calculation
488 return (double) GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX) / (double) UINT32_MAX;
492 envi_action_bw_double (struct GAS_RIL_Handle *solver,
493 struct RIL_Peer_Agent *agent,
499 agent->address->assigned_bw_in.value__ = htonl (agent->bw_in);
500 solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls, agent->address);
505 agent->address->assigned_bw_out.value__ = htonl (agent->bw_out);
506 solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls, agent->address);
511 envi_action_bw_halven (struct GAS_RIL_Handle *solver,
512 struct RIL_Peer_Agent *agent,
515 if ((direction_in && 1 == agent->bw_in) ||
516 (!direction_in && 1 == agent->bw_out))
523 agent->address->assigned_bw_in.value__ = htonl (agent->bw_in);
524 solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls, agent->address);
529 agent->address->assigned_bw_out.value__ = htonl (agent->bw_out);
530 solver->callbacks->bw_changed (solver->callbacks->bw_changed_cls, agent->address);
535 * Puts the action into effect
536 * @param solver solver handle
537 * @param action action to perform by the solver
540 envi_do_action (struct GAS_RIL_Handle *solver,
541 struct RIL_Peer_Agent *agent,
546 case RIL_ACTION_BW_IN_DBL:
547 envi_action_bw_double (solver, agent, GNUNET_YES);
549 case RIL_ACTION_BW_IN_HLV:
550 envi_action_bw_halven (solver, agent, GNUNET_YES);
552 case RIL_ACTION_BW_OUT_DBL:
553 envi_action_bw_double (solver, agent, GNUNET_NO);
555 case RIL_ACTION_BW_OUT_HLV:
556 envi_action_bw_halven (solver, agent, GNUNET_NO);
562 * Performs one step of the Markov Decision Process. Other than in the literature the step starts
563 * after having done the last action a_old. It observes the new state s_next and the reward
564 * received. Then the coefficient update is done according to the SARSA or Q-learning method. The
565 * next action is put into effect.
566 * @param agent the agent performing the step
569 agent_step (struct RIL_Peer_Agent *agent)
575 s_next = envi_get_state(agent->envi);
576 reward = envi_get_reward(agent->envi, agent);
578 switch (agent->envi->parameters.algorithm)
581 agent_modify_eligibility (agent, RIL_E_SET);
582 if (agent_decide_exploration (agent))
584 a_next = agent_get_action_explore (agent, s_next);
588 a_next = agent_get_action_best (agent, s_next);
590 //updates weights with selected action (on-policy)
591 agent_update_weights (agent, reward, s_next, a_next);
595 //updates weights with best action, disregarding actually selected action (off-policy)
596 a_next = agent_get_action_best (agent, s_next);
597 agent_update_weights (agent, reward, s_next, a_next);
598 if (agent_decide_exploration (agent))
600 a_next = agent_get_action_explore (agent, s_next);
601 agent_modify_eligibility(agent, RIL_E_ZERO);
605 a_next = agent_get_action_best (agent, s_next);
606 agent_modify_eligibility(agent, RIL_E_SET);
611 GNUNET_assert (-1 != a_next);
613 agent_modify_eligibility (agent, RIL_E_ACCUMULATE);
615 envi_do_action(agent->envi, agent, a_next);
617 GNUNET_free(agent->s_old);
618 agent->s_old = s_next;
619 agent->a_old = a_next;
621 agent->step_count += 1;
625 * Cycles through all agents and lets the active ones do a step. Schedules the next step.
626 * @param solver the solver handle
627 * @param tc task context for the scheduler
630 ril_periodic_step (void *cls,
631 const struct GNUNET_SCHEDULER_TaskContext *tc)
633 struct GAS_RIL_Handle *solver = cls;
634 struct RIL_Peer_Agent *cur;
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RIL step number %d\n", solver->step_count);
638 for (cur = solver->agents_head; NULL != cur; cur = cur->next)
646 solver->step_count += 1;
647 solver->next_step = GNUNET_SCHEDULER_add_delayed (
654 * Initialize an agent without addresses and its knowledge base
655 * @param s ril solver
656 * @param peer the one in question
657 * @return handle to the new agent
659 static struct RIL_Peer_Agent *
661 const struct GNUNET_PeerIdentity *peer)
664 struct GAS_RIL_Handle * solver = s;
665 struct RIL_Peer_Agent * agent = GNUNET_malloc (sizeof (struct RIL_Peer_Agent));
667 agent->envi = solver;
669 agent->step_count = 0;
670 agent->active = GNUNET_NO;
672 agent->n = RIL_ACTION_TYPE_NUM;
673 agent->m = solver->networks_count * 4;
674 agent->W = (double **) GNUNET_malloc (sizeof (double) * agent->n);
675 for (i = 0; i < agent->n; i++)
677 (agent->W)[i] = (double *) GNUNET_malloc (sizeof (double) * agent->m);
680 agent->e = (double *) GNUNET_malloc (sizeof (double) * agent->m);
681 agent_modify_eligibility (agent, RIL_E_ZERO);
683 GNUNET_CONTAINER_DLL_insert_tail (solver->agents_head, solver->agents_tail, agent);
690 * @param s solver handle
691 * @param agent the agent to retire
694 agent_die (struct GAS_RIL_Handle *solver,
695 struct RIL_Peer_Agent *agent)
699 for (i = 0; i < agent->n; i++)
701 GNUNET_free((agent->W)[i]);
703 GNUNET_free(agent->W);
704 GNUNET_free(agent->e);
705 GNUNET_free(agent->s_old);
709 * Returns the agent for a peer
710 * @param s solver handle
711 * @param peer identity of the peer
714 static struct RIL_Peer_Agent *
715 ril_get_agent (struct GAS_RIL_Handle *solver,
716 const struct GNUNET_PeerIdentity *peer)
718 struct RIL_Peer_Agent *cur;
720 for (cur = solver->agents_head; NULL != cur; cur = cur->next)
722 if (0 == GNUNET_CRYPTO_hash_cmp (&peer->hashPubKey, &cur->peer.hashPubKey))
728 return agent_init (solver, peer);
732 * Iterator, which allocates one agent per peer
735 * @param key peer identity
736 * @param value address
737 * @return whether iterator should continue
740 ril_init_agents_it (void *cls,
741 const struct GNUNET_HashCode *key,
744 struct GAS_RIL_Handle *solver = cls;
745 struct ATS_Address *address = value;
746 struct RIL_Peer_Agent *agent;
747 uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
749 agent = ril_get_agent (solver, &address->peer);
751 GNUNET_assert (NULL != agent);
753 if (NULL == agent->address)
755 agent->address = address;
756 agent->address->active = GNUNET_YES;
757 agent->bw_in = min_bw;
758 agent->address->assigned_bw_in.value__ = htonl (min_bw);
759 agent->bw_out = min_bw;
760 agent->address->assigned_bw_out.value__ = htonl (min_bw);
767 * Lookup network struct by type
769 * @param s the solver handle
770 * @param type the network type
771 * @return the network struct
773 static struct RIL_Network *
774 ril_get_network (struct GAS_RIL_Handle *s, uint32_t type)
777 for (i = 0 ; i < s->networks_count; i++)
779 if (s->network_entries[i].type == type)
780 return &s->network_entries[i];
788 * Solver API functions
789 * ---------------------------
793 * Changes the preferences for a peer in the problem
795 * @param solver the solver handle
796 * @param peer the peer to change the preference for
797 * @param kind the kind to change the preference
798 * @param pref_rel the normalized preference value for this kind over all clients
801 GAS_ril_address_change_preference (void *s,
802 const struct GNUNET_PeerIdentity *peer,
803 enum GNUNET_ATS_PreferenceKind kind,
806 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
807 "Preference `%s' for peer `%s' changed to %.2f \n",
808 GNUNET_ATS_print_preference_type (kind),
812 * Nothing to do here. Preferences are considered during reward calculation.
818 * Init the reinforcement learning problem solver
821 * network[i] contains the network type as type GNUNET_ATS_NetworkType[i]
822 * out_quota[i] contains outbound quota for network type i
823 * in_quota[i] contains inbound quota for network type i
826 * network = {GNUNET_ATS_NET_UNSPECIFIED, GNUNET_ATS_NET_LOOPBACK, GNUNET_ATS_NET_LAN, GNUNET_ATS_NET_WAN, GNUNET_ATS_NET_WLAN}
827 * network[2] == GNUNET_ATS_NET_LAN
828 * out_quota[2] == 65353
829 * in_quota[2] == 65353
831 * @param cfg configuration handle
832 * @param stats the GNUNET_STATISTICS handle
833 * @param network array of GNUNET_ATS_NetworkType with length dest_length
834 * @param addresses hashmap containing all addresses
835 * @param out_quota array of outbound quotas
836 * @param in_quota array of outbound quota
837 * @param dest_length array length for quota arrays
838 * @param bw_changed_cb callback for changed bandwidth amounts
839 * @param bw_changed_cb_cls cls for callback
840 * @param get_preference callback to get relative preferences for a peer
841 * @param get_preference_cls cls for callback to get relative preferences
842 * @param get_properties_cls for callback to get relative properties
843 * @param get_properties_cls cls for callback to get relative properties
844 * @return handle for the solver on success, NULL on fail
847 GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
848 const struct GNUNET_STATISTICS_Handle *stats,
849 const struct GNUNET_CONTAINER_MultiHashMap *addresses,
851 unsigned long long *out_quota,
852 unsigned long long *in_quota,
854 GAS_bandwidth_changed_cb bw_changed_cb,
855 void *bw_changed_cb_cls,
856 GAS_get_preferences get_preference,
857 void *get_preference_cls,
858 GAS_get_properties get_properties,
859 void *get_properties_cls)
862 unsigned long long tmp;
863 struct RIL_Network * cur;
864 struct GAS_RIL_Handle *solver = GNUNET_malloc (sizeof (struct GAS_RIL_Handle));
866 GNUNET_assert (NULL != cfg);
867 GNUNET_assert (NULL != stats);
868 GNUNET_assert (NULL != network);
869 GNUNET_assert (NULL != bw_changed_cb);
870 GNUNET_assert (NULL != get_preference);
871 GNUNET_assert (NULL != get_properties);
873 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time(cfg, "ats", "RIL_STEP_TIME", &solver->step_time))
875 solver->step_time = RIL_DEFAULT_STEP_TIME;
877 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "RIL_DISCOUNT_FACTOR", &tmp))
879 solver->parameters.gamma = (double) tmp / 100;;
883 solver->parameters.gamma = RIL_DEFAULT_DISCOUNT_FACTOR;
885 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "RIL_GRADIENT_STEP_SIZE", &tmp))
887 solver->parameters.alpha = (double) tmp / 100;;
891 solver->parameters.alpha = RIL_DEFAULT_GRADIENT_STEP_SIZE;
893 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "RIL_TRACE_DECAY", &tmp))
895 solver->parameters.lambda = (double) tmp / 100;;
899 solver->parameters.lambda = RIL_DEFAULT_TRACE_DECAY;
902 solver->stats = (struct GNUNET_STATISTICS_Handle *) stats;
903 solver->callbacks = GNUNET_malloc (sizeof (struct RIL_Callbacks));
904 solver->callbacks->bw_changed = bw_changed_cb;
905 solver->callbacks->bw_changed_cls = bw_changed_cb_cls;
906 solver->callbacks->get_preferences = get_preference;
907 solver->callbacks->get_preferences_cls = get_preference_cls;
908 solver->callbacks->get_properties = get_properties;
909 solver->callbacks->get_properties_cls = get_properties_cls;
910 solver->networks_count = dest_length;
911 solver->network_entries = GNUNET_malloc (dest_length * sizeof (struct RIL_Network));
912 solver->bulk_lock = GNUNET_NO;
913 solver->addresses = addresses;
914 solver->step_count = 0;
916 for (c = 0; c < dest_length; c++)
918 cur = &solver->network_entries[c];
919 cur->type = network[c];
920 cur->bw_in_available = in_quota[c];
921 cur->bw_in_assigned = 0;
922 cur->bw_out_available = out_quota[c];
923 cur->bw_out_assigned = 0;
926 c = GNUNET_CONTAINER_multihashmap_iterate (addresses, &ril_init_agents_it, solver);
928 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_init() has been called\n");
929 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RIL number of addresses: %d\n", c);
931 solver->next_step = GNUNET_SCHEDULER_add_delayed (
932 GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_millisecond_ (), 1000),
940 * Shutdown the reinforcement learning problem solver
942 * @param solver the respective handle to shutdown
945 GAS_ril_done (void * solver)
947 struct GAS_RIL_Handle *s = solver;
948 struct RIL_Peer_Agent *cur_agent;
949 struct RIL_Peer_Agent *next_agent;
951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_done() has been called\n");
953 cur_agent = s->agents_head;
954 while (NULL != cur_agent)
956 next_agent = cur_agent->next;
957 GNUNET_CONTAINER_DLL_remove (s->agents_head, s->agents_tail, cur_agent);
958 agent_die (s, cur_agent);
959 cur_agent = next_agent;
962 GNUNET_SCHEDULER_cancel (s->next_step);
963 GNUNET_free (s->callbacks);
964 GNUNET_free (s->network_entries);
970 * Add a single address within a network to the solver
972 * @param solver the solver Handle
973 * @param address the address to add
974 * @param network network type of this address
977 GAS_ril_address_add (void *solver,
978 struct ATS_Address *address,
981 struct GAS_RIL_Handle *s = solver;
982 //TODO! implement solver address add
985 * initialize new agent
987 * increase state vector
993 * reiterate all addresses, create new agent if necessary and give the agent the address
995 GNUNET_CONTAINER_multihashmap_iterate (s->addresses, &ril_init_agents_it, solver);
997 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_add() has been called\n");
1001 * Remove an address from the solver
1003 * @param solver the solver handle
1004 * @param address the address to remove
1005 * @param session_only delete only session not whole address
1008 GAS_ril_address_delete (void *solver,
1009 struct ATS_Address *address,
1012 //TODO! implement solver address delete
1015 * if (last address of peer)
1018 * decrease state vector
1019 * decrease knowledge matrix
1020 * decrease action vector
1022 struct GAS_RIL_Handle *s = solver;
1023 struct RIL_Peer_Agent *agent;
1025 agent = ril_get_agent(s, &address->peer);
1027 if (0 == memcmp (agent->address->addr, address->addr, address->addr_len)) //if used address deleted
1029 agent->address = NULL; //delete address
1030 GNUNET_CONTAINER_multihashmap_iterate (s->addresses, &ril_init_agents_it, solver); //put another address
1031 if (NULL == agent->address) //no other address available
1033 agent->active = GNUNET_NO;
1037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_delete() has been called\n");
1041 * Transport properties for this address have changed
1043 * @param solver solver handle
1044 * @param address the address
1045 * @param type the ATSI type in HBO
1046 * @param abs_value the absolute value of the property
1047 * @param rel_value the normalized value
1050 GAS_ril_address_property_changed (void *solver,
1051 struct ATS_Address *address,
1056 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1057 "Property `%s' for peer `%s' address %p changed to %.2f \n",
1058 GNUNET_ATS_print_property_type (type),
1059 GNUNET_i2s (&address->peer),
1060 address, rel_value);
1062 * Nothing to do here, properties are considered in every reward calculation
1068 * Transport session for this address has changed
1070 * NOTE: values in addresses are already updated
1072 * @param solver solver handle
1073 * @param address the address
1074 * @param cur_session the current session
1075 * @param new_session the new session
1078 GAS_ril_address_session_changed (void *solver,
1079 struct ATS_Address *address,
1080 uint32_t cur_session,
1081 uint32_t new_session)
1083 //TODO? consider session changed in solver behaviour
1085 * Potentially add session activity as a feature in state vector
1087 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_session_changed() has been called\n");
1092 * Usage for this address has changed
1094 * NOTE: values in addresses are already updated
1096 * @param solver solver handle
1097 * @param address the address
1098 * @param in_use usage state
1101 GAS_ril_address_inuse_changed (void *solver,
1102 struct ATS_Address *address,
1105 //TODO! consider address_inuse_changed according to matthias' email
1107 * See matthias' email
1109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_inuse_changed() has been called\n");
1113 * Network scope for this address has changed
1115 * NOTE: values in addresses are already updated
1117 * @param solver solver handle
1118 * @param address the address
1119 * @param current_network the current network
1120 * @param new_network the new network
1123 GAS_ril_address_change_network (void *solver,
1124 struct ATS_Address *address,
1125 uint32_t current_network,
1126 uint32_t new_network)
1128 struct GAS_RIL_Handle *s = solver;
1129 struct RIL_Peer_Agent *agent;
1130 struct RIL_Network *net;
1132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Network type changed, moving %s address from `%s' to `%s'\n",
1133 (GNUNET_YES == address->active) ? "active" : "inactive",
1134 GNUNET_ATS_print_network_type (current_network),
1135 GNUNET_ATS_print_network_type (new_network));
1137 agent = ril_get_agent(s, &address->peer);
1139 if (address->active)
1141 //remove from old network
1142 net = ril_get_network (s, current_network);
1143 net->bw_in_assigned -= agent->bw_in;
1144 net->bw_out_assigned -= agent->bw_out;
1146 //add to new network
1147 net = ril_get_network (s, new_network);
1148 net->bw_in_assigned += agent->bw_in;
1149 net->bw_out_assigned += agent->bw_out;
1154 * Get application feedback for a peer
1156 * @param solver the solver handle
1157 * @param application the application
1158 * @param peer the peer to change the preference for
1159 * @param scope the time interval for this feedback: [now - scope .. now]
1160 * @param kind the kind to change the preference
1161 * @param score the score
1164 GAS_ril_address_preference_feedback (void *solver,
1166 const struct GNUNET_PeerIdentity *peer,
1167 const struct GNUNET_TIME_Relative scope,
1168 enum GNUNET_ATS_PreferenceKind kind,
1171 //TODO! collect reward until next reward calculation
1172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_preference_feedback() has been called\n");
1176 * Start a bulk operation
1178 * @param solver the solver
1181 GAS_ril_bulk_start (void *solver)
1183 //TODO? consideration: keep bulk counter and stop agents during bulk
1185 * bulk counter up, but not really relevant, because there is no complete calculation of the
1186 * bandwidth assignment triggered anyway. Therefore, changes to addresses can come and go as
1187 * they want. Consideration: Step-pause during bulk-start-stop period...
1189 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_bulk_start() has been called\n");
1194 * Bulk operation done
1197 GAS_ril_bulk_stop (void *solver)
1199 //TODO? consideration: keep bulk counter and stop agents during bulk
1201 * bulk counter down, see bulk_start()
1203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_bulk_stop() has been called\n");
1207 * Get the preferred address for a specific peer
1209 * @param solver the solver handle
1210 * @param peer the identity of the peer
1212 const struct ATS_Address *
1213 GAS_ril_get_preferred_address (void *solver,
1214 const struct GNUNET_PeerIdentity *peer)
1217 * activate agent, return currently chosen address
1219 struct GAS_RIL_Handle *s = solver;
1220 struct RIL_Peer_Agent *agent;
1222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_get_preferred_address() has been called\n");
1224 agent = ril_get_agent(s, peer);
1225 agent->active = GNUNET_YES;
1227 GNUNET_assert (NULL != agent->address);
1229 return agent->address;
1233 * Stop notifying about address and bandwidth changes for this peer
1235 * @param solver the solver handle
1236 * @param peer the peer
1239 GAS_ril_stop_get_preferred_address (void *solver,
1240 const struct GNUNET_PeerIdentity *peer)
1242 struct GAS_RIL_Handle *s = solver;
1243 struct RIL_Peer_Agent *agent;
1245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_stop_get_preferred_address() has been called\n");
1247 agent = ril_get_agent(s, peer);
1248 agent->active = GNUNET_NO;
1251 /* end of gnunet-service-ats-solver_ril.c */