aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-05-06 15:50:20 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-05-06 15:50:20 +0000
commit6e198fdbfa22da72fadcae22b8797af76696b78a (patch)
treec5f5ff123a8670df80a7a286879f7e710aefe843 /src
parent4e1baae59f18ee5d7cd47afe28ced3daaaa5a5ad (diff)
downloadgnunet-6e198fdbfa22da72fadcae22b8797af76696b78a.tar.gz
gnunet-6e198fdbfa22da72fadcae22b8797af76696b78a.zip
- refine preference calculcations to reflect all clients
- refining bandwidth distribution in a network - adding a configurable factor to better respect preferences
Diffstat (limited to 'src')
-rw-r--r--src/ats/ats.conf.in5
-rw-r--r--src/ats/experiments/example.exp13
-rw-r--r--src/ats/experiments/set_preference.exp42
-rw-r--r--src/ats/gnunet-ats-solver-eval.c10
-rw-r--r--src/ats/gnunet-service-ats_normalization.c260
-rw-r--r--src/ats/gnunet-service-ats_normalization.h4
-rw-r--r--src/ats/plugin_ats_mlp.c2
-rw-r--r--src/ats/plugin_ats_proportional.c120
8 files changed, 261 insertions, 195 deletions
diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in
index 50de81bbe..aa938e4c3 100644
--- a/src/ats/ats.conf.in
+++ b/src/ats/ats.conf.in
@@ -32,6 +32,11 @@ BLUETOOTH_QUOTA_IN = 128 KiB
32BLUETOOTH_QUOTA_OUT = 128 KiB 32BLUETOOTH_QUOTA_OUT = 128 KiB
33# ATS options 33# ATS options
34 34
35# Proportional specific settings
36# How proportional to preferences is bandwidth distribution in a network
37# 1: Fair with respect to addresses without preferences
38# > 1: The bigger, the more respect is payed to preferences
39PROP_PROPORTIONALITY_FACTOR = 4
35 40
36# MLP specific settings 41# MLP specific settings
37# MLP defaults 42# MLP defaults
diff --git a/src/ats/experiments/example.exp b/src/ats/experiments/example.exp
index 9e69ab8e2..a490e5ec6 100644
--- a/src/ats/experiments/example.exp
+++ b/src/ats/experiments/example.exp
@@ -1,10 +1,11 @@
1[experiment] 1[experiment]
2 name = test 2name = test
3 max_duration = 15 s 3max_duration = 15 s
4 log_freq = 1000 ms 4log_freq = 1000 ms
5 cfg_file = experiments/gnunet_ats_sim_default.conf 5cfg_file = experiments/gnunet_ats_sim_default.conf
6 6log_output_dir = data/
7 7log_append_time_stamp = no
8
8[episode-0] 9[episode-0]
9# Setup addresses 10# Setup addresses
10 11
diff --git a/src/ats/experiments/set_preference.exp b/src/ats/experiments/set_preference.exp
index dfbd75b18..5e651dc25 100644
--- a/src/ats/experiments/set_preference.exp
+++ b/src/ats/experiments/set_preference.exp
@@ -1,23 +1,24 @@
1# Example setting up two peers 1# Example setting up two peers
2 2
3[experiment] 3[experiment]
4 name = test 4name = test
5 max_duration = 15 s 5max_duration = 15 s
6 log_freq = 1000 ms 6log_freq = 1000 ms
7 cfg_file = experiments/gnunet_ats_sim_default.conf 7log_prefix = set_preference
8 8cfg_file = experiments/gnunet_ats_sim_default.conf
9 9
10[episode-0] 10[episode-0]
11# Setup addresses 11# Setup addresses
12 12
13# operations = address_add, address_del, start_set_property, stop_set_property, 13# operations = address_add, address_del, start_set_property, stop_set_property,
14# start_set_preference, stop_preference, start_request, stop_request 14# start_set_preference, stop_preference, start_request, stop_request
15duration = 5 s 15duration = 2 s
16
16op-0-operation = address_add 17op-0-operation = address_add
17op-0-address-id = 0 18op-0-address-id = 0
18op-0-peer-id = 0 19op-0-peer-id = 0
19op-0-address-session = 0 20op-0-address-session = 0
20op-0-address-network = 0 21op-0-address-network = lan
21op-0-address = 0_0_test 22op-0-address = 0_0_test
22op-0-plugin = test 23op-0-plugin = test
23 24
@@ -25,7 +26,7 @@ op-1-operation = address_add
25op-1-address-id = 1 26op-1-address-id = 1
26op-1-peer-id = 1 27op-1-peer-id = 1
27op-1-address-session = 0 28op-1-address-session = 0
28op-1-address-network = 0 29op-1-address-network = lan
29op-1-address = 1_1_test 30op-1-address = 1_1_test
30op-1-plugin = test 31op-1-plugin = test
31 32
@@ -37,18 +38,18 @@ op-3-peer-id = 1
37 38
38[episode-1] 39[episode-1]
39# Set delay 40# Set delay
40duration = 1 s 41duration = 10 s
41 42
42op-0-operation = start_set_preference 43op-0-operation = start_set_preference
43op-0-address-id = 0 44op-0-address-id = 0
44op-0-peer-id = 0 45op-0-peer-id = 0
45op-0-client-id = 1 46op-0-client-id = 1
46# constant, linear, sinus, random 47# constant, linear, sinus, random
47op-0-gen-type = constant 48op-0-gen-type = linear
48op-0-base-rate= 10000 49op-0-base-rate= 1000
49op-0-max-rate = 10000 50op-0-max-rate = 10000
50op-0-period = 1000 ms 51op-0-period = 10 s
51op-0-frequency = 1000 ms 52op-0-frequency = 500 ms
52# BANDWIDTH, LATENCY 53# BANDWIDTH, LATENCY
53op-0-pref = BANDWIDTH 54op-0-pref = BANDWIDTH
54 55
@@ -58,12 +59,13 @@ op-1-address-id = 1
58op-1-peer-id = 1 59op-1-peer-id = 1
59op-1-client-id = 1 60op-1-client-id = 1
60# constant, linear, sinus, random 61# constant, linear, sinus, random
61op-1-gen-type = linear 62op-1-gen-type = constant
62op-1-base-rate= 10000 63op-1-base-rate= 1000
63op-1-max-rate = 20000 64op-1-max-rate = 1000
64op-1-period = 1000 ms 65op-1-period = 10 s
65op-1-frequency = 100 ms 66op-1-frequency = 500 ms
66op-1-prop = DELAY 67# BANDWIDTH, LATENCY
68op-1-pref = BANDWIDTH
67 69
68[episode-2] 70[episode-2]
69# Shutdown 71# Shutdown
diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c
index c1ab82991..9aef4245b 100644
--- a/src/ats/gnunet-ats-solver-eval.c
+++ b/src/ats/gnunet-ats-solver-eval.c
@@ -2452,7 +2452,7 @@ GNUNET_ATS_solvers_experimentation_load (char *filename)
2452 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment", 2452 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2453 "name", &e->name)) 2453 "name", &e->name))
2454 { 2454 {
2455 fprintf (stderr, "Invalid %s", "name"); 2455 fprintf (stderr, "Invalid %s \n", "name");
2456 free_experiment (e); 2456 free_experiment (e);
2457 return NULL; 2457 return NULL;
2458 } 2458 }
@@ -2462,7 +2462,7 @@ GNUNET_ATS_solvers_experimentation_load (char *filename)
2462 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment", 2462 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
2463 "log_prefix", &e->log_prefix)) 2463 "log_prefix", &e->log_prefix))
2464 { 2464 {
2465 fprintf (stderr, "Invalid %s", "name"); 2465 fprintf (stderr, "Invalid %s \n", "log_prefix");
2466 free_experiment (e); 2466 free_experiment (e);
2467 return NULL; 2467 return NULL;
2468 } 2468 }
@@ -2490,7 +2490,7 @@ GNUNET_ATS_solvers_experimentation_load (char *filename)
2490 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment", 2490 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
2491 "cfg_file", &e->cfg_file)) 2491 "cfg_file", &e->cfg_file))
2492 { 2492 {
2493 fprintf (stderr, "Invalid %s", "cfg_file"); 2493 fprintf (stderr, "Invalid %s \n", "cfg_file");
2494 free_experiment (e); 2494 free_experiment (e);
2495 return NULL; 2495 return NULL;
2496 } 2496 }
@@ -2500,7 +2500,7 @@ GNUNET_ATS_solvers_experimentation_load (char *filename)
2500 e->cfg = GNUNET_CONFIGURATION_create(); 2500 e->cfg = GNUNET_CONFIGURATION_create();
2501 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file)) 2501 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
2502 { 2502 {
2503 fprintf (stderr, "Invalid configuration %s", "cfg_file"); 2503 fprintf (stderr, "Invalid configuration %s \n", "cfg_file");
2504 free_experiment (e); 2504 free_experiment (e);
2505 return NULL; 2505 return NULL;
2506 } 2506 }
@@ -2510,7 +2510,7 @@ GNUNET_ATS_solvers_experimentation_load (char *filename)
2510 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment", 2510 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
2511 "log_freq", &e->log_freq)) 2511 "log_freq", &e->log_freq))
2512 { 2512 {
2513 fprintf (stderr, "Invalid %s", "log_freq"); 2513 fprintf (stderr, "Invalid %s \n", "log_freq");
2514 free_experiment (e); 2514 free_experiment (e);
2515 return NULL; 2515 return NULL;
2516 } 2516 }
diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c
index 3ecbabbf8..fd09a262f 100644
--- a/src/ats/gnunet-service-ats_normalization.c
+++ b/src/ats/gnunet-service-ats_normalization.c
@@ -53,11 +53,16 @@ struct PreferenceClient
53 void *client; 53 void *client;
54 54
55 /** 55 /**
56 * Total preference for this peer 56 * Array of sum of absolute preferences for this client
57 */ 57 */
58 double f_abs_sum[GNUNET_ATS_PreferenceCount]; 58 double f_abs_sum[GNUNET_ATS_PreferenceCount];
59 59
60 /** 60 /**
61 * Array of sum of relative preferences for this client
62 */
63 double f_rel_sum[GNUNET_ATS_PreferenceCount];
64
65 /**
61 * List of peer preferences for this client 66 * List of peer preferences for this client
62 */ 67 */
63 68
@@ -98,15 +103,18 @@ struct PreferencePeer
98 struct GNUNET_PeerIdentity id; 103 struct GNUNET_PeerIdentity id;
99 104
100 /** 105 /**
101 * Absolute preference values 106 * Absolute preference values for all preference types
102 */ 107 */
103 double f_abs[GNUNET_ATS_PreferenceCount]; 108 double f_abs[GNUNET_ATS_PreferenceCount];
104 109
105 /** 110 /**
106 * Relative preference values 111 * Relative preference values for all preference types
107 */ 112 */
108 double f_rel[GNUNET_ATS_PreferenceCount]; 113 double f_rel[GNUNET_ATS_PreferenceCount];
109 114
115 /**
116 * Absolute point of time of next aging process
117 */
110 struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount]; 118 struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount];
111}; 119};
112 120
@@ -127,6 +135,20 @@ struct PeerRelative
127}; 135};
128 136
129/** 137/**
138 * Quality Normalization
139 */
140struct Property
141{
142 uint32_t prop_type;
143 uint32_t atsi_type;
144 uint32_t min;
145 uint32_t max;
146};
147
148struct Property properties[GNUNET_ATS_QualityPropertiesCount];
149
150
151/**
130 * Callback to call on changing preference values 152 * Callback to call on changing preference values
131 */ 153 */
132static GAS_Normalization_preference_changed_cb pref_changed_cb; 154static GAS_Normalization_preference_changed_cb pref_changed_cb;
@@ -184,128 +206,110 @@ static GNUNET_SCHEDULER_TaskIdentifier aging_task;
184 * @param kind the kind 206 * @param kind the kind
185 * @return the new relative preference 207 * @return the new relative preference
186 */ 208 */
187static double 209static void
188update_peers (struct GNUNET_PeerIdentity *id, 210update_relative_values_for_peer (const struct GNUNET_PeerIdentity *id,
189 enum GNUNET_ATS_PreferenceKind kind) 211 enum GNUNET_ATS_PreferenceKind kind, struct PeerRelative *rp)
190{ 212{
191 struct PreferenceClient *c_cur; 213 struct PreferenceClient *c_cur;
192 struct PreferencePeer *p_cur; 214 struct PreferencePeer *p_cur;
193 struct PeerRelative *rp;
194 double f_rel_total; 215 double f_rel_total;
216 double f_rel_sum;
195 double backup; 217 double backup;
196 unsigned int count; 218 unsigned int peer_count;
197 219
220 f_rel_sum = 0.0;
198 f_rel_total = 0.0; 221 f_rel_total = 0.0;
199 count = 0; 222 peer_count = 0;
200 223
201 /* For all clients */ 224 /* For all clients */
202 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) 225 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
203 { 226 {
204 /* Find peer with id */ 227 /* For peer entries with this id */
205 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next) 228 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
206 { 229 {
230 f_rel_sum += p_cur->f_rel[kind];
207 if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity))) 231 if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity)))
208 break; 232 {
209 } 233 peer_count ++;
210 if (NULL != p_cur) 234 f_rel_total += p_cur->f_rel[kind];
211 { 235 }
212 /* Found peer with id */ 236
213 f_rel_total += p_cur->f_rel[kind];
214 count++;
215 } 237 }
216 } 238 }
217 239
218 /* Find a client */ 240 LOG (GNUNET_ERROR_TYPE_DEBUG,
219 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 241 "%u clients have a total relative preference for peer `%s' `%s' of %.3f and for %s in total %.3f\n",
220 "%u clients have a total relative preference for peer `%s''s `%s' of %.3f\n", 242 peer_count, GNUNET_i2s (id),
221 count, GNUNET_i2s (id), GNUNET_ATS_print_preference_type (kind), 243 GNUNET_ATS_print_preference_type (kind),
222 f_rel_total); 244 f_rel_total,
223 if (NULL != (rp = GNUNET_CONTAINER_multipeermap_get (preference_peers, id))) 245 GNUNET_ATS_print_preference_type (kind),
246 f_rel_sum);
247
248 /* Find entry for the peer containing relative values in the hashmap */
249 if (NULL != rp)
224 { 250 {
225 backup = rp->f_rel[kind]; 251 backup = rp->f_rel[kind];
226 if (0 < count) 252 if (f_rel_sum > 0)
227 { 253 rp->f_rel[kind] = f_rel_total / f_rel_sum;
228 rp->f_rel[kind] = f_rel_total / count;
229 }
230 else 254 else
231 { 255 {
256 /* No client had any preferences for this type and any peer */
232 rp->f_rel[kind] = DEFAULT_REL_PREFERENCE; 257 rp->f_rel[kind] = DEFAULT_REL_PREFERENCE;
233 } 258 }
234 } 259 }
235 else
236 {
237 return DEFAULT_REL_PREFERENCE;
238 }
239 260
240 if ((backup != rp->f_rel[kind]) && (NULL != pref_changed_cb)) 261 if ((backup != rp->f_rel[kind]) && (NULL != pref_changed_cb))
241 { 262 {
242 pref_changed_cb (pref_changed_cb_cls, &rp->id, kind, rp->f_rel[kind]); 263 pref_changed_cb (pref_changed_cb_cls, &rp->id, kind, rp->f_rel[kind]);
243 } 264 }
244
245 return rp->f_rel[kind];
246} 265}
247 266
248/** 267/**
249 * Recalculate preference for a specific ATS property 268 * Recalculate preference for a specific ATS property
250 * 269 *
251 * @param c the preference client 270 * @param c the preference client
252 * @param p the peer
253 * @param kind the preference kind 271 * @param kind the preference kind
254 * @return the result 272 * @return the result
255 */ 273 */
256static double 274static void
257recalculate_rel_preferences (struct PreferenceClient *c, 275recalculate_relative_preferences (struct PreferenceClient *c, enum GNUNET_ATS_PreferenceKind kind)
258 struct PreferencePeer *p, enum GNUNET_ATS_PreferenceKind kind)
259{ 276{
260 struct PreferencePeer *p_cur; 277 struct PreferencePeer *p_cur;
261 struct PeerRelative *rp;
262 double backup;
263 double res;
264 double ret;
265 278
266 /* For this client: sum preferences to total preference */ 279 /* For this client: sum of absolute preference values for this preference */
267 c->f_abs_sum[kind] = 0; 280 c->f_abs_sum[kind] = 0.0;
281 /* For this client: sum of relative preference values for this preference
282 *
283 * Note: this value should also be 1.0, but:
284 * if no preferences exist due to aging, this value can be 0.0
285 * and the client can be removed */
286 c->f_rel_sum[kind] = 0.0;
287
268 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) 288 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
269 c->f_abs_sum[kind] += p_cur->f_abs[kind]; 289 c->f_abs_sum[kind] += p_cur->f_abs[kind];
270 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 290 LOG (GNUNET_ERROR_TYPE_DEBUG,
271 "Client %p has total preference for %s of %.3f\n", c->client, 291 "Client %p has sum of total preferences for %s of %.3f\n",
272 GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]); 292 c->client, GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]);
273 293
274 ret = DEFAULT_REL_PREFERENCE;
275 /* For all peers: calculate relative preference */ 294 /* For all peers: calculate relative preference */
276 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next) 295 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
277 { 296 {
278 /* Calculate relative preference for specific kind */ 297 /* Calculate relative preference for specific kind */
279 backup = p_cur->f_rel[kind];
280 if (DEFAULT_ABS_PREFERENCE == c->f_abs_sum[kind])
281 /* No peer has a preference for this property,
282 * so set default preference */
283 p_cur->f_rel[kind] = DEFAULT_REL_PREFERENCE;
284 else
285 p_cur->f_rel[kind] = (c->f_abs_sum[kind] + p_cur->f_abs[kind])
286 / c->f_abs_sum[kind];
287 298
288 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 299 /* Every application has a preference for each peer between
289 "Client %p: peer `%s' has relative preference for %s of %.3f\n", 300 * [0 .. 1] in relative values
290 c->client, GNUNET_i2s (&p_cur->id), 301 * and [0 .. inf] in absolute values */
291 GNUNET_ATS_print_preference_type (kind), p_cur->f_rel[kind]); 302 p_cur->f_rel[kind] = p_cur->f_abs[kind] / c->f_abs_sum[kind];
303 c->f_rel_sum[kind] += p_cur->f_rel[kind];
292 304
293 if (p_cur->f_rel[kind] != backup) 305 LOG (GNUNET_ERROR_TYPE_DEBUG,
294 { 306 "Client %p has relative preference for %s for peer `%s' of %.3f\n",
295 /* Value changed, recalculate */ 307 c->client,
296 res = update_peers (&p_cur->id, kind); 308 GNUNET_ATS_print_preference_type (kind),
297 if (0 == memcmp (&p->id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity))) 309 GNUNET_i2s (&p_cur->id),
298 ret = res; 310 p_cur->f_rel[kind]);
299 }
300 else
301 {
302 /* Value did not chang, return old value*/
303 GNUNET_assert(
304 NULL != (rp = GNUNET_CONTAINER_multipeermap_get (preference_peers, &p->id)));
305 ret = rp->f_rel[kind];
306 }
307 } 311 }
308 return ret; 312
309} 313}
310 314
311/** 315/**
@@ -316,8 +320,8 @@ recalculate_rel_preferences (struct PreferenceClient *c,
316 * @param score_abs the absolute value 320 * @param score_abs the absolute value
317 * @return the new relative preference value 321 * @return the new relative preference value
318 */ 322 */
319static double 323static void
320update_preference (struct PreferenceClient *c, struct PreferencePeer *p, 324update_abs_preference (struct PreferenceClient *c, struct PreferencePeer *p,
321 enum GNUNET_ATS_PreferenceKind kind, float score_abs) 325 enum GNUNET_ATS_PreferenceKind kind, float score_abs)
322{ 326{
323 double score = score_abs; 327 double score = score_abs;
@@ -327,7 +331,8 @@ update_preference (struct PreferenceClient *c, struct PreferencePeer *p,
327 { 331 {
328 case GNUNET_ATS_PREFERENCE_BANDWIDTH: 332 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
329 case GNUNET_ATS_PREFERENCE_LATENCY: 333 case GNUNET_ATS_PREFERENCE_LATENCY:
330 p->f_abs[kind] = (p->f_abs[kind] + score) / 2; 334 p->f_abs[kind] = score;
335 /* p->f_abs[kind] = (p->f_abs[kind] + score) / 2; */
331 p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), 336 p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
332 PREF_AGING_INTERVAL); 337 PREF_AGING_INTERVAL);
333 break; 338 break;
@@ -336,7 +341,32 @@ update_preference (struct PreferenceClient *c, struct PreferencePeer *p,
336 default: 341 default:
337 break; 342 break;
338 } 343 }
339 return recalculate_rel_preferences (c, p, kind); 344}
345
346static int update_iterator (void *cls,
347 const struct GNUNET_PeerIdentity *key,
348 void *value)
349{
350 enum GNUNET_ATS_PreferenceKind *kind = cls;
351 update_relative_values_for_peer (key, (*kind), (struct PeerRelative *) value);
352 return GNUNET_OK;
353}
354
355static void
356run_preference_update (struct PreferenceClient *c_cur,
357 struct PreferencePeer *p_cur,enum GNUNET_ATS_PreferenceKind kind,
358 float score_abs)
359{
360 double old_value;
361
362 /* Update relative value */
363 old_value = p_cur->f_rel[kind];
364 recalculate_relative_preferences (c_cur, kind);
365 if (p_cur->f_rel[kind] == old_value)
366 return;
367
368 /* Relative preference value changed, recalculate for all peers */
369 GNUNET_CONTAINER_multipeermap_iterate (preference_peers, &update_iterator, &kind);
340} 370}
341 371
342/** 372/**
@@ -373,15 +403,19 @@ preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
373 backup = p->f_abs[i]; 403 backup = p->f_abs[i];
374 if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE) 404 if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE)
375 p->f_abs[i] *= PREF_AGING_FACTOR; 405 p->f_abs[i] *= PREF_AGING_FACTOR;
406
376 if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON) 407 if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON)
377 p->f_abs[i] = DEFAULT_ABS_PREFERENCE; 408 p->f_abs[i] = DEFAULT_ABS_PREFERENCE;
378 if ((p->f_abs[i] != DEFAULT_ABS_PREFERENCE) 409
379 && (backup != p->f_abs[i])) 410 if ( (p->f_abs[i] != DEFAULT_ABS_PREFERENCE) &&
411 (backup != p->f_abs[i]) )
380 { 412 {
381 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 413 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
382 "Aged preference for peer `%s' from %.3f to %.3f\n", 414 "Aged preference for peer `%s' from %.3f to %.3f\n",
383 GNUNET_i2s (&p->id), backup, p->f_abs[i]); 415 GNUNET_i2s (&p->id), backup, p->f_abs[i]);
384 recalculate_rel_preferences (p->client, p, i); 416
417 run_preference_update(cur_client, p, i, p->f_abs[i]);
418
385 p->next_aging[i] = GNUNET_TIME_absolute_add ( 419 p->next_aging[i] = GNUNET_TIME_absolute_add (
386 GNUNET_TIME_absolute_get (), PREF_AGING_INTERVAL); 420 GNUNET_TIME_absolute_get (), PREF_AGING_INTERVAL);
387 values_to_update++; 421 values_to_update++;
@@ -408,27 +442,31 @@ preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
408/** 442/**
409 * Normalize an updated preference value 443 * Normalize an updated preference value
410 * 444 *
411 * @param src the client with this preference 445 * @param client the client with this preference
412 * @param peer the peer to change the preference for 446 * @param peer the peer to change the preference for
413 * @param kind the kind to change the preference 447 * @param kind the kind to change the preference
414 * @param score_abs the normalized score 448 * @param score_abs the normalized score
415 */ 449 */
416void 450void
417GAS_normalization_normalize_preference (void *src, 451GAS_normalization_normalize_preference (void *client,
418 const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, 452 const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind,
419 float score_abs) 453 float score_abs)
420{ 454{
421 struct PreferenceClient *c_cur; 455 struct PreferenceClient *c_cur;
422 struct PreferencePeer *p_cur; 456 struct PreferencePeer *p_cur;
423 struct PeerRelative *r_cur; 457 struct PeerRelative *r_cur;
458 double old_value;
424 int i; 459 int i;
425 460
426 GNUNET_assert(NULL != src); 461 GNUNET_assert(NULL != client);
427 GNUNET_assert(NULL != peer); 462 GNUNET_assert(NULL != peer);
428 463
429 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 464 LOG (GNUNET_ERROR_TYPE_DEBUG,
430 "Client %p changes preference for peer `%s' for `%s' to %.2f\n", src, 465 "Client %p changes preference for peer `%s' for `%s' to %.2f\n",
431 GNUNET_i2s (peer), GNUNET_ATS_print_preference_type (kind), score_abs); 466 client,
467 GNUNET_i2s (peer),
468 GNUNET_ATS_print_preference_type (kind),
469 score_abs);
432 470
433 if (kind >= GNUNET_ATS_PreferenceCount) 471 if (kind >= GNUNET_ATS_PreferenceCount)
434 { 472 {
@@ -439,16 +477,22 @@ GAS_normalization_normalize_preference (void *src,
439 /* Find preference client */ 477 /* Find preference client */
440 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) 478 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
441 { 479 {
442 if (src == c_cur->client) 480 if (client == c_cur->client)
443 break; 481 break;
444 } 482 }
445 /* Not found: create new preference client */ 483 /* Not found: create new preference client */
446 if (NULL == c_cur) 484 if (NULL == c_cur)
447 { 485 {
448 c_cur = GNUNET_new (struct PreferenceClient); 486 c_cur = GNUNET_new (struct PreferenceClient);
449 c_cur->client = src; 487 c_cur->client = client;
488 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
489 {
490 c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE;
491 c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE;
492 }
493
450 GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur); 494 GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur);
451 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Adding new client %p \n", c_cur); 495 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new client %p \n", c_cur);
452 } 496 }
453 497
454 /* Find entry for peer */ 498 /* Find entry for peer */
@@ -464,32 +508,42 @@ GAS_normalization_normalize_preference (void *src,
464 p_cur->id = (*peer); 508 p_cur->id = (*peer);
465 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 509 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
466 { 510 {
467 /* Default value per peer absolut preference for a quality: 511 /* Default value per peer absolute preference for a preference: 0 */
468 * No value set, so absolute preference 0 */
469 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE; 512 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE;
470 /* Default value per peer relative preference for a quality: 1.0 */ 513 /* Default value per peer relative preference for a quality: 1.0 */
471 p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; 514 p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
472 p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS; 515 p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS;
473 } 516 }
517 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer %p for client %p \n",
518 p_cur, c_cur);
474 GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur); 519 GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur);
475 } 520 }
476 521
522 /* Create struct for peer */
477 if (NULL == GNUNET_CONTAINER_multipeermap_get (preference_peers, peer)) 523 if (NULL == GNUNET_CONTAINER_multipeermap_get (preference_peers, peer))
478 { 524 {
479 r_cur = GNUNET_new (struct PeerRelative); 525 r_cur = GNUNET_new (struct PeerRelative);
480 r_cur->id = (*peer); 526 r_cur->id = (*peer);
481 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++) 527 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
482 r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE; 528 r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
483 GNUNET_assert (GNUNET_OK == 529 GNUNET_assert(
484 GNUNET_CONTAINER_multipeermap_put (preference_peers, &r_cur->id, r_cur, 530 GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (preference_peers,
485 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 531 &r_cur->id, r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
486 } 532 }
487 533
534 /* Update absolute value */
535 old_value = p_cur->f_abs[kind];
536 update_abs_preference (c_cur, p_cur, kind, score_abs);
537 if (p_cur->f_abs[kind] == old_value)
538 return;
539
540 run_preference_update (c_cur, p_cur, kind, score_abs);
541
542 /* Start aging task */
488 if (GNUNET_SCHEDULER_NO_TASK == aging_task) 543 if (GNUNET_SCHEDULER_NO_TASK == aging_task)
489 aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, 544 aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
490 &preference_aging, NULL ); 545 &preference_aging, NULL );
491 546
492 update_preference (c_cur, p_cur, kind, score_abs);
493} 547}
494 548
495/** 549/**
@@ -576,20 +630,6 @@ GAS_normalization_get_properties (struct ATS_Address *address)
576 return norm_values; 630 return norm_values;
577} 631}
578 632
579
580/**
581 * Quality Normalization
582 */
583struct Property
584{
585 uint32_t prop_type;
586 uint32_t atsi_type;
587 uint32_t min;
588 uint32_t max;
589};
590
591struct Property properties[GNUNET_ATS_QualityPropertiesCount];
592
593/** 633/**
594 * Normalize a specific ATS type with the values in queue 634 * Normalize a specific ATS type with the values in queue
595 * @param address the address 635 * @param address the address
diff --git a/src/ats/gnunet-service-ats_normalization.h b/src/ats/gnunet-service-ats_normalization.h
index 0a4625ab4..a82d66f46 100644
--- a/src/ats/gnunet-service-ats_normalization.h
+++ b/src/ats/gnunet-service-ats_normalization.h
@@ -29,9 +29,9 @@
29 29
30#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 30#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
31#define PREF_AGING_FACTOR 0.95 31#define PREF_AGING_FACTOR 0.95
32#define PREF_EPSILON 0.1 32#define PREF_EPSILON 0.01
33 33
34#define DEFAULT_REL_PREFERENCE 1.0 34#define DEFAULT_REL_PREFERENCE 0.0
35#define DEFAULT_ABS_PREFERENCE 0.0 35#define DEFAULT_ABS_PREFERENCE 0.0
36 36
37#define DEFAULT_REL_QUALITY 1.0 37#define DEFAULT_REL_QUALITY 1.0
diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c
index 1ceb294ca..1c93915cf 100644
--- a/src/ats/plugin_ats_mlp.c
+++ b/src/ats/plugin_ats_mlp.c
@@ -1681,7 +1681,7 @@ get_peer_pref_value (struct GAS_MLP_Handle *mlp, const struct GNUNET_PeerIdentit
1681 int c; 1681 int c;
1682 preferences = mlp->get_preferences (mlp->get_preferences_cls, peer); 1682 preferences = mlp->get_preferences (mlp->get_preferences_cls, peer);
1683 1683
1684 res = 0.0; 1684 res = 1.0;
1685 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++) 1685 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++)
1686 { 1686 {
1687 if (c != GNUNET_ATS_PREFERENCE_END) 1687 if (c != GNUNET_ATS_PREFERENCE_END)
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 5798fd82e..7badd3491 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -203,12 +203,7 @@
203 * 203 *
204 */ 204 */
205 205
206#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) 206#define PROPORTIONALITY_FACTOR 2.0
207#define PREF_AGING_FACTOR 0.95
208
209#define DEFAULT_REL_PREFERENCE 1.0
210#define DEFAULT_ABS_PREFERENCE 0.0
211#define MIN_UPDATE_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
212 207
213/** 208/**
214 * A handle for the proportional solver 209 * A handle for the proportional solver
@@ -292,6 +287,10 @@ struct GAS_PROPORTIONAL_Handle
292 */ 287 */
293 unsigned int network_count; 288 unsigned int network_count;
294 289
290 /**
291 * Proportionality factor
292 */
293 double prop_factor;
295}; 294};
296 295
297/** 296/**
@@ -400,6 +399,7 @@ libgnunet_plugin_ats_proportional_init (void *cls)
400 struct GAS_PROPORTIONAL_Handle *s; 399 struct GAS_PROPORTIONAL_Handle *s;
401 struct Network * cur; 400 struct Network * cur;
402 char * net_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString; 401 char * net_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
402 unsigned long long prop_factor;
403 int c; 403 int c;
404 404
405 GNUNET_assert (NULL != env); 405 GNUNET_assert (NULL != env);
@@ -440,6 +440,23 @@ libgnunet_plugin_ats_proportional_init (void *cls)
440 s->addresses = env->addresses; 440 s->addresses = env->addresses;
441 s->requests = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); 441 s->requests = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
442 442
443 if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_number(s->env->cfg, "ats",
444 "PROP_PROPORTIONALITY_FACTOR", &prop_factor))
445 {
446 if (prop_factor > 1)
447 s->prop_factor = (double) prop_factor;
448 else
449 {
450 GNUNET_break (0);
451 s->prop_factor = PROPORTIONALITY_FACTOR;
452 }
453 }
454 else
455 s->prop_factor = PROPORTIONALITY_FACTOR;
456 LOG (GNUNET_ERROR_TYPE_ERROR, "Using proportionality factor %.0f\n",
457 s->prop_factor);
458
459
443 for (c = 0; c < env->network_count; c++) 460 for (c = 0; c < env->network_count; c++)
444 { 461 {
445 cur = &s->network_entries[c]; 462 cur = &s->network_entries[c];
@@ -557,18 +574,21 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
557 struct Network *net, struct ATS_Address *address_except) 574 struct Network *net, struct ATS_Address *address_except)
558{ 575{
559 struct AddressSolverInformation *asi; 576 struct AddressSolverInformation *asi;
560 struct AddressWrapper *cur; 577 struct AddressWrapper *cur_address;
561 578
562 unsigned long long remaining_quota_in = 0; 579 unsigned long long remaining_quota_in = 0;
563 unsigned long long quota_out_used = 0; 580 unsigned long long quota_out_used = 0;
564 unsigned long long remaining_quota_out = 0; 581 unsigned long long remaining_quota_out = 0;
565 unsigned long long quota_in_used = 0; 582 unsigned long long quota_in_used = 0;
583 int count_addresses;
566 uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); 584 uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
567 double peer_prefs; 585 double relative_peer_prefence;
568 double total_prefs; /* Important: has to be double not float due to precision */ 586 double sum_relative_peer_prefences; /* Important: has to be double not float due to precision */
569 double cur_pref; /* Important: has to be double not float due to precision */ 587 double cur_pref; /* Important: has to be double not float due to precision */
570 const double *t = NULL; /* Important: has to be double not float due to precision */ 588 double peer_weight;
571 int c; 589 double total_weight;
590 const double *peer_relative_prefs = NULL; /* Important: has to be double not float due to precision */
591
572 unsigned long long assigned_quota_in = 0; 592 unsigned long long assigned_quota_in = 0;
573 unsigned long long assigned_quota_out = 0; 593 unsigned long long assigned_quota_out = 0;
574 594
@@ -603,49 +623,49 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
603 remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw); 623 remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
604 LOG(GNUNET_ERROR_TYPE_DEBUG, "Remaining bandwidth : (in/out): %llu/%llu \n", 624 LOG(GNUNET_ERROR_TYPE_DEBUG, "Remaining bandwidth : (in/out): %llu/%llu \n",
605 remaining_quota_in, remaining_quota_out); 625 remaining_quota_in, remaining_quota_out);
606 total_prefs = 0.0; 626 sum_relative_peer_prefences = 0.0;
607 for (cur = net->head; NULL != cur; cur = cur->next)
608 {
609 if (GNUNET_YES == cur->addr->active)
610 {
611 GNUNET_assert(
612 NULL != (t = s->get_preferences (s->get_preferences_cls, &cur->addr->peer)));
613 627
614 peer_prefs = 0.0; 628 /* Calculate sum of relative preference for active addresses in this network */
615 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++) 629 count_addresses = 0;
616 { 630 for (cur_address = net->head; NULL != cur_address; cur_address = cur_address->next)
617 if (c != GNUNET_ATS_PREFERENCE_END) 631 {
618 { 632 if (GNUNET_YES != cur_address->addr->active)
619 //fprintf (stderr, "VALUE[%u] %s %.3f \n", c, GNUNET_i2s (&cur->addr->peer), t[c]); 633 continue;
620 peer_prefs += t[c]; 634
621 } 635 GNUNET_assert( NULL != (peer_relative_prefs = s->get_preferences (s->get_preferences_cls,
622 } 636 &cur_address->addr->peer)));
623 total_prefs += (peer_prefs / (GNUNET_ATS_PreferenceCount - 1)); 637 relative_peer_prefence = 0.0;
624 } 638 relative_peer_prefence += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
639 sum_relative_peer_prefences += relative_peer_prefence;
640 count_addresses ++;
625 } 641 }
626 for (cur = net->head; NULL != cur; cur = cur->next) 642
643 GNUNET_assert (count_addresses == net->active_addresses);
644
645 LOG (GNUNET_ERROR_TYPE_INFO,
646 "Total relative preference %.3f for %u addresses in network %s\n",
647 sum_relative_peer_prefences, net->active_addresses, net->desc);
648
649 for (cur_address = net->head; NULL != cur_address; cur_address = cur_address->next)
627 { 650 {
628 if (GNUNET_YES == cur->addr->active) 651 if (GNUNET_YES == cur_address->addr->active)
629 { 652 {
630 cur_pref = 0.0; 653 GNUNET_assert( NULL != (peer_relative_prefs =
631 GNUNET_assert( 654 s->get_preferences (s->get_preferences_cls, &cur_address->addr->peer)));
632 NULL != (t = s->get_preferences (s->get_preferences_cls, &cur->addr->peer)));
633 655
634 for (c = 0; c < GNUNET_ATS_PreferenceCount; c++) 656 cur_pref = peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
635 { 657 total_weight = net->active_addresses +
636 if (c != GNUNET_ATS_PREFERENCE_END) 658 s->prop_factor * sum_relative_peer_prefences;
637 cur_pref += t[c]; 659 peer_weight = (1.0 + (s->prop_factor * cur_pref));
638 }
639 cur_pref /= 2;
640 660
641 assigned_quota_in = min_bw 661 assigned_quota_in = min_bw
642 + ((cur_pref / total_prefs) * remaining_quota_in); 662 + ((peer_weight / total_weight) * remaining_quota_in);
643 assigned_quota_out = min_bw 663 assigned_quota_out = min_bw
644 + ((cur_pref / total_prefs) * remaining_quota_out); 664 + ((peer_weight / total_weight) * remaining_quota_out);
645 665
646 LOG (GNUNET_ERROR_TYPE_INFO, 666 LOG (GNUNET_ERROR_TYPE_INFO,
647 "New quota for peer `%s' with preference (cur/total) %.3f/%.3f (in/out): %llu / %llu\n", 667 "New quota for peer `%s' with weight (cur/total) %.3f/%.3f (in/out): %llu / %llu\n",
648 GNUNET_i2s (&cur->addr->peer), cur_pref, total_prefs, 668 GNUNET_i2s (&cur_address->addr->peer), peer_weight, total_weight,
649 assigned_quota_in, assigned_quota_out); 669 assigned_quota_in, assigned_quota_out);
650 } 670 }
651 else 671 else
@@ -663,7 +683,7 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
663 assigned_quota_out = UINT32_MAX; 683 assigned_quota_out = UINT32_MAX;
664 684
665 /* Compare to current bandwidth assigned */ 685 /* Compare to current bandwidth assigned */
666 asi = cur->addr->solver_information; 686 asi = cur_address->addr->solver_information;
667 asi->calculated_quota_in_NBO = htonl (assigned_quota_in); 687 asi->calculated_quota_in_NBO = htonl (assigned_quota_in);
668 asi->calculated_quota_out_NBO = htonl (assigned_quota_out); 688 asi->calculated_quota_out_NBO = htonl (assigned_quota_out);
669 } 689 }
@@ -1140,13 +1160,11 @@ GAS_proportional_get_preferred_address (void *solver,
1140 GNUNET_assert(peer != NULL); 1160 GNUNET_assert(peer != NULL);
1141 1161
1142 /* Add to list of pending requests */ 1162 /* Add to list of pending requests */
1143 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, 1163 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, peer))
1144 peer))
1145 { 1164 {
1146 GNUNET_assert (GNUNET_OK == 1165 GNUNET_assert(
1147 GNUNET_CONTAINER_multipeermap_put (s->requests, 1166 GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (s->requests, peer, NULL,
1148 peer, NULL, 1167 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1149 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1150 } 1168 }
1151 1169
1152 /* Get address with: stick to current address, lower distance, lower latency */ 1170 /* Get address with: stick to current address, lower distance, lower latency */