ats_ril: solver continued
[oweals/gnunet.git] / src / ats / gnunet-service-ats-solver_ril.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011 Christian Grothoff (and other contributing authors)
4
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.
9
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.
14
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.
19 */
20
21 /**
22  * @file ats/gnunet-service-ats-solver_ril.c
23  * @brief ATS reinforcement learning solver
24  * @author Fabian Oehlmann
25  * @author Matthias Wachs
26  */
27 #include "platform.h"
28 #include "float.h"
29 #include "gnunet_util_lib.h"
30 #include "gnunet-service-ats_addresses.h"
31 #include "gnunet_statistics_service.h"
32
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
38
39 /**
40  * ATS reinforcement learning solver
41  *
42  * General description
43  */
44
45 enum RIL_Action
46 {
47         RIL_BW_DBL = 0,
48         RIL_BW_HLV = 1,
49         RIL_NUM_ACTIONS = 2
50 };
51 //TODO add the rest of the actions
52
53 /**
54  * Global learning parameters
55  */
56 struct RIL_Learning_Parameters
57 {
58         /**
59          * Learning discount factor in the TD-update
60          */
61         float gamma;
62
63         /**
64          * Gradient-descent step-size
65          */
66         float alpha;
67
68         /**
69          * Trace-decay factor for eligibility traces
70          */
71         float lambda;
72 };
73
74 struct RIL_Peer_Agent
75 {
76         /**
77          * Next agent in solver's linked list
78          */
79         struct RIL_Peer_Agent *next;
80
81         /**
82          * Previous agent in solver's linked list
83          */
84         struct RIL_Peer_Agent *prev;
85
86         /**
87          * Environment handle
88          */
89         struct GAS_RIL_Handle *envi;
90
91         /**
92          * Peer ID
93          */
94         struct GNUNET_PeerIdentity peer;
95
96         /**
97          * Whether the agent is active or not
98          */
99         int active;
100
101         /**
102         * Number of performed time-steps
103         */
104         unsigned long long step_count;
105
106         /**
107          * Experience matrix W
108          */
109         double ** W;
110
111         /**
112          * Number of rows of W / Number of state-vector features
113          */
114         int m;
115
116         /**
117          * Number of columns of W / Number of actions
118          */
119         int n;
120
121         /**
122          * Last perceived state feature vector
123          */
124         double * s_old;
125
126         /**
127          * Last chosen action
128          */
129         int a_old;
130
131         /**
132          * Last eligibility trace vector
133          */
134         double * e_t;
135
136         /**
137          * Address in use
138          */
139         struct ATS_Address * address;
140 };
141
142 struct RIL_Network
143 {
144           /**
145            * ATS network type
146            */
147           unsigned int type;
148
149           /**
150            * Network description
151            */
152           char *desc;
153
154           /**
155            * Total available inbound bandwidth
156            */
157           unsigned long long bw_in_available;
158
159           /**
160            * Total assigned outbound bandwidth
161            */
162           unsigned long long bw_in_assigned;
163
164           /**
165            * Total available outbound bandwidth
166            */
167           unsigned long long bw_out_available;
168
169           /**
170            * Total assigned outbound bandwidth
171            */
172           unsigned long long bw_out_assigned;
173 };
174
175 struct RIL_Callbacks
176 {
177           /**
178            * Bandwidth changed callback
179            */
180           GAS_bandwidth_changed_cb bw_changed;
181
182           /**
183            * Bandwidth changed callback cls
184            */
185           void *bw_changed_cls;
186
187           /**
188            * ATS function to get preferences
189            */
190           GAS_get_preferences get_preferences;
191
192           /**
193            * Closure for ATS function to get preferences
194            */
195           void *get_preferences_cls;
196
197           /**
198            * ATS function to get properties
199            */
200           GAS_get_properties get_properties;
201
202           /**
203            * Closure for ATS function to get properties
204            */
205           void *get_properties_cls;
206 };
207
208 /**
209  * A handle for the reinforcement learning solver
210  */
211 struct GAS_RIL_Handle
212 {
213         /**
214         * Statistics handle
215         */
216         struct GNUNET_STATISTICS_Handle *stats;
217
218         /**
219         * Hashmap containing all valid addresses
220         */
221         const struct GNUNET_CONTAINER_MultiHashMap *addresses;
222
223         /**
224         * Callbacks for the solver
225         */
226         struct RIL_Callbacks callbacks;
227
228         /**
229         * Bulk lock
230         */
231         int bulk_lock;
232
233         /**
234         * Number of changes while solver was locked
235         */
236         int bulk_requests;
237
238         /**
239         * Number of performed time-steps
240         */
241         unsigned long long step_count;
242
243         /**
244         * Interval time between steps in milliseconds //TODO put in agent
245         */
246         struct GNUNET_TIME_Relative step_time;
247
248         /**
249         * Task identifier of the next time-step to be executed //TODO put in agent
250         */
251         GNUNET_SCHEDULER_TaskIdentifier next_step;
252
253         /**
254         * Learning parameters
255         */
256         struct RIL_Learning_Parameters parameters;
257
258         /**
259         * Array of networks with global assignment state
260         */
261         struct RIL_Network * network_entries;
262
263         /**
264         * Networks count
265         */
266         unsigned int networks_count;
267
268         /**
269         * List of active peer-agents
270         */
271         struct RIL_Peer_Agent * agents_head;
272         struct RIL_Peer_Agent * agents_tail;
273 };
274
275
276
277
278 /**
279  *  Private functions
280  *  ---------------------------
281  */
282
283 /**
284  * Estimate the current action-value for state s and action a
285  * @param agent agent performing the estimation
286  * @param state s
287  * @param action a
288  * @return estimation value
289  */
290 double
291 agent_estimate_q (struct RIL_Peer_Agent *agent,
292                 double *state,
293                 int action)
294 {
295         int i;
296         double result = 0;
297
298         for (i = 0; i < agent->m; i++)
299         {
300                 result += state[i] * (agent->W)[agent->m][action];
301         }
302
303         return result;
304 }
305
306 int
307 agent_choose_action (struct RIL_Peer_Agent *agent,
308                 double *state)
309 {
310         int i;
311         int max_i = -1;
312         double r;
313         double cur_q;
314         double max_q = DBL_MIN;
315
316         r = ((double) GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX) / (double) UINT32_MAX);
317
318         if (r < RIL_EXPLORE_RATIO)
319         {
320                 return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, agent->n);
321         }
322
323         for (i = 0; i < agent->m; i++)
324         {
325                 cur_q = agent_estimate_q (agent, state, i);
326                 if (cur_q > max_q)
327                 {
328                         max_q = cur_q;
329                         max_i = i;
330                 }
331         }
332
333         GNUNET_assert(-1 != max_i);
334
335         return max_i;
336 }
337
338 double *
339 envi_get_state (void *s)
340 {
341         int i;
342         struct GAS_RIL_Handle *solver = s;
343         struct RIL_Network *net;
344         double *state = GNUNET_malloc (sizeof (double) * solver->networks_count * 4);
345
346         for (i = 0; i < solver->networks_count; i += 4)
347         {
348                 net = (&solver->network_entries)[i];
349                 state[i]   = (double) net->bw_in_assigned;
350                 state[i+1] = (double) net->bw_in_available;
351                 state[i+2] = (double) net->bw_out_assigned;
352                 state[i+3] = (double) net->bw_out_available;
353         }
354
355         return state;
356 }
357
358 double
359 envi_get_reward ()
360 {
361         //TODO implement
362         return (double) GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX) / (double) UINT32_MAX;
363 }
364
365 void
366 agent_step (struct RIL_Peer_Agent *agent)
367 {
368         int a_next;
369         double *s_next;
370         double reward;
371         double delta;
372         double q_next;
373
374
375         s_next = envi_get_state(agent->envi);
376         reward = envi_get_reward();
377
378         a_next = agent_choose_action (agent, s_next);
379         q_next = agent_estimate_q(agent, s_next, a_next);
380
381         if (NULL != agent->s_old)
382         {
383                 delta = reward +
384                                 (agent->envi->parameters.gamma * q_next) -
385                                 agent_estimate_q(agent, agent->s_old, agent->a_old);
386         }
387
388         GNUNET_free(agent->s_old);
389         agent->s_old = s_next;
390         agent->a_old = a_next;
391
392         agent->step_count += 1;
393 }
394
395 void
396 ril_periodic_step (void *s,
397                                 const struct GNUNET_SCHEDULER_TaskContext *tc)
398 {
399         /*
400          * iterate over active agents and do a time step
401          */
402         struct GAS_RIL_Handle *solver = s;
403         struct RIL_Peer_Agent *cur;
404
405         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RIL step number %d\n", solver->step_count);
406
407         for (cur = solver->agents_head; NULL != cur; cur = cur->next)
408         {
409                 if (cur->active)
410                 {
411                         agent_step (cur);
412                 }
413         }
414
415         solver->step_count += 1;
416         solver->next_step = GNUNET_SCHEDULER_add_delayed (
417                         solver->step_time,
418                         &ril_periodic_step,
419                         solver);
420 }
421
422 /**
423  * Initialize an agent without addresses and its knowledge base
424  * @param s ril solver
425  * @param peer the one in question
426  * @return handle to the new agent
427  */
428 struct RIL_Peer_Agent *
429 agent_init (void *s,
430                 struct GNUNET_PeerIdentity peer)
431 {
432         int i;
433         struct GAS_RIL_Handle * solver = s;
434         struct RIL_Peer_Agent * agent = GNUNET_malloc (sizeof (struct RIL_Peer_Agent));
435
436         agent->envi = solver;
437         agent->peer = peer;
438         agent->step_count = 0;
439         agent->active = GNUNET_NO;
440         agent->s_old = NULL;
441         agent->n = solver->networks_count * 4;
442         agent->m = RIL_NUM_ACTIONS;
443         agent->W = (double **) GNUNET_malloc (sizeof (double) * agent->n);
444         for (i = 0; i < agent->n; i++)
445         {
446                 (agent->W)[i] = (double *) GNUNET_malloc (sizeof (double) * agent->m);
447         }
448         agent->a_old = -1;
449         agent->e_t = NULL;
450
451         GNUNET_CONTAINER_DLL_insert (solver->agents_head, solver->agents_tail, agent);
452
453         return agent;
454 }
455
456 /**
457  * Deallocate agent
458  * @param s solver handle
459  * @param agent the agent to retire
460  */
461 void
462 agent_die (void *s,
463                 struct RIL_Peer_Agent * agent)
464 {
465
466 }
467
468 /**
469  * Returns the agent for a peer
470  * @param s solver handle
471  * @param peer identity of the peer
472  * @return agent
473  */
474 struct RIL_Peer_Agent *
475 ril_get_agent (struct GAS_RIL_Handle * s,
476                 struct GNUNET_PeerIdentity peer)
477 {
478         struct GAS_RIL_Handle * solver = s;
479         struct RIL_Peer_Agent * cur;
480
481         for (cur = s->agents_head; NULL != cur; cur = cur->next)
482         {
483                 if (0 == GNUNET_CRYPTO_hash_cmp (&peer.hashPubKey, &cur->peer.hashPubKey))
484                 {
485                         return cur;
486                 }
487         }
488
489         return agent_init (solver, peer);
490 }
491
492 /**
493  * Iterator, which allocates one agent per peer
494  *
495  * @param cls solver
496  * @param key peer identity
497  * @param value address
498  * @return whether iterator should continue
499  */
500 int
501 init_agents_it (void *cls,
502                                 const struct GNUNET_HashCode *key,
503                                 void *value)
504 {
505         struct GAS_RIL_Handle *solver = cls;
506         struct ATS_Address *address = value;
507         struct RIL_Peer_Agent *agent;
508
509         agent = ril_get_agent (solver, address->peer);
510
511         GNUNET_assert (agent != NULL);
512
513         if (NULL == agent->address)
514         {
515                 agent->address = address;
516         }
517
518         return GNUNET_YES;
519 }
520
521
522
523 /**
524  *  Solver API functions
525  *  ---------------------------
526  */
527
528 /**
529  * Changes the preferences for a peer in the problem
530  *
531  * @param solver the solver handle
532  * @param peer the peer to change the preference for
533  * @param kind the kind to change the preference
534  * @param pref_rel the normalized preference value for this kind over all clients
535  */
536 void
537 GAS_ril_address_change_preference (void *solver,
538                                                                                         const struct GNUNET_PeerIdentity *peer,
539                                                                                         enum GNUNET_ATS_PreferenceKind kind,
540                                                                                         double pref_rel)
541 {
542           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
543                       "Preference `%s' for peer `%s' changed to %.2f \n",
544                       GNUNET_ATS_print_preference_type (kind),
545                       GNUNET_i2s (peer),
546                       pref_rel);
547           /*
548            * Nothing to do here. Preferences are considered during reward calculation.
549            */
550 }
551
552
553 /**
554  * Init the reinforcement learning problem solver
555  *
556  * Quotas:
557  * network[i] contains the network type as type GNUNET_ATS_NetworkType[i]
558  * out_quota[i] contains outbound quota for network type i
559  * in_quota[i] contains inbound quota for network type i
560  *
561  * Example
562  * network = {GNUNET_ATS_NET_UNSPECIFIED, GNUNET_ATS_NET_LOOPBACK, GNUNET_ATS_NET_LAN, GNUNET_ATS_NET_WAN, GNUNET_ATS_NET_WLAN}
563  * network[2]   == GNUNET_ATS_NET_LAN
564  * out_quota[2] == 65353
565  * in_quota[2]  == 65353
566  *
567  * @param cfg configuration handle
568  * @param stats the GNUNET_STATISTICS handle
569  * @param network array of GNUNET_ATS_NetworkType with length dest_length
570  * @param addresses hashmap containing all addresses
571  * @param out_quota array of outbound quotas
572  * @param in_quota array of outbound quota
573  * @param dest_length array length for quota arrays
574  * @param bw_changed_cb callback for changed bandwidth amounts
575  * @param bw_changed_cb_cls cls for callback
576  * @param get_preference callback to get relative preferences for a peer
577  * @param get_preference_cls cls for callback to get relative preferences
578  * @param get_properties_cls for callback to get relative properties
579  * @param get_properties_cls cls for callback to get relative properties
580  * @return handle for the solver on success, NULL on fail
581  */
582 void *
583 GAS_ril_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
584                                 const struct GNUNET_STATISTICS_Handle *stats,
585                                 const struct GNUNET_CONTAINER_MultiHashMap *addresses,
586                                 int *network,
587                                 unsigned long long *out_quota,
588                                 unsigned long long *in_quota,
589                                 int dest_length,
590                                 GAS_bandwidth_changed_cb bw_changed_cb,
591                                 void *bw_changed_cb_cls,
592                                 GAS_get_preferences get_preference,
593                                 void *get_preference_cls,
594                                 GAS_get_properties get_properties,
595                                 void *get_properties_cls)
596 {
597         //TODO implement
598         int c;
599         unsigned long long tmp;
600         struct RIL_Network * cur;
601         struct GAS_RIL_Handle *solver = GNUNET_malloc (sizeof (struct GAS_RIL_Handle));
602         char * net_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
603
604         GNUNET_assert (NULL != cfg);
605         GNUNET_assert (NULL != stats);
606         GNUNET_assert (NULL != network);
607         GNUNET_assert (NULL != bw_changed_cb);
608         GNUNET_assert (NULL != get_preference);
609         GNUNET_assert (NULL != get_properties);
610
611         if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time(cfg, "ats", "RIL_STEP_TIME", &solver->step_time))
612         {
613                 solver->step_time = RIL_DEFAULT_STEP_TIME;
614         }
615         if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "RIL_DISCOUNT_FACTOR", &tmp))
616         {
617                 solver->parameters.gamma = (double) tmp / 100;;
618         }
619         else
620         {
621                 solver->parameters.gamma = RIL_DEFAULT_DISCOUNT_FACTOR;
622         }
623         if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "RIL_GRADIENT_STEP_SIZE", &tmp))
624         {
625                 solver->parameters.alpha = (double) tmp / 100;;
626         }
627         else
628         {
629                 solver->parameters.alpha = RIL_DEFAULT_GRADIENT_STEP_SIZE;
630         }
631         if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "RIL_TRACE_DECAY", &tmp))
632         {
633                 solver->parameters.lambda = (double) tmp / 100;;
634         }
635         else
636         {
637                 solver->parameters.lambda = RIL_DEFAULT_TRACE_DECAY;
638         }
639
640         solver->stats = (struct GNUNET_STATISTICS_Handle *) stats;
641         solver->callbacks.bw_changed = bw_changed_cb;
642         solver->callbacks.bw_changed_cls = bw_changed_cb_cls;
643         solver->callbacks.get_preferences = get_preference;
644         solver->callbacks.get_preferences_cls = get_preference_cls;
645         solver->callbacks.get_properties = get_properties;
646         solver->callbacks.get_properties_cls = get_properties_cls;
647         solver->networks_count = dest_length;
648         solver->network_entries = GNUNET_malloc (dest_length * sizeof (struct RIL_Network));
649         solver->bulk_lock = GNUNET_NO;
650         solver->addresses = addresses;
651         solver->step_count = 0;
652
653         for (c = 0; c < dest_length; c++)
654         {
655                 cur = &solver->network_entries[c];
656                 cur->type = network[c];
657                 cur->bw_in_available = in_quota[c];
658                 cur->bw_in_assigned = 0;
659                 cur->bw_out_available = out_quota[c];
660                 cur->bw_out_assigned = 0;
661                 cur->desc = net_str[c];
662         }
663
664         c = GNUNET_CONTAINER_multihashmap_iterate (addresses, &init_agents_it, solver);
665
666         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_init() has been called\n");
667         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RIL number of addresses: %d\n", c);
668
669         solver->next_step = GNUNET_SCHEDULER_add_delayed (
670                                 GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_millisecond_ (), 1000),
671                                 &ril_periodic_step,
672                                 solver);
673
674         return solver;
675 }
676
677 /**
678  * Shutdown the reinforcement learning problem solver
679  *
680  * @param solver the respective handle to shutdown
681  */
682 void
683 GAS_ril_done (void * solver)
684 {
685         //TODO implement
686         struct GAS_RIL_Handle *s = solver;
687
688         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_done() has been called\n");
689
690         GNUNET_SCHEDULER_cancel (s->next_step);
691         GNUNET_free (s->network_entries);
692         GNUNET_free (s);
693 }
694
695
696 /**
697  * Add a single address within a network to the solver
698  *
699  * @param solver the solver Handle
700  * @param address the address to add
701  * @param network network type of this address
702  */
703 void
704 GAS_ril_address_add (void *solver,
705                                                         struct ATS_Address *address,
706                                                         uint32_t network)
707 {
708         //TODO implement
709         /*
710          * if (new peer)
711          *     initialize new agent
712          * Add address
713          * increase state vector
714          * knowledge matrix
715          * and action vector
716          */
717         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_add() has been called\n");
718 }
719
720 /**
721  * Remove an address from the solver
722  *
723  * @param solver the solver handle
724  * @param address the address to remove
725  * @param session_only delete only session not whole address
726  */
727 void
728 GAS_ril_address_delete (void *solver,
729                                                 struct ATS_Address *address,
730                                                 int session_only)
731 {
732         //TODO implement
733         /*
734          * remove address
735          * if (last address of peer)
736          *     remove agent
737          * else
738          *     decrease state vector
739          *     decrease knowledge matrix
740          *     decrease action vector
741          */
742         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_delete() has been called\n");
743 }
744
745 /**
746  * Transport properties for this address have changed
747  *
748  * @param solver solver handle
749  * @param address the address
750  * @param type the ATSI type in HBO
751  * @param abs_value the absolute value of the property
752  * @param rel_value the normalized value
753  */
754 void
755 GAS_ril_address_property_changed (void *solver,
756                                                                                                                         struct ATS_Address *address,
757                                                                                                                         uint32_t type,
758                                                                                                                         uint32_t abs_value,
759                                                                                                                         double rel_value)
760 {
761           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
762                       "Property `%s' for peer `%s' address %p changed to %.2f \n",
763                       GNUNET_ATS_print_property_type (type),
764                       GNUNET_i2s (&address->peer),
765                       address, rel_value);
766           /*
767            * Nothing to do here, properties are considered in every reward calculation
768            */
769 }
770
771
772 /**
773  * Transport session for this address has changed
774  *
775  * NOTE: values in addresses are already updated
776  *
777  * @param solver solver handle
778  * @param address the address
779  * @param cur_session the current session
780  * @param new_session the new session
781  */
782 void
783 GAS_ril_address_session_changed (void *solver,
784                                                                                                                         struct ATS_Address *address,
785                                                                                                                         uint32_t cur_session,
786                                                                                                                         uint32_t new_session)
787 {
788         //TODO implement
789         /*
790          * Potentially add session activity as a feature in state vector
791          */
792         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_session_changed() has been called\n");
793 }
794
795
796 /**
797  * Usage for this address has changed
798  *
799  * NOTE: values in addresses are already updated
800  *
801  * @param solver solver handle
802  * @param address the address
803  * @param in_use usage state
804  */
805 void
806 GAS_ril_address_inuse_changed (void *solver,
807                                                                                                                         struct ATS_Address *address,
808                                                                                                                         int in_use)
809 {
810         //TODO implement
811         /**
812          * See matthias' email
813          */
814         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_inuse_changed() has been called\n");
815 }
816
817 /**
818  * Network scope for this address has changed
819  *
820  * NOTE: values in addresses are already updated
821  *
822  * @param solver solver handle
823  * @param address the address
824  * @param current_network the current network
825  * @param new_network the new network
826  */
827 void
828 GAS_ril_address_change_network (void *solver,
829                                                                                                                                            struct ATS_Address *address,
830                                                                                                                                            uint32_t current_network,
831                                                                                                                                            uint32_t new_network)
832 {
833         //TODO implement
834         /*
835          * update network
836          */
837         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_change_network() has been called\n");
838 }
839
840 /**
841  * Get application feedback for a peer
842  *
843  * @param solver the solver handle
844  * @param application the application
845  * @param peer the peer to change the preference for
846  * @param scope the time interval for this feedback: [now - scope .. now]
847  * @param kind the kind to change the preference
848  * @param score the score
849  */
850 void
851 GAS_ril_address_preference_feedback (void *solver,
852                                                                                         void *application,
853                                                                                         const struct GNUNET_PeerIdentity *peer,
854                                                                                         const struct GNUNET_TIME_Relative scope,
855                                                                                         enum GNUNET_ATS_PreferenceKind kind,
856                                                                                         double score)
857 {
858         //TODO implement
859         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_address_preference_feedback() has been called\n");
860 }
861
862 /**
863  * Start a bulk operation
864  *
865  * @param solver the solver
866  */
867 void
868 GAS_ril_bulk_start (void *solver)
869 {
870         //TODO implement
871         /*
872          * bulk counter up, but not really relevant, because there is no complete calculation of the
873          * bandwidth assignment triggered anyway. Therefore, changes to addresses can come and go as
874          * they want. Consideration: Step-pause during bulk-start-stop period...
875          */
876         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_bulk_start() has been called\n");
877 }
878
879
880 /**
881  * Bulk operation done
882  */
883 void
884 GAS_ril_bulk_stop (void *solver)
885 {
886         //TODO implement
887         /*
888          * bulk counter down, see bulk_start()
889          */
890         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_bulk_stop() has been called\n");
891 }
892
893 /**
894  * Get the preferred address for a specific peer
895  *
896  * @param solver the solver handle
897  * @param peer the identity of the peer
898  */
899 const struct ATS_Address *
900 GAS_ril_get_preferred_address (void *solver,
901                                const struct GNUNET_PeerIdentity *peer)
902 {
903         //TODO implement
904         /*
905          * connect-only for requested peers, move agent to active list
906          */
907         struct GAS_RIL_Handle *s = solver;
908
909         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_get_preferred_address() has been called\n");
910
911         if (0 == GNUNET_CONTAINER_multihashmap_contains(s->addresses, &peer->hashPubKey))
912         {
913                 return GNUNET_CONTAINER_multihashmap_get(s->addresses, &peer->hashPubKey);
914         }
915
916         GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No address for peer in addresses\n");
917         return NULL;
918 }
919
920 /**
921  * Stop notifying about address and bandwidth changes for this peer
922  *
923  * @param solver the solver handle
924  * @param peer the peer
925  */
926 void
927 GAS_ril_stop_get_preferred_address (void *solver,
928                                      const struct GNUNET_PeerIdentity *peer)
929 {
930         //TODO implement
931         /*
932          * connect-only for requested peers, move agent to paused list
933          */
934         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ril_stop_get_preferred_address() has been called\n");
935 }
936
937 /* end of gnunet-service-ats-solver_reinf.c */