08062012e113a5c1950b77c21f73a1e9627c79b3
[oweals/gnunet.git] / src / ats / gnunet-service-ats_normalization.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_normalization.c
23  * @brief ats service address: management of ATS properties and preferences normalization
24  * @author Matthias Wachs
25  * @author Christian Grothoff
26  */
27 #include "platform.h"
28 #include "gnunet_ats_service.h"
29 #include "gnunet-service-ats_normalization.h"
30
31
32
33 /**
34  * Preference client
35  */
36 struct PreferenceClient
37 {
38   /**
39    * Next in DLL
40    */
41   struct PreferenceClient *prev;
42
43   /**
44    * Next in DLL
45    */
46
47   struct PreferenceClient *next;
48
49   /**
50    * Client handle
51    */
52   void *client;
53
54   /**
55    * Total preference for this peer
56    */
57   double f_total[GNUNET_ATS_PreferenceCount];
58
59   /**
60    * List of peer preferences for this client
61    */
62
63   /**
64    * Head of peer list
65    */
66   struct PreferencePeer *p_head;
67
68   /**
69    * Tail of peer list
70    */
71   struct PreferencePeer *p_tail;
72 };
73
74
75 /**
76  * Preference peer
77  */
78 struct PreferencePeer
79 {
80   /**
81    * Next in DLL
82    */
83   struct PreferencePeer *next;
84
85   /**
86    * Previous in DLL
87    */
88   struct PreferencePeer *prev;
89
90   /**
91    * Client
92    */
93   struct PreferenceClient *client;
94
95   /**
96    * Peer id
97    */
98   struct GNUNET_PeerIdentity id;
99
100   /**
101    * Preference Values
102    */
103   double f[GNUNET_ATS_PreferenceCount];
104
105   /**
106    * Relative Preference Values
107    */
108   double f_rel[GNUNET_ATS_PreferenceCount];
109
110   /**
111    * Relative Total Preference Value
112    */
113   double f_rel_total;
114
115   GNUNET_SCHEDULER_TaskIdentifier aging_task;
116 };
117
118
119
120 struct PreferenceClient *pc_head;
121 struct PreferenceClient *pc_tail;
122
123 static void
124 preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
125 {
126
127 }
128
129 /**
130  * Changes the preferences for a peer in the problem
131  *
132  * @param solver the solver handle
133  * @param client the client with this preference
134  * @param peer the peer to change the preference for
135  * @param kind the kind to change the preference
136  * @param score the normalized score
137  */
138 float
139 GAS_normalization_change_preference (void *src,
140                                          const struct GNUNET_PeerIdentity *peer,
141                                          enum GNUNET_ATS_PreferenceKind kind,
142                                          float score_abs)
143 {
144         float score_rel = 1.0;
145   struct PreferenceClient *c_cur;
146   struct PreferencePeer *p_cur;
147   int i;
148
149
150   GNUNET_assert (NULL != src);
151   GNUNET_assert (NULL != peer);
152 /*
153   LOG (GNUNET_ERROR_TYPE_DEBUG, "Client %p changes preference for peer `%s' %s %f\n",
154                                 src,
155                                 GNUNET_i2s (peer),
156                                 GNUNET_ATS_print_preference_type (kind),
157                                 score_abs);
158 */
159   if (kind >= GNUNET_ATS_PreferenceCount)
160   {
161       GNUNET_break (0);
162       return 0.0;
163   }
164
165   /* Find preference client */
166   for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
167   {
168       if (src == c_cur->client)
169         break;
170   }
171   /* Not found: create new preference client */
172   if (NULL == c_cur)
173   {
174     c_cur = GNUNET_malloc (sizeof (struct PreferenceClient));
175     c_cur->client = src;
176     GNUNET_CONTAINER_DLL_insert (pc_head, pc_tail, c_cur);
177   }
178
179   /* Find entry for peer */
180   for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
181     if (0 == memcmp (&p_cur->id, peer, sizeof (p_cur->id)))
182         break;
183
184   /* Not found: create new peer entry */
185   if (NULL == p_cur)
186   {
187       p_cur = GNUNET_malloc (sizeof (struct PreferencePeer));
188       p_cur->client = c_cur;
189       p_cur->id = (*peer);
190       for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
191       {
192         /* Default value per peer absolut preference for a quality:
193          * No value set, so absolute preference 0 */
194         p_cur->f[i] = DEFAULT_ABS_PREFERENCE;
195         /* Default value per peer relative preference for a quality: 1.0 */
196         p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
197       }
198       p_cur->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, &preference_aging, p_cur);
199       GNUNET_CONTAINER_DLL_insert (c_cur->p_head, c_cur->p_tail, p_cur);
200   }
201 //  update_preference (p_cur, kind, score);
202   return score_rel;
203 }
204
205 void
206 GAS_normalization_start ()
207 {
208         return;
209 }
210
211 void
212 GAS_normalization_stop ()
213 {
214   struct PreferenceClient *pc;
215   struct PreferenceClient *next_pc;
216   struct PreferencePeer *p;
217   struct PreferencePeer *next_p;
218
219   next_pc = pc_head;
220   while (NULL != (pc = next_pc))
221   {
222       next_pc = pc->next;
223       GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc);
224       next_p = pc->p_head;
225       while (NULL != (p = next_p))
226       {
227           next_p = p->next;
228           if (GNUNET_SCHEDULER_NO_TASK != p->aging_task)
229           {
230                 GNUNET_SCHEDULER_cancel(p->aging_task);
231                 p->aging_task = GNUNET_SCHEDULER_NO_TASK;
232           }
233           GNUNET_CONTAINER_DLL_remove (pc->p_head, pc->p_tail, p);
234           GNUNET_free (p);
235       }
236       GNUNET_free (pc);
237   }
238         return;
239 }
240
241 /* end of gnunet-service-ats_normalization.c */