diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-09-25 12:31:45 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-09-25 12:31:45 +0000 |
commit | 69b2a33cf1b5296a4d0c0f5a8693f8772b4d2bbf (patch) | |
tree | e41a2ccb90a97057ba7d20a5fdaa01a2bce3f745 /src/ats/gnunet-service-ats_normalization.c | |
parent | 304e0c0afb16f79780ccc11bcf9f1e7b81f31376 (diff) | |
download | gnunet-69b2a33cf1b5296a4d0c0f5a8693f8772b4d2bbf.tar.gz gnunet-69b2a33cf1b5296a4d0c0f5a8693f8772b4d2bbf.zip |
single aging task + indentation
Diffstat (limited to 'src/ats/gnunet-service-ats_normalization.c')
-rw-r--r-- | src/ats/gnunet-service-ats_normalization.c | 992 |
1 files changed, 490 insertions, 502 deletions
diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c index 24f551036..a028b06d3 100644 --- a/src/ats/gnunet-service-ats_normalization.c +++ b/src/ats/gnunet-service-ats_normalization.c | |||
@@ -1,22 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2011 Christian Grothoff (and other contributing authors) | 3 | (C) 2011 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 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 | 7 | by the Free Software Foundation; either version 3, or (at your |
8 | option) any later version. | 8 | option) any later version. |
9 | 9 | ||
10 | GNUnet is distributed in the hope that it will be useful, but | 10 | GNUnet is distributed in the hope that it will be useful, but |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | General Public License for more details. | 13 | General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 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 | 16 | along with GNUnet; see the file COPYING. If not, write to the |
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file ats/gnunet-service-ats_normalization.c | 22 | * @file ats/gnunet-service-ats_normalization.c |
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "ats-normalization",__VA_ARGS__) | 32 | #define LOG(kind,...) GNUNET_log_from (kind, "ats-normalization",__VA_ARGS__) |
33 | 33 | ||
34 | |||
35 | /** | 34 | /** |
36 | * Preference client | 35 | * Preference client |
37 | */ | 36 | */ |
@@ -73,7 +72,6 @@ struct PreferenceClient | |||
73 | struct PreferencePeer *p_tail; | 72 | struct PreferencePeer *p_tail; |
74 | }; | 73 | }; |
75 | 74 | ||
76 | |||
77 | /** | 75 | /** |
78 | * Preference peer | 76 | * Preference peer |
79 | */ | 77 | */ |
@@ -109,10 +107,7 @@ struct PreferencePeer | |||
109 | */ | 107 | */ |
110 | double f_rel[GNUNET_ATS_PreferenceCount]; | 108 | double f_rel[GNUNET_ATS_PreferenceCount]; |
111 | 109 | ||
112 | /** | 110 | struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount]; |
113 | * Aging Task | ||
114 | */ | ||
115 | GNUNET_SCHEDULER_TaskIdentifier aging_task; | ||
116 | }; | 111 | }; |
117 | 112 | ||
118 | /** | 113 | /** |
@@ -131,19 +126,16 @@ struct PeerRelative | |||
131 | struct GNUNET_PeerIdentity id; | 126 | struct GNUNET_PeerIdentity id; |
132 | }; | 127 | }; |
133 | 128 | ||
134 | |||
135 | /** | 129 | /** |
136 | * Callback to call on changing preference values | 130 | * Callback to call on changing preference values |
137 | */ | 131 | */ |
138 | static GAS_Normalization_preference_changed_cb pref_changed_cb; | 132 | static GAS_Normalization_preference_changed_cb pref_changed_cb; |
139 | 133 | ||
140 | |||
141 | /** | 134 | /** |
142 | * Closure for callback to call on changing preference values | 135 | * Closure for callback to call on changing preference values |
143 | */ | 136 | */ |
144 | static void *pref_changed_cb_cls; | 137 | static void *pref_changed_cb_cls; |
145 | 138 | ||
146 | |||
147 | /** | 139 | /** |
148 | * Callback to call on changing property values | 140 | * Callback to call on changing property values |
149 | */ | 141 | */ |
@@ -154,43 +146,37 @@ GAS_Normalization_property_changed_cb prop_ch_cb; | |||
154 | */ | 146 | */ |
155 | void *prop_ch_cb_cls; | 147 | void *prop_ch_cb_cls; |
156 | 148 | ||
157 | |||
158 | /** | 149 | /** |
159 | * Hashmap to store peer information for preference normalization | 150 | * Hashmap to store peer information for preference normalization |
160 | */ | 151 | */ |
161 | static struct GNUNET_CONTAINER_MultiHashMap *preference_peers; | 152 | static struct GNUNET_CONTAINER_MultiHashMap *preference_peers; |
162 | 153 | ||
163 | |||
164 | |||
165 | /** | 154 | /** |
166 | * Hashmap to store peer information for property normalization | 155 | * Hashmap to store peer information for property normalization |
167 | */ | 156 | */ |
168 | static struct GNUNET_CONTAINER_MultiHashMap *property_peers; | 157 | static struct GNUNET_CONTAINER_MultiHashMap *property_peers; |
169 | 158 | ||
170 | |||
171 | |||
172 | /** | 159 | /** |
173 | * Clients in DLL: head | 160 | * Clients in DLL: head |
174 | */ | 161 | */ |
175 | static struct PreferenceClient *pc_head; | 162 | static struct PreferenceClient *pc_head; |
176 | 163 | ||
177 | |||
178 | /** | 164 | /** |
179 | * Clients in DLL: tail | 165 | * Clients in DLL: tail |
180 | */ | 166 | */ |
181 | static struct PreferenceClient *pc_tail; | 167 | static struct PreferenceClient *pc_tail; |
182 | 168 | ||
183 | |||
184 | /** | 169 | /** |
185 | * Default values | 170 | * Default values |
186 | */ | 171 | */ |
187 | static struct PeerRelative defvalues; | 172 | static struct PeerRelative defvalues; |
188 | 173 | ||
174 | static GNUNET_SCHEDULER_TaskIdentifier aging_task; | ||
175 | |||
189 | /** | 176 | /** |
190 | * Application Preference Normalization | 177 | * Application Preference Normalization |
191 | */ | 178 | */ |
192 | 179 | ||
193 | |||
194 | /** | 180 | /** |
195 | * Update a peer | 181 | * Update a peer |
196 | * @param id peer id | 182 | * @param id peer id |
@@ -199,67 +185,66 @@ static struct PeerRelative defvalues; | |||
199 | */ | 185 | */ |
200 | static double | 186 | static double |
201 | update_peers (struct GNUNET_PeerIdentity *id, | 187 | update_peers (struct GNUNET_PeerIdentity *id, |
202 | enum GNUNET_ATS_PreferenceKind kind) | 188 | enum GNUNET_ATS_PreferenceKind kind) |
203 | { | 189 | { |
204 | struct PreferenceClient *c_cur; | 190 | struct PreferenceClient *c_cur; |
205 | struct PreferencePeer *p_cur; | 191 | struct PreferencePeer *p_cur; |
206 | struct PeerRelative *rp; | 192 | struct PeerRelative *rp; |
207 | double f_rel_total; | 193 | double f_rel_total; |
208 | double backup; | 194 | double backup; |
209 | unsigned int count; | 195 | unsigned int count; |
210 | 196 | ||
211 | f_rel_total = 0.0; | 197 | f_rel_total = 0.0; |
212 | count = 0; | 198 | count = 0; |
213 | 199 | ||
214 | /* For all clients */ | 200 | /* For all clients */ |
215 | for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) | 201 | for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) |
216 | { | 202 | { |
217 | /* Find peer with id */ | 203 | /* Find peer with id */ |
218 | for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) | 204 | for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) |
219 | { | 205 | { |
220 | if (0 == memcmp (id, &p_cur->id, sizeof (struct GNUNET_PeerIdentity))) | 206 | if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity))) |
221 | break; | 207 | break; |
222 | } | 208 | } |
223 | if (NULL != p_cur) | 209 | if (NULL != p_cur) |
224 | { | 210 | { |
225 | /* Found peer with id */ | 211 | /* Found peer with id */ |
226 | f_rel_total += p_cur->f_rel[kind]; | 212 | f_rel_total += p_cur->f_rel[kind]; |
227 | count ++; | 213 | count++; |
228 | } | 214 | } |
229 | } | 215 | } |
230 | 216 | ||
231 | /* Find a client */ | 217 | /* Find a client */ |
232 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 218 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
233 | "%u clients have a total relative preference for peer `%s''s `%s' of %.3f\n", | 219 | "%u clients have a total relative preference for peer `%s''s `%s' of %.3f\n", |
234 | count, | 220 | count, GNUNET_i2s (id), GNUNET_ATS_print_preference_type (kind), |
235 | GNUNET_i2s (id), | 221 | f_rel_total); |
236 | GNUNET_ATS_print_preference_type (kind), | 222 | if (NULL |
237 | f_rel_total); | 223 | != (rp = GNUNET_CONTAINER_multihashmap_get (preference_peers, |
238 | if (NULL != (rp = GNUNET_CONTAINER_multihashmap_get (preference_peers, &id->hashPubKey))) | 224 | &id->hashPubKey))) |
239 | { | 225 | { |
240 | backup = rp->f_rel[kind]; | 226 | backup = rp->f_rel[kind]; |
241 | if (0 < count) | 227 | if (0 < count) |
242 | { | 228 | { |
243 | rp->f_rel[kind] = f_rel_total / count; | 229 | rp->f_rel[kind] = f_rel_total / count; |
244 | } | 230 | } |
245 | else | 231 | else |
246 | { | 232 | { |
247 | rp->f_rel[kind] = DEFAULT_REL_PREFERENCE; | 233 | rp->f_rel[kind] = DEFAULT_REL_PREFERENCE; |
248 | } | 234 | } |
249 | } | 235 | } |
250 | else | 236 | else |
251 | { | 237 | { |
252 | return DEFAULT_REL_PREFERENCE; | 238 | return DEFAULT_REL_PREFERENCE; |
253 | } | 239 | } |
254 | |||
255 | if ((backup != rp->f_rel[kind]) && (NULL != pref_changed_cb)) | ||
256 | { | ||
257 | pref_changed_cb (pref_changed_cb_cls, &rp->id, kind, rp->f_rel[kind]); | ||
258 | } | ||
259 | |||
260 | return rp->f_rel[kind]; | ||
261 | } | ||
262 | 240 | ||
241 | if ((backup != rp->f_rel[kind]) && (NULL != pref_changed_cb)) | ||
242 | { | ||
243 | pref_changed_cb (pref_changed_cb_cls, &rp->id, kind, rp->f_rel[kind]); | ||
244 | } | ||
245 | |||
246 | return rp->f_rel[kind]; | ||
247 | } | ||
263 | 248 | ||
264 | /** | 249 | /** |
265 | * Recalculate preference for a specific ATS property | 250 | * Recalculate preference for a specific ATS property |
@@ -271,65 +256,59 @@ update_peers (struct GNUNET_PeerIdentity *id, | |||
271 | */ | 256 | */ |
272 | static double | 257 | static double |
273 | recalculate_rel_preferences (struct PreferenceClient *c, | 258 | recalculate_rel_preferences (struct PreferenceClient *c, |
274 | struct PreferencePeer *p, | 259 | struct PreferencePeer *p, enum GNUNET_ATS_PreferenceKind kind) |
275 | enum GNUNET_ATS_PreferenceKind kind) | ||
276 | { | 260 | { |
277 | struct PreferencePeer *p_cur; | 261 | struct PreferencePeer *p_cur; |
278 | struct PeerRelative *rp; | 262 | struct PeerRelative *rp; |
279 | double backup; | 263 | double backup; |
280 | double res; | 264 | double res; |
281 | double ret; | 265 | double ret; |
282 | 266 | ||
283 | /* For this client: sum preferences to total preference */ | 267 | /* For this client: sum preferences to total preference */ |
284 | c->f_abs_sum[kind] = 0; | 268 | c->f_abs_sum[kind] = 0; |
285 | for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) | 269 | for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) |
286 | c->f_abs_sum[kind] += p_cur->f_abs[kind]; | 270 | c->f_abs_sum[kind] += p_cur->f_abs[kind]; |
287 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 271 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
288 | "Client %p has total preference for %s of %.3f\n", | 272 | "Client %p has total preference for %s of %.3f\n", c->client, |
289 | c->client, | 273 | GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]); |
290 | GNUNET_ATS_print_preference_type (kind), | 274 | |
291 | c->f_abs_sum[kind]); | 275 | ret = DEFAULT_REL_PREFERENCE; |
292 | 276 | /* For all peers: calculate relative preference */ | |
293 | ret = DEFAULT_REL_PREFERENCE; | 277 | for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) |
294 | /* For all peers: calculate relative preference */ | 278 | { |
295 | for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) | 279 | /* Calculate relative preference for specific kind */ |
296 | { | 280 | backup = p_cur->f_rel[kind]; |
297 | /* Calculate relative preference for specific kind */ | 281 | if (DEFAULT_ABS_PREFERENCE == c->f_abs_sum[kind]) |
298 | backup = p_cur->f_rel[kind]; | 282 | /* No peer has a preference for this property, |
299 | if (DEFAULT_ABS_PREFERENCE == c->f_abs_sum[kind]) | 283 | * so set default preference */ |
300 | /* No peer has a preference for this property, | 284 | p_cur->f_rel[kind] = DEFAULT_REL_PREFERENCE; |
301 | * so set default preference */ | 285 | else |
302 | p_cur->f_rel[kind] = DEFAULT_REL_PREFERENCE; | 286 | p_cur->f_rel[kind] = (c->f_abs_sum[kind] + p_cur->f_abs[kind]) |
303 | else | 287 | / c->f_abs_sum[kind]; |
304 | p_cur->f_rel[kind] = (c->f_abs_sum[kind] + p_cur->f_abs[kind]) / | 288 | |
305 | c->f_abs_sum[kind]; | 289 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
306 | 290 | "Client %p: peer `%s' has relative preference for %s of %.3f\n", | |
307 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 291 | c->client, GNUNET_i2s (&p_cur->id), |
308 | "Client %p: peer `%s' has relative preference for %s of %.3f\n", | 292 | GNUNET_ATS_print_preference_type (kind), p_cur->f_rel[kind]); |
309 | c->client, | 293 | |
310 | GNUNET_i2s (&p_cur->id), | 294 | if (p_cur->f_rel[kind] != backup) |
311 | GNUNET_ATS_print_preference_type (kind), | 295 | { |
312 | p_cur->f_rel[kind]); | 296 | /* Value changed, recalculate */ |
313 | 297 | res = update_peers (&p_cur->id, kind); | |
314 | if (p_cur->f_rel[kind] != backup) | 298 | if (0 == memcmp (&p->id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity))) |
315 | { | 299 | ret = res; |
316 | /* Value changed, recalculate */ | 300 | } |
317 | res = update_peers (&p_cur->id,kind); | 301 | else |
318 | if (0 == memcmp (&p->id, &p_cur->id, sizeof (struct GNUNET_PeerIdentity))) | 302 | { |
319 | ret = res; | 303 | /* Value did not chang, return old value*/ |
320 | } | 304 | GNUNET_assert( |
321 | else | 305 | NULL != (rp = GNUNET_CONTAINER_multihashmap_get (preference_peers, &p->id.hashPubKey))); |
322 | { | 306 | ret = rp->f_rel[kind]; |
323 | /* Value did not chang, return old value*/ | 307 | } |
324 | GNUNET_assert (NULL != (rp = GNUNET_CONTAINER_multihashmap_get (preference_peers, | 308 | } |
325 | &p->id.hashPubKey))); | 309 | return ret; |
326 | ret = rp->f_rel[kind]; | ||
327 | } | ||
328 | } | ||
329 | return ret; | ||
330 | } | 310 | } |
331 | 311 | ||
332 | |||
333 | /** | 312 | /** |
334 | * Update the absolute preference value for a peer | 313 | * Update the absolute preference value for a peer |
335 | * @param c the client | 314 | * @param c the client |
@@ -339,28 +318,28 @@ recalculate_rel_preferences (struct PreferenceClient *c, | |||
339 | * @return the new relative preference value | 318 | * @return the new relative preference value |
340 | */ | 319 | */ |
341 | static double | 320 | static double |
342 | update_preference (struct PreferenceClient *c, | 321 | update_preference (struct PreferenceClient *c, struct PreferencePeer *p, |
343 | struct PreferencePeer *p, | 322 | enum GNUNET_ATS_PreferenceKind kind, float score_abs) |
344 | enum GNUNET_ATS_PreferenceKind kind, | ||
345 | float score_abs) | ||
346 | { | 323 | { |
347 | double score = score_abs; | 324 | double score = score_abs; |
348 | 325 | ||
349 | /* Update preference value according to type */ | 326 | /* Update preference value according to type */ |
350 | switch (kind) { | 327 | switch (kind) |
351 | case GNUNET_ATS_PREFERENCE_BANDWIDTH: | 328 | { |
352 | case GNUNET_ATS_PREFERENCE_LATENCY: | 329 | case GNUNET_ATS_PREFERENCE_BANDWIDTH: |
353 | p->f_abs[kind] = (p->f_abs[kind] + score) / 2; | 330 | case GNUNET_ATS_PREFERENCE_LATENCY: |
354 | break; | 331 | p->f_abs[kind] = (p->f_abs[kind] + score) / 2; |
355 | case GNUNET_ATS_PREFERENCE_END: | 332 | p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), |
356 | break; | 333 | PREF_AGING_INTERVAL); |
357 | default: | 334 | break; |
358 | break; | 335 | case GNUNET_ATS_PREFERENCE_END: |
336 | break; | ||
337 | default: | ||
338 | break; | ||
359 | } | 339 | } |
360 | return recalculate_rel_preferences (c, p, kind); | 340 | return recalculate_rel_preferences (c, p, kind); |
361 | } | 341 | } |
362 | 342 | ||
363 | |||
364 | /** | 343 | /** |
365 | * Reduce absolute preferences since they got old | 344 | * Reduce absolute preferences since they got old |
366 | * | 345 | * |
@@ -370,33 +349,53 @@ update_preference (struct PreferenceClient *c, | |||
370 | static void | 349 | static void |
371 | preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 350 | preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
372 | { | 351 | { |
373 | int i; | 352 | int i; |
374 | double backup; | 353 | int values_to_update; |
375 | struct PreferencePeer *p = cls; | 354 | double backup; |
376 | GNUNET_assert (NULL != p); | 355 | struct PreferencePeer *p; |
377 | 356 | struct PreferenceClient *pc; | |
378 | p->aging_task = GNUNET_SCHEDULER_NO_TASK; | 357 | aging_task = GNUNET_SCHEDULER_NO_TASK; |
379 | 358 | GNUNET_break (0); | |
380 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Aging preferences for peer `%s'\n", | 359 | values_to_update = 0; |
381 | GNUNET_i2s (&p->id)); | 360 | for (pc = pc_head; NULL != pc; pc =pc->next); |
382 | |||
383 | /* Aging absolute values: */ | ||
384 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
385 | { | 361 | { |
386 | backup = p->f_abs[i]; | 362 | GNUNET_break (0); |
387 | if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE) | 363 | for (p = pc->p_head; NULL != p; p = p->next) |
388 | p->f_abs[i] *= PREF_AGING_FACTOR; | 364 | { |
389 | if (backup != p->f_abs[i]) | 365 | GNUNET_break (0); |
390 | { | 366 | /* Aging absolute values: */ |
391 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Aged preference for peer `%s' from %.3f to %.3f\n", | 367 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) |
392 | GNUNET_i2s (&p->id), backup, p->f_abs[i]); | 368 | { |
393 | recalculate_rel_preferences (p->client, p, i); | 369 | GNUNET_break (0); |
394 | } | 370 | if (0 == GNUNET_TIME_absolute_get_remaining(p->next_aging[i]).rel_value_us) |
395 | } | 371 | { |
396 | p->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, | 372 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Aging preferences for peer `%s'\n", |
397 | &preference_aging, p); | 373 | GNUNET_i2s (&p->id)); |
398 | } | 374 | } |
375 | |||
376 | backup = p->f_abs[i]; | ||
377 | if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE) | ||
378 | p->f_abs[i] *= PREF_AGING_FACTOR; | ||
379 | if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON) | ||
380 | p->f_abs[i] = DEFAULT_ABS_PREFERENCE; | ||
381 | if ((p->f_abs[i] != DEFAULT_ABS_PREFERENCE) && (backup != p->f_abs[i])) | ||
382 | { | ||
383 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
384 | "Aged preference for peer `%s' from %.3f to %.3f\n", | ||
385 | GNUNET_i2s (&p->id), backup, p->f_abs[i]); | ||
386 | recalculate_rel_preferences (p->client, p, i); | ||
387 | p->next_aging[i] = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), | ||
388 | PREF_AGING_INTERVAL); | ||
389 | values_to_update ++; | ||
390 | } | ||
391 | } /* preferences */ | ||
392 | } /* end: p */ | ||
393 | } /* end: pc_head */ | ||
394 | if (values_to_update > 0) | ||
395 | aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, | ||
396 | &preference_aging, NULL); | ||
399 | 397 | ||
398 | } | ||
400 | 399 | ||
401 | /** | 400 | /** |
402 | * Normalize an updated preference value | 401 | * Normalize an updated preference value |
@@ -408,84 +407,82 @@ preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
408 | */ | 407 | */ |
409 | void | 408 | void |
410 | GAS_normalization_normalize_preference (void *src, | 409 | GAS_normalization_normalize_preference (void *src, |
411 | const struct GNUNET_PeerIdentity *peer, | 410 | const struct GNUNET_PeerIdentity *peer, |
412 | enum GNUNET_ATS_PreferenceKind kind, | 411 | enum GNUNET_ATS_PreferenceKind kind, |
413 | float score_abs) | 412 | float score_abs) |
414 | { | 413 | { |
415 | struct PreferenceClient *c_cur; | 414 | struct PreferenceClient *c_cur; |
416 | struct PreferencePeer *p_cur; | 415 | struct PreferencePeer *p_cur; |
417 | struct PeerRelative *r_cur; | 416 | struct PeerRelative *r_cur; |
418 | int i; | 417 | int i; |
419 | 418 | ||
419 | GNUNET_assert(NULL != src); | ||
420 | GNUNET_assert(NULL != peer); | ||
420 | 421 | ||
421 | GNUNET_assert (NULL != src); | 422 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
422 | GNUNET_assert (NULL != peer); | 423 | "Client %p changes preference for peer `%s' for `%s' to %.2f\n", src, |
423 | 424 | GNUNET_i2s (peer), GNUNET_ATS_print_preference_type (kind), score_abs); | |
424 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
425 | "Client %p changes preference for peer `%s' for `%s' to %.2f\n", | ||
426 | src, | ||
427 | GNUNET_i2s (peer), | ||
428 | GNUNET_ATS_print_preference_type (kind), | ||
429 | score_abs); | ||
430 | 425 | ||
431 | if (kind >= GNUNET_ATS_PreferenceCount) | 426 | if (kind >= GNUNET_ATS_PreferenceCount) |
432 | { | 427 | { |
433 | GNUNET_break (0); | 428 | GNUNET_break(0); |
434 | return; | 429 | return; |
435 | } | 430 | } |
436 | 431 | ||
437 | /* Find preference client */ | 432 | /* Find preference client */ |
438 | for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) | 433 | for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) |
439 | { | 434 | { |
440 | if (src == c_cur->client) | 435 | if (src == c_cur->client) |
441 | break; | 436 | break; |
442 | } | 437 | } |
443 | /* Not found: create new preference client */ | 438 | /* Not found: create new preference client */ |
444 | if (NULL == c_cur) | 439 | if (NULL == c_cur) |
445 | { | 440 | { |
446 | c_cur = GNUNET_malloc (sizeof (struct PreferenceClient)); | 441 | c_cur = GNUNET_malloc (sizeof (struct PreferenceClient)); |
447 | c_cur->client = src; | 442 | c_cur->client = src; |
448 | GNUNET_CONTAINER_DLL_insert (pc_head, pc_tail, c_cur); | 443 | GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur); |
449 | } | 444 | } |
450 | 445 | ||
451 | /* Find entry for peer */ | 446 | /* Find entry for peer */ |
452 | for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) | 447 | for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) |
453 | if (0 == memcmp (&p_cur->id, peer, sizeof (p_cur->id))) | 448 | if (0 == memcmp (&p_cur->id, peer, sizeof(p_cur->id))) |
454 | break; | 449 | break; |
455 | 450 | ||
456 | /* Not found: create new peer entry */ | 451 | /* Not found: create new peer entry */ |
457 | if (NULL == p_cur) | 452 | if (NULL == p_cur) |
458 | { | 453 | { |
459 | p_cur = GNUNET_malloc (sizeof (struct PreferencePeer)); | 454 | p_cur = GNUNET_malloc (sizeof (struct PreferencePeer)); |
460 | p_cur->client = c_cur; | 455 | p_cur->client = c_cur; |
461 | p_cur->id = (*peer); | 456 | p_cur->id = (*peer); |
462 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | 457 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) |
463 | { | 458 | { |
464 | /* Default value per peer absolut preference for a quality: | 459 | /* Default value per peer absolut preference for a quality: |
465 | * No value set, so absolute preference 0 */ | 460 | * No value set, so absolute preference 0 */ |
466 | p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; | 461 | p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; |
467 | /* Default value per peer relative preference for a quality: 1.0 */ | 462 | /* Default value per peer relative preference for a quality: 1.0 */ |
468 | p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; | 463 | p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; |
469 | } | 464 | } |
470 | p_cur->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, | 465 | GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur); |
471 | &preference_aging, p_cur); | ||
472 | GNUNET_CONTAINER_DLL_insert (c_cur->p_head, c_cur->p_tail, p_cur); | ||
473 | } | 466 | } |
474 | 467 | ||
475 | if (NULL == GNUNET_CONTAINER_multihashmap_get (preference_peers, | 468 | if (NULL == GNUNET_CONTAINER_multihashmap_get (preference_peers, |
476 | &peer->hashPubKey)) | 469 | &peer->hashPubKey)) |
477 | { | 470 | { |
478 | r_cur = GNUNET_malloc (sizeof (struct PeerRelative)); | 471 | r_cur = GNUNET_malloc (sizeof (struct PeerRelative)); |
479 | r_cur->id = (*peer); | 472 | r_cur->id = (*peer); |
480 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | 473 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) |
481 | r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; | 474 | r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; |
482 | GNUNET_CONTAINER_multihashmap_put (preference_peers, &r_cur->id.hashPubKey, | 475 | GNUNET_CONTAINER_multihashmap_put (preference_peers, &r_cur->id.hashPubKey, |
483 | r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 476 | r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
484 | } | 477 | } |
478 | |||
479 | if (GNUNET_SCHEDULER_NO_TASK == aging_task) | ||
480 | aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, | ||
481 | &preference_aging, NULL); | ||
482 | |||
485 | update_preference (c_cur, p_cur, kind, score_abs); | 483 | update_preference (c_cur, p_cur, kind, score_abs); |
486 | } | 484 | } |
487 | 485 | ||
488 | |||
489 | /** | 486 | /** |
490 | * Get the normalized preference values for a specific peer or | 487 | * Get the normalized preference values for a specific peer or |
491 | * the default values if | 488 | * the default values if |
@@ -497,17 +494,18 @@ GAS_normalization_normalize_preference (void *src, | |||
497 | const double * | 494 | const double * |
498 | GAS_normalization_get_preferences (const struct GNUNET_PeerIdentity *id) | 495 | GAS_normalization_get_preferences (const struct GNUNET_PeerIdentity *id) |
499 | { | 496 | { |
500 | GNUNET_assert (NULL != preference_peers); | 497 | GNUNET_assert(NULL != preference_peers); |
501 | GNUNET_assert (NULL != id); | 498 | GNUNET_assert(NULL != id); |
502 | |||
503 | struct PeerRelative *rp; | ||
504 | if (NULL == (rp = GNUNET_CONTAINER_multihashmap_get (preference_peers, &id->hashPubKey))) | ||
505 | { | ||
506 | return defvalues.f_rel; | ||
507 | } | ||
508 | return rp->f_rel; | ||
509 | } | ||
510 | 499 | ||
500 | struct PeerRelative *rp; | ||
501 | if (NULL | ||
502 | == (rp = GNUNET_CONTAINER_multihashmap_get (preference_peers, | ||
503 | &id->hashPubKey))) | ||
504 | { | ||
505 | return defvalues.f_rel; | ||
506 | } | ||
507 | return rp->f_rel; | ||
508 | } | ||
511 | 509 | ||
512 | /** | 510 | /** |
513 | * Get the normalized properties values for a specific peer or | 511 | * Get the normalized properties values for a specific peer or |
@@ -520,22 +518,20 @@ GAS_normalization_get_preferences (const struct GNUNET_PeerIdentity *id) | |||
520 | const double * | 518 | const double * |
521 | GAS_normalization_get_properties (struct ATS_Address *address) | 519 | GAS_normalization_get_properties (struct ATS_Address *address) |
522 | { | 520 | { |
523 | static double norm_values[GNUNET_ATS_QualityPropertiesCount]; | 521 | static double norm_values[GNUNET_ATS_QualityPropertiesCount]; |
524 | int i; | 522 | int i; |
525 | 523 | ||
526 | GNUNET_assert (NULL != address); | 524 | GNUNET_assert(NULL != address); |
527 | |||
528 | for (i = 0; i < GNUNET_ATS_QualityPropertiesCount; i++) | ||
529 | { | ||
530 | if ((address->atsin[i].norm >= 1.0) && | ||
531 | (address->atsin[i].norm <= 2.0)) | ||
532 | norm_values[i] = address->atsin[i].norm; | ||
533 | else | ||
534 | norm_values[i] = DEFAULT_REL_QUALITY; | ||
535 | } | ||
536 | return norm_values; | ||
537 | } | ||
538 | 525 | ||
526 | for (i = 0; i < GNUNET_ATS_QualityPropertiesCount; i++) | ||
527 | { | ||
528 | if ((address->atsin[i].norm >= 1.0) && (address->atsin[i].norm <= 2.0)) | ||
529 | norm_values[i] = address->atsin[i].norm; | ||
530 | else | ||
531 | norm_values[i] = DEFAULT_REL_QUALITY; | ||
532 | } | ||
533 | return norm_values; | ||
534 | } | ||
539 | 535 | ||
540 | /** | 536 | /** |
541 | * Quality Normalization | 537 | * Quality Normalization |
@@ -543,10 +539,10 @@ GAS_normalization_get_properties (struct ATS_Address *address) | |||
543 | 539 | ||
544 | struct Property | 540 | struct Property |
545 | { | 541 | { |
546 | uint32_t prop_type; | 542 | uint32_t prop_type; |
547 | uint32_t atsi_type; | 543 | uint32_t atsi_type; |
548 | uint32_t min; | 544 | uint32_t min; |
549 | uint32_t max; | 545 | uint32_t max; |
550 | }; | 546 | }; |
551 | 547 | ||
552 | struct Property properties[GNUNET_ATS_QualityPropertiesCount]; | 548 | struct Property properties[GNUNET_ATS_QualityPropertiesCount]; |
@@ -560,118 +556,114 @@ struct Property properties[GNUNET_ATS_QualityPropertiesCount]; | |||
560 | 556 | ||
561 | uint32_t | 557 | uint32_t |
562 | property_average (struct ATS_Address *address, | 558 | property_average (struct ATS_Address *address, |
563 | const struct GNUNET_ATS_Information *atsi) | 559 | const struct GNUNET_ATS_Information *atsi) |
564 | { | 560 | { |
565 | struct GAS_NormalizationInfo *ni; | 561 | struct GAS_NormalizationInfo *ni; |
566 | uint32_t current_type; | 562 | uint32_t current_type; |
567 | uint32_t current_val; | 563 | uint32_t current_val; |
568 | uint32_t res; | 564 | uint32_t res; |
569 | uint64_t sum; | 565 | uint64_t sum; |
570 | uint32_t count; | 566 | uint32_t count; |
571 | unsigned int c1; | 567 | unsigned int c1; |
572 | unsigned int index; | 568 | unsigned int index; |
573 | unsigned int props[] = GNUNET_ATS_QualityProperties; | 569 | unsigned int props[] = GNUNET_ATS_QualityProperties; |
574 | 570 | ||
575 | /* Average the values of this property */ | 571 | /* Average the values of this property */ |
576 | current_type = ntohl (atsi->type); | 572 | current_type = ntohl (atsi->type); |
577 | current_val = ntohl (atsi->value); | 573 | current_val = ntohl (atsi->value); |
578 | 574 | ||
579 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) | 575 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) |
580 | { | 576 | { |
581 | if (current_type == props[c1]) | 577 | if (current_type == props[c1]) |
582 | break; | 578 | break; |
583 | } | 579 | } |
584 | if (c1 == GNUNET_ATS_QualityPropertiesCount) | 580 | if (c1 == GNUNET_ATS_QualityPropertiesCount) |
585 | { | 581 | { |
586 | GNUNET_break (0); | 582 | GNUNET_break(0); |
587 | return GNUNET_ATS_VALUE_UNDEFINED; | 583 | return GNUNET_ATS_VALUE_UNDEFINED; |
588 | } | 584 | } |
589 | index = c1; | 585 | index = c1; |
590 | |||
591 | ni = &address->atsin[index]; | ||
592 | ni->atsi_abs[ni->avg_queue_index] = current_val; | ||
593 | ni->avg_queue_index ++; | ||
594 | if (GAS_normalization_queue_length == ni->avg_queue_index) | ||
595 | ni->avg_queue_index = 0; | ||
596 | |||
597 | count = 0; | ||
598 | sum = 0; | ||
599 | for (c1 = 0; c1 < GAS_normalization_queue_length; c1++) | ||
600 | { | ||
601 | if (GNUNET_ATS_VALUE_UNDEFINED != ni->atsi_abs[c1]) | ||
602 | { | ||
603 | count++; | ||
604 | if (GNUNET_ATS_VALUE_UNDEFINED > (sum + ni->atsi_abs[c1])) | ||
605 | sum += ni->atsi_abs[c1]; | ||
606 | else | ||
607 | { | ||
608 | sum = GNUNET_ATS_VALUE_UNDEFINED - 1; | ||
609 | GNUNET_break (0); | ||
610 | } | ||
611 | } | ||
612 | } | ||
613 | GNUNET_assert (0 != count); | ||
614 | res = sum / count; | ||
615 | LOG (GNUNET_ERROR_TYPE_DEBUG, "New average of `%s' created by adding %u from %u elements: %u\n", | ||
616 | GNUNET_ATS_print_property_type(current_type), | ||
617 | current_val, count, res , sum); | ||
618 | ni->avg = res; | ||
619 | return res; | ||
620 | } | ||
621 | 586 | ||
587 | ni = &address->atsin[index]; | ||
588 | ni->atsi_abs[ni->avg_queue_index] = current_val; | ||
589 | ni->avg_queue_index++; | ||
590 | if (GAS_normalization_queue_length == ni->avg_queue_index) | ||
591 | ni->avg_queue_index = 0; | ||
592 | |||
593 | count = 0; | ||
594 | sum = 0; | ||
595 | for (c1 = 0; c1 < GAS_normalization_queue_length; c1++) | ||
596 | { | ||
597 | if (GNUNET_ATS_VALUE_UNDEFINED != ni->atsi_abs[c1]) | ||
598 | { | ||
599 | count++; | ||
600 | if (GNUNET_ATS_VALUE_UNDEFINED > (sum + ni->atsi_abs[c1])) | ||
601 | sum += ni->atsi_abs[c1]; | ||
602 | else | ||
603 | { | ||
604 | sum = GNUNET_ATS_VALUE_UNDEFINED - 1; | ||
605 | GNUNET_break(0); | ||
606 | } | ||
607 | } | ||
608 | } | ||
609 | GNUNET_assert(0 != count); | ||
610 | res = sum / count; | ||
611 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
612 | "New average of `%s' created by adding %u from %u elements: %u\n", | ||
613 | GNUNET_ATS_print_property_type (current_type), current_val, count, res, | ||
614 | sum); | ||
615 | ni->avg = res; | ||
616 | return res; | ||
617 | } | ||
622 | 618 | ||
623 | struct FindMinMaxCtx | 619 | struct FindMinMaxCtx |
624 | { | 620 | { |
625 | struct Property *p; | 621 | struct Property *p; |
626 | uint32_t min; | 622 | uint32_t min; |
627 | uint32_t max; | 623 | uint32_t max; |
628 | }; | 624 | }; |
629 | 625 | ||
630 | static int | 626 | static int |
631 | find_min_max_it (void *cls, const struct GNUNET_HashCode *h, void *k) | 627 | find_min_max_it (void *cls, const struct GNUNET_HashCode *h, void *k) |
632 | { | 628 | { |
633 | struct ATS_Address *a = (struct ATS_Address *) k; | 629 | struct ATS_Address *a = (struct ATS_Address *) k; |
634 | struct FindMinMaxCtx *find_res = cls; | 630 | struct FindMinMaxCtx *find_res = cls; |
635 | 631 | ||
636 | if (a->atsin[find_res->p->prop_type].avg > find_res->max) | 632 | if (a->atsin[find_res->p->prop_type].avg > find_res->max) |
637 | find_res->max = a->atsin[find_res->p->prop_type].avg; | 633 | find_res->max = a->atsin[find_res->p->prop_type].avg; |
638 | 634 | ||
639 | if (a->atsin[find_res->p->prop_type].avg < find_res->min) | 635 | if (a->atsin[find_res->p->prop_type].avg < find_res->min) |
640 | find_res->min = a->atsin[find_res->p->prop_type].avg; | 636 | find_res->min = a->atsin[find_res->p->prop_type].avg; |
641 | 637 | ||
642 | return GNUNET_OK; | 638 | return GNUNET_OK; |
643 | } | 639 | } |
644 | 640 | ||
645 | |||
646 | static int | 641 | static int |
647 | normalize_address (void *cls, const struct GNUNET_HashCode *h, void *k) | 642 | normalize_address (void *cls, const struct GNUNET_HashCode *h, void *k) |
648 | { | 643 | { |
649 | struct Property *p = cls; | 644 | struct Property *p = cls; |
650 | struct ATS_Address *address = (struct ATS_Address *) k; | 645 | struct ATS_Address *address = (struct ATS_Address *) k; |
651 | |||
652 | double delta; | ||
653 | uint32_t avg_value = address->atsin[p->prop_type].avg; | ||
654 | 646 | ||
655 | delta = p->max - p->min; | 647 | double delta; |
656 | address->atsin[p->prop_type].norm = (delta + (avg_value - p->min)) / (delta); | 648 | uint32_t avg_value = address->atsin[p->prop_type].avg; |
657 | 649 | ||
658 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalize `%s' address %p's '%s' with value %u to range [%u..%u] = %.3f\n", | 650 | delta = p->max - p->min; |
659 | GNUNET_i2s (&address->peer), | 651 | address->atsin[p->prop_type].norm = (delta + (avg_value - p->min)) / (delta); |
660 | address, | ||
661 | GNUNET_ATS_print_property_type (p->atsi_type), | ||
662 | address->atsin[p->prop_type].avg, | ||
663 | p->min, p->max, | ||
664 | address->atsin[p->prop_type].norm ); | ||
665 | 652 | ||
666 | if (NULL != prop_ch_cb) | 653 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
667 | prop_ch_cb (prop_ch_cb_cls, address, p->atsi_type, | 654 | "Normalize `%s' address %p's '%s' with value %u to range [%u..%u] = %.3f\n", |
668 | address->atsin[p->prop_type].norm); | 655 | GNUNET_i2s (&address->peer), address, |
656 | GNUNET_ATS_print_property_type (p->atsi_type), | ||
657 | address->atsin[p->prop_type].avg, p->min, p->max, | ||
658 | address->atsin[p->prop_type].norm); | ||
669 | 659 | ||
660 | if (NULL != prop_ch_cb) | ||
661 | prop_ch_cb (prop_ch_cb_cls, address, p->atsi_type, | ||
662 | address->atsin[p->prop_type].norm); | ||
670 | 663 | ||
671 | return GNUNET_OK; | 664 | return GNUNET_OK; |
672 | } | 665 | } |
673 | 666 | ||
674 | |||
675 | /** | 667 | /** |
676 | * Normalize avg_value to a range of values between [1.0, 2.0] | 668 | * Normalize avg_value to a range of values between [1.0, 2.0] |
677 | * based on min max values currently known. | 669 | * based on min max values currently known. |
@@ -684,64 +676,62 @@ normalize_address (void *cls, const struct GNUNET_HashCode *h, void *k) | |||
684 | 676 | ||
685 | static void | 677 | static void |
686 | property_normalize (struct GNUNET_CONTAINER_MultiHashMap *addresses, | 678 | property_normalize (struct GNUNET_CONTAINER_MultiHashMap *addresses, |
687 | struct Property *p, | 679 | struct Property *p, struct ATS_Address *address, uint32_t avg_value) |
688 | struct ATS_Address *address, | ||
689 | uint32_t avg_value) | ||
690 | { | 680 | { |
691 | struct FindMinMaxCtx find_ctx; | 681 | struct FindMinMaxCtx find_ctx; |
692 | int addr_count; | 682 | int addr_count; |
693 | int limits_changed; | 683 | int limits_changed; |
694 | 684 | ||
695 | find_ctx.p = p; | 685 | find_ctx.p = p; |
696 | find_ctx.max = 0; | 686 | find_ctx.max = 0; |
697 | find_ctx.min = UINT32_MAX; | 687 | find_ctx.min = UINT32_MAX; |
698 | addr_count = GNUNET_CONTAINER_multihashmap_iterate(addresses, &find_min_max_it, &find_ctx); | 688 | addr_count = GNUNET_CONTAINER_multihashmap_iterate (addresses, |
699 | if (0 == addr_count) | 689 | &find_min_max_it, &find_ctx); |
700 | { | 690 | if (0 == addr_count) |
701 | GNUNET_break (0); | 691 | { |
702 | return; | 692 | GNUNET_break(0); |
703 | } | 693 | return; |
704 | 694 | } | |
705 | 695 | ||
706 | limits_changed = GNUNET_NO; | 696 | limits_changed = GNUNET_NO; |
707 | if (find_ctx.max != p->max) | 697 | if (find_ctx.max != p->max) |
708 | { | 698 | { |
709 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalizing %s: new maximum %u -> recalculate all values\n", | 699 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
710 | GNUNET_ATS_print_property_type (p->atsi_type), | 700 | "Normalizing %s: new maximum %u -> recalculate all values\n", |
711 | find_ctx.max); | 701 | GNUNET_ATS_print_property_type (p->atsi_type), find_ctx.max); |
712 | p->max = find_ctx.max; | 702 | p->max = find_ctx.max; |
713 | limits_changed = GNUNET_YES; | 703 | limits_changed = GNUNET_YES; |
714 | } | 704 | } |
715 | |||
716 | if ((find_ctx.min != p->min) && (find_ctx.min < p->max)) | ||
717 | { | ||
718 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalizing %s: new minimum %u -> recalculate all values\n", | ||
719 | GNUNET_ATS_print_property_type (p->atsi_type), | ||
720 | find_ctx.min, find_ctx.max); | ||
721 | p->min = find_ctx.min; | ||
722 | limits_changed = GNUNET_YES; | ||
723 | } | ||
724 | else if (find_ctx.min == p->max) | ||
725 | { | ||
726 | /* Only one value, so minimum has to be 0 */ | ||
727 | p->min = 0; | ||
728 | } | ||
729 | |||
730 | /* Normalize the values of this property */ | ||
731 | if (GNUNET_NO == limits_changed) | ||
732 | { | ||
733 | /* normalize just this address */ | ||
734 | normalize_address (p, &address->peer.hashPubKey, address); | ||
735 | return; | ||
736 | } | ||
737 | else | ||
738 | { | ||
739 | /* limits changed, normalize all addresses */ | ||
740 | GNUNET_CONTAINER_multihashmap_iterate(addresses, &normalize_address, p); | ||
741 | return; | ||
742 | } | ||
743 | } | ||
744 | 705 | ||
706 | if ((find_ctx.min != p->min) && (find_ctx.min < p->max)) | ||
707 | { | ||
708 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
709 | "Normalizing %s: new minimum %u -> recalculate all values\n", | ||
710 | GNUNET_ATS_print_property_type (p->atsi_type), find_ctx.min, | ||
711 | find_ctx.max); | ||
712 | p->min = find_ctx.min; | ||
713 | limits_changed = GNUNET_YES; | ||
714 | } | ||
715 | else if (find_ctx.min == p->max) | ||
716 | { | ||
717 | /* Only one value, so minimum has to be 0 */ | ||
718 | p->min = 0; | ||
719 | } | ||
720 | |||
721 | /* Normalize the values of this property */ | ||
722 | if (GNUNET_NO == limits_changed) | ||
723 | { | ||
724 | /* normalize just this address */ | ||
725 | normalize_address (p, &address->peer.hashPubKey, address); | ||
726 | return; | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | /* limits changed, normalize all addresses */ | ||
731 | GNUNET_CONTAINER_multihashmap_iterate (addresses, &normalize_address, p); | ||
732 | return; | ||
733 | } | ||
734 | } | ||
745 | 735 | ||
746 | /** | 736 | /** |
747 | * Update and normalize atsi performance information | 737 | * Update and normalize atsi performance information |
@@ -752,54 +742,53 @@ property_normalize (struct GNUNET_CONTAINER_MultiHashMap *addresses, | |||
752 | * @param atsi_count the number of atsi information in the array | 742 | * @param atsi_count the number of atsi information in the array |
753 | */ | 743 | */ |
754 | void | 744 | void |
755 | GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiHashMap *addresses, | 745 | GAS_normalization_normalize_property ( |
756 | struct ATS_Address *address, | 746 | struct GNUNET_CONTAINER_MultiHashMap *addresses, |
757 | const struct GNUNET_ATS_Information *atsi, | 747 | struct ATS_Address *address, const struct GNUNET_ATS_Information *atsi, |
758 | uint32_t atsi_count) | 748 | uint32_t atsi_count) |
759 | { | 749 | { |
760 | struct Property *cur_prop; | 750 | struct Property *cur_prop; |
761 | int c1; | 751 | int c1; |
762 | int c2; | 752 | int c2; |
763 | uint32_t current_type; | 753 | uint32_t current_type; |
764 | uint32_t current_val; | 754 | uint32_t current_val; |
765 | unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; | 755 | unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; |
766 | 756 | ||
767 | GNUNET_assert (NULL != address); | 757 | GNUNET_assert(NULL != address); |
768 | GNUNET_assert (NULL != atsi); | 758 | GNUNET_assert(NULL != atsi); |
769 | |||
770 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating %u elements for peer `%s'\n", | ||
771 | atsi_count, GNUNET_i2s (&address->peer)); | ||
772 | |||
773 | for (c1 = 0; c1 < atsi_count; c1++) | ||
774 | { | ||
775 | current_type = ntohl (atsi[c1].type); | ||
776 | |||
777 | for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) | ||
778 | { | ||
779 | /* Check if type is valid */ | ||
780 | if (current_type == existing_properties[c2]) | ||
781 | break; | ||
782 | } | ||
783 | if (GNUNET_ATS_QualityPropertiesCount == c2) | ||
784 | { | ||
785 | /* Invalid property, continue with next element */ | ||
786 | continue; | ||
787 | } | ||
788 | /* Averaging */ | ||
789 | current_val = property_average (address, &atsi[c1]); | ||
790 | if (GNUNET_ATS_VALUE_UNDEFINED == current_val) | ||
791 | { | ||
792 | GNUNET_break (0); | ||
793 | continue; | ||
794 | } | ||
795 | |||
796 | /* Normalizing */ | ||
797 | /* Check min, max */ | ||
798 | cur_prop = &properties[c2]; | ||
799 | property_normalize (addresses, cur_prop, address, current_val); | ||
800 | } | ||
801 | } | ||
802 | 759 | ||
760 | LOG(GNUNET_ERROR_TYPE_DEBUG, "Updating %u elements for peer `%s'\n", | ||
761 | atsi_count, GNUNET_i2s (&address->peer)); | ||
762 | |||
763 | for (c1 = 0; c1 < atsi_count; c1++) | ||
764 | { | ||
765 | current_type = ntohl (atsi[c1].type); | ||
766 | |||
767 | for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++) | ||
768 | { | ||
769 | /* Check if type is valid */ | ||
770 | if (current_type == existing_properties[c2]) | ||
771 | break; | ||
772 | } | ||
773 | if (GNUNET_ATS_QualityPropertiesCount == c2) | ||
774 | { | ||
775 | /* Invalid property, continue with next element */ | ||
776 | continue; | ||
777 | } | ||
778 | /* Averaging */ | ||
779 | current_val = property_average (address, &atsi[c1]); | ||
780 | if (GNUNET_ATS_VALUE_UNDEFINED == current_val) | ||
781 | { | ||
782 | GNUNET_break(0); | ||
783 | continue; | ||
784 | } | ||
785 | |||
786 | /* Normalizing */ | ||
787 | /* Check min, max */ | ||
788 | cur_prop = &properties[c2]; | ||
789 | property_normalize (addresses, cur_prop, address, current_val); | ||
790 | } | ||
791 | } | ||
803 | 792 | ||
804 | /** | 793 | /** |
805 | * Start the normalization component | 794 | * Start the normalization component |
@@ -811,34 +800,33 @@ GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiHashMap *addr | |||
811 | */ | 800 | */ |
812 | void | 801 | void |
813 | GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, | 802 | GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, |
814 | void *pref_ch_cb_cls, | 803 | void *pref_ch_cb_cls, GAS_Normalization_property_changed_cb property_ch_cb, |
815 | GAS_Normalization_property_changed_cb property_ch_cb, | 804 | void *property_ch_cb_cls) |
816 | void *property_ch_cb_cls) | ||
817 | { | 805 | { |
818 | int c1; | 806 | int c1; |
819 | int i; | 807 | int i; |
820 | preference_peers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | 808 | preference_peers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); |
821 | property_peers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | 809 | property_peers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); |
822 | unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; | 810 | unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; |
823 | |||
824 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) | ||
825 | { | ||
826 | properties[c1].prop_type = c1; | ||
827 | properties[c1].atsi_type = existing_properties[c1]; | ||
828 | properties[c1].min = 0; | ||
829 | properties[c1].max = 0; | ||
830 | } | ||
831 | |||
832 | pref_changed_cb = pref_ch_cb; | ||
833 | pref_changed_cb_cls = pref_ch_cb_cls; | ||
834 | prop_ch_cb = property_ch_cb; | ||
835 | prop_ch_cb_cls = pref_ch_cb_cls; | ||
836 | |||
837 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
838 | defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE; | ||
839 | return; | ||
840 | } | ||
841 | 811 | ||
812 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) | ||
813 | { | ||
814 | properties[c1].prop_type = c1; | ||
815 | properties[c1].atsi_type = existing_properties[c1]; | ||
816 | properties[c1].min = 0; | ||
817 | properties[c1].max = 0; | ||
818 | } | ||
819 | |||
820 | pref_changed_cb = pref_ch_cb; | ||
821 | pref_changed_cb_cls = pref_ch_cb_cls; | ||
822 | prop_ch_cb = property_ch_cb; | ||
823 | prop_ch_cb_cls = pref_ch_cb_cls; | ||
824 | |||
825 | for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) | ||
826 | defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE; | ||
827 | aging_task = GNUNET_SCHEDULER_NO_TASK; | ||
828 | return; | ||
829 | } | ||
842 | 830 | ||
843 | /** | 831 | /** |
844 | * Free a peer | 832 | * Free a peer |
@@ -849,19 +837,17 @@ GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, | |||
849 | * @return GNUNET_OK to continue | 837 | * @return GNUNET_OK to continue |
850 | */ | 838 | */ |
851 | static int | 839 | static int |
852 | free_peer (void *cls, | 840 | free_peer (void *cls, const struct GNUNET_HashCode * key, void *value) |
853 | const struct GNUNET_HashCode * key, | ||
854 | void *value) | ||
855 | { | 841 | { |
856 | struct PeerRelative *rp = value; | 842 | struct PeerRelative *rp = value; |
857 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (preference_peers, key, value)) | 843 | if (GNUNET_YES |
858 | GNUNET_free (rp); | 844 | == GNUNET_CONTAINER_multihashmap_remove (preference_peers, key, value)) |
859 | else | 845 | GNUNET_free(rp); |
860 | GNUNET_break (0); | 846 | else |
861 | return GNUNET_OK; | 847 | GNUNET_break(0); |
848 | return GNUNET_OK; | ||
862 | } | 849 | } |
863 | 850 | ||
864 | |||
865 | /** | 851 | /** |
866 | * Stop the normalization component and free all items | 852 | * Stop the normalization component and free all items |
867 | */ | 853 | */ |
@@ -873,29 +859,31 @@ GAS_normalization_stop () | |||
873 | struct PreferencePeer *p; | 859 | struct PreferencePeer *p; |
874 | struct PreferencePeer *next_p; | 860 | struct PreferencePeer *next_p; |
875 | 861 | ||
862 | if (GNUNET_SCHEDULER_NO_TASK != aging_task) | ||
863 | { | ||
864 | GNUNET_SCHEDULER_cancel (aging_task); | ||
865 | aging_task = GNUNET_SCHEDULER_NO_TASK; | ||
866 | } | ||
867 | |||
876 | next_pc = pc_head; | 868 | next_pc = pc_head; |
877 | while (NULL != (pc = next_pc)) | 869 | while (NULL != (pc = next_pc)) |
878 | { | 870 | { |
879 | next_pc = pc->next; | 871 | next_pc = pc->next; |
880 | GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc); | 872 | GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, pc); |
881 | next_p = pc->p_head; | 873 | next_p = pc->p_head; |
882 | while (NULL != (p = next_p)) | 874 | while (NULL != (p = next_p)) |
883 | { | 875 | { |
884 | next_p = p->next; | 876 | next_p = p->next; |
885 | if (GNUNET_SCHEDULER_NO_TASK != p->aging_task) | 877 | GNUNET_CONTAINER_DLL_remove(pc->p_head, pc->p_tail, p); |
886 | { | 878 | GNUNET_free(p); |
887 | GNUNET_SCHEDULER_cancel(p->aging_task); | 879 | } |
888 | p->aging_task = GNUNET_SCHEDULER_NO_TASK; | 880 | GNUNET_free(pc); |
889 | } | ||
890 | GNUNET_CONTAINER_DLL_remove (pc->p_head, pc->p_tail, p); | ||
891 | GNUNET_free (p); | ||
892 | } | ||
893 | GNUNET_free (pc); | ||
894 | } | 881 | } |
895 | GNUNET_CONTAINER_multihashmap_iterate (preference_peers, &free_peer, NULL); | 882 | |
883 | GNUNET_CONTAINER_multihashmap_iterate (preference_peers, &free_peer, NULL ); | ||
896 | GNUNET_CONTAINER_multihashmap_destroy (preference_peers); | 884 | GNUNET_CONTAINER_multihashmap_destroy (preference_peers); |
897 | GNUNET_CONTAINER_multihashmap_destroy (property_peers); | 885 | GNUNET_CONTAINER_multihashmap_destroy (property_peers); |
898 | return; | 886 | return; |
899 | } | 887 | } |
900 | 888 | ||
901 | /* end of gnunet-service-ats_normalization.c */ | 889 | /* end of gnunet-service-ats_normalization.c */ |