summaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats_normalization.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-06-17 11:47:27 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-06-17 11:47:27 +0000
commit1320b67d1d14c614ec575735e9862560f1649388 (patch)
tree82de05fc7bad7a0b99906fc7abb59c6f4e6caaa9 /src/ats/gnunet-service-ats_normalization.c
parentd52bea90a2d3be57e79bb60456b6614a0089aa98 (diff)
downloadgnunet-1320b67d1d14c614ec575735e9862560f1649388.tar.gz
gnunet-1320b67d1d14c614ec575735e9862560f1649388.zip
changes
Diffstat (limited to 'src/ats/gnunet-service-ats_normalization.c')
-rw-r--r--src/ats/gnunet-service-ats_normalization.c185
1 files changed, 174 insertions, 11 deletions
diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c
index 08062012e..28ab2fb87 100644
--- a/src/ats/gnunet-service-ats_normalization.c
+++ b/src/ats/gnunet-service-ats_normalization.c
@@ -54,7 +54,7 @@ struct PreferenceClient
54 /** 54 /**
55 * Total preference for this peer 55 * Total preference for this peer
56 */ 56 */
57 double f_total[GNUNET_ATS_PreferenceCount]; 57 double f_abs_sum[GNUNET_ATS_PreferenceCount];
58 58
59 /** 59 /**
60 * List of peer preferences for this client 60 * List of peer preferences for this client
@@ -98,20 +98,24 @@ struct PreferencePeer
98 struct GNUNET_PeerIdentity id; 98 struct GNUNET_PeerIdentity id;
99 99
100 /** 100 /**
101 * Preference Values 101 * Absolute preference values
102 */ 102 */
103 double f[GNUNET_ATS_PreferenceCount]; 103 double f_abs[GNUNET_ATS_PreferenceCount];
104 104
105 /** 105 /**
106 * Relative Preference Values 106 * Relative preference values
107 */ 107 */
108 double f_rel[GNUNET_ATS_PreferenceCount]; 108 double f_rel[GNUNET_ATS_PreferenceCount];
109 109
110 /** 110 /**
111 * Relative Total Preference Value 111 * Relative total preference value
112 */ 112 */
113 double f_rel_total; 113 double f_rel_total;
114 114
115
116 /**
117 * Aging Task
118 */
115 GNUNET_SCHEDULER_TaskIdentifier aging_task; 119 GNUNET_SCHEDULER_TaskIdentifier aging_task;
116}; 120};
117 121
@@ -120,10 +124,169 @@ struct PreferencePeer
120struct PreferenceClient *pc_head; 124struct PreferenceClient *pc_head;
121struct PreferenceClient *pc_tail; 125struct PreferenceClient *pc_tail;
122 126
127
128
129static double
130update_peers (struct GNUNET_PeerIdentity *id,
131 enum GNUNET_ATS_PreferenceKind kind)
132{
133 struct PreferenceClient *c_cur;
134 struct PreferencePeer *p_cur;
135 double f_rel_total;
136 unsigned int count;
137
138 f_rel_total = 0.0;
139 count = 0;
140 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
141 {
142 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
143 {
144 if (0 == memcmp (id, &p_cur->id, sizeof (struct GNUNET_PeerIdentity)))
145 break;
146 }
147 if (NULL != p_cur)
148 {
149 f_rel_total += p_cur->f_rel[kind];
150 count ++;
151 }
152 }
153
154 if (0 < count)
155 {
156 f_rel_total /= count;
157 }
158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Total relative preference for all %u clients for %s is %.3f\n",
159 count,
160 GNUNET_ATS_print_preference_type (kind),
161 f_rel_total);
162 return f_rel_total;
163}
164
165/**
166 * Recalculate preference for a specific ATS property
167 *
168 * @param p the peer
169 * @param kind the preference kind
170 */
171static double
172recalculate_rel_preferences (struct PreferenceClient *c,
173 struct PreferencePeer *p,
174 enum GNUNET_ATS_PreferenceKind kind)
175{
176 struct PreferencePeer *p_cur;
177 double backup;
178 double res;
179 double ret;
180
181 /* For this client: sum preferences to total preference */
182 c->f_abs_sum[kind] = 0;
183 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
184 c->f_abs_sum[kind] += p_cur->f_abs[kind];
185
186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p has total preference for %s of %.3f\n",
187 c->client,
188 GNUNET_ATS_print_preference_type (kind),
189 c->f_abs_sum[kind]);
190
191 ret = 0.0;
192 /* For all peers: calculate relative preference */
193 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
194 {
195 /* Calculate relative preference for specific kind */
196 backup = p_cur->f_rel[kind];
197 if (DEFAULT_ABS_PREFERENCE == c->f_abs_sum[kind])
198 {
199 /* No peer has a preference for this property, so set default preference */
200 p_cur->f_rel[kind] = DEFAULT_REL_PREFERENCE;
201 }
202 else
203 {
204 p_cur->f_rel[kind] = (c->f_abs_sum[kind] + p_cur->f_abs[kind]) / c->f_abs_sum[kind];
205 }
206
207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p: peer `%s' has relative preference for %s of %.3f\n",
208 c->client,
209 GNUNET_i2s (&p_cur->id),
210 GNUNET_ATS_print_preference_type (kind),
211 p_cur->f_rel[kind]);
212
213 res = 0.0;
214 if (p_cur->f_rel[kind] != backup)
215 {
216 res = update_peers (&p_cur->id,kind);
217 if (0 == memcmp (&p->id, &p_cur->id, sizeof (struct GNUNET_PeerIdentity)))
218 {
219 ret = res;
220 }
221 }
222
223 }
224 return ret;
225}
226
227static double
228update_preference (struct PreferenceClient *c,
229 struct PreferencePeer *p,
230 enum GNUNET_ATS_PreferenceKind kind,
231 float score_abs)
232{
233 double score = score_abs;
234
235 /* Update preference value according to type */
236 switch (kind) {
237 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
238 case GNUNET_ATS_PREFERENCE_LATENCY:
239 p->f_abs[kind] = (p->f_abs[kind] + score) / 2;
240 break;
241 case GNUNET_ATS_PREFERENCE_END:
242 break;
243 default:
244 break;
245 }
246 return recalculate_rel_preferences (c, p, kind);
247}
248
123static void 249static void
124preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 250preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
125{ 251{
126 252 int i;
253 //double *t = NULL;
254 double backup;
255 struct PreferencePeer *p = cls;
256 GNUNET_assert (NULL != p);
257
258 p->aging_task = GNUNET_SCHEDULER_NO_TASK;
259
260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Aging preferences for peer `%s'\n",
261 GNUNET_i2s (&p->id));
262
263 /* Issue for aging :
264 *
265 * Not for every peer preference values are set by default, so reducing the
266 * absolute preference value does not help for aging because it does not have
267 * influence on the relative values.
268 *
269 * So we have to reduce the relative value to have an immediate impact on
270 * quota calculation. In addition we cannot call recalculate_preferences here
271 * but instead reduce the absolute value to have an aging impact on future
272 * calls to change_preference where recalculate_preferences is called
273 *
274 */
275 /* Aging absolute values: */
276 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
277 {
278 backup = p->f_abs[i];
279 if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE)
280 p->f_abs[i] *= PREF_AGING_FACTOR;
281 if (backup != p->f_abs[i])
282 {
283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Aged preference for peer `%s' from %.3f to %.3f\n",
284 GNUNET_i2s (&p->id), backup, p->f_abs[i]);
285 recalculate_rel_preferences (p->client, p, i);
286 }
287 }
288 p->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
289 &preference_aging, p);
127} 290}
128 291
129/** 292/**
@@ -149,13 +312,13 @@ GAS_normalization_change_preference (void *src,
149 312
150 GNUNET_assert (NULL != src); 313 GNUNET_assert (NULL != src);
151 GNUNET_assert (NULL != peer); 314 GNUNET_assert (NULL != peer);
152/* 315
153 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client %p changes preference for peer `%s' %s %f\n", 316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p changes preference for peer `%s' for `%s' to %.2f\n",
154 src, 317 src,
155 GNUNET_i2s (peer), 318 GNUNET_i2s (peer),
156 GNUNET_ATS_print_preference_type (kind), 319 GNUNET_ATS_print_preference_type (kind),
157 score_abs); 320 score_abs);
158*/ 321
159 if (kind >= GNUNET_ATS_PreferenceCount) 322 if (kind >= GNUNET_ATS_PreferenceCount)
160 { 323 {
161 GNUNET_break (0); 324 GNUNET_break (0);
@@ -191,14 +354,14 @@ GAS_normalization_change_preference (void *src,
191 { 354 {
192 /* Default value per peer absolut preference for a quality: 355 /* Default value per peer absolut preference for a quality:
193 * No value set, so absolute preference 0 */ 356 * No value set, so absolute preference 0 */
194 p_cur->f[i] = DEFAULT_ABS_PREFERENCE; 357 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE;
195 /* Default value per peer relative preference for a quality: 1.0 */ 358 /* Default value per peer relative preference for a quality: 1.0 */
196 p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; 359 p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
197 } 360 }
198 p_cur->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, &preference_aging, p_cur); 361 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); 362 GNUNET_CONTAINER_DLL_insert (c_cur->p_head, c_cur->p_tail, p_cur);
200 } 363 }
201// update_preference (p_cur, kind, score); 364 score_rel = update_preference (c_cur, p_cur, kind, score_abs);
202 return score_rel; 365 return score_rel;
203} 366}
204 367