diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-06-17 11:47:27 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-06-17 11:47:27 +0000 |
commit | 1320b67d1d14c614ec575735e9862560f1649388 (patch) | |
tree | 82de05fc7bad7a0b99906fc7abb59c6f4e6caaa9 /src/ats/gnunet-service-ats_normalization.c | |
parent | d52bea90a2d3be57e79bb60456b6614a0089aa98 (diff) | |
download | gnunet-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.c | 185 |
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 | |||
120 | struct PreferenceClient *pc_head; | 124 | struct PreferenceClient *pc_head; |
121 | struct PreferenceClient *pc_tail; | 125 | struct PreferenceClient *pc_tail; |
122 | 126 | ||
127 | |||
128 | |||
129 | static double | ||
130 | update_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 | */ | ||
171 | static double | ||
172 | recalculate_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 | |||
227 | static double | ||
228 | update_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 | |||
123 | static void | 249 | static void |
124 | preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 250 | preference_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 | ||