diff options
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses_mlp.c')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.c | 167 |
1 files changed, 127 insertions, 40 deletions
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c index 41e96649d..7277355ac 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.c +++ b/src/ats/gnunet-service-ats_addresses_mlp.c | |||
@@ -33,17 +33,78 @@ | |||
33 | #include "glpk.h" | 33 | #include "glpk.h" |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* | 36 | |
37 | * The MLP handle | 37 | /** |
38 | * Create the MLP problem | ||
39 | * | ||
40 | * @param mlp the MLP handle | ||
41 | * @return GNUNET_OK or GNUNET_SYSERR | ||
38 | */ | 42 | */ |
39 | static struct GAS_MLP_Handle *GAS_mlp; | ||
40 | 43 | ||
44 | static int | ||
45 | mlp_create_problem (struct GAS_MLP_Handle *mlp) | ||
46 | { | ||
47 | int res = GNUNET_OK; | ||
48 | int col; | ||
49 | |||
50 | /* Set a problem name */ | ||
51 | glp_set_prob_name (mlp->prob, "gnunet ats bandwidth distribution"); | ||
52 | |||
53 | /* Set optimization direction to maximize */ | ||
54 | glp_set_obj_dir (mlp->prob, GLP_MAX); | ||
55 | |||
56 | /* Adding invariant columns */ | ||
57 | |||
58 | /* Diversity d column */ | ||
59 | |||
60 | col = glp_add_cols (mlp->prob, 1); | ||
61 | mlp->c_d = col; | ||
62 | /* Column name */ | ||
63 | glp_set_col_name (mlp->prob, col, "d"); | ||
64 | /* Column coffiecient */ | ||
65 | glp_set_obj_coef (mlp->prob, col, mlp->co_D); | ||
66 | /* Column lower bound = 0.0 */ | ||
67 | glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); | ||
68 | |||
69 | /* Utilization u column */ | ||
70 | |||
71 | col = glp_add_cols (mlp->prob, 1); | ||
72 | mlp->c_u = col; | ||
73 | /* Column name */ | ||
74 | glp_set_col_name (mlp->prob, col, "u"); | ||
75 | /* Column coffiecient */ | ||
76 | glp_set_obj_coef (mlp->prob, col, mlp->co_U); | ||
77 | /* Column lower bound = 0.0 */ | ||
78 | glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); | ||
79 | |||
80 | /* Relitivity r column */ | ||
81 | |||
82 | col = glp_add_cols (mlp->prob, 1); | ||
83 | mlp->c_r = col; | ||
84 | /* Column name */ | ||
85 | glp_set_col_name (mlp->prob, col, "r"); | ||
86 | /* Column coffiecient */ | ||
87 | glp_set_obj_coef (mlp->prob, col, mlp->co_R); | ||
88 | /* Column lower bound = 0.0 */ | ||
89 | glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0); | ||
90 | |||
91 | /* Quality metric columns */ | ||
92 | col = glp_add_cols(mlp->prob, mlp->m); | ||
93 | mlp->c_q_start = col; | ||
94 | mlp->c_q_end = col + mlp->m; | ||
95 | |||
96 | mlp->co_Q = GNUNET_malloc (mlp->m * sizeof (double)); | ||
97 | |||
98 | return res; | ||
99 | } | ||
41 | 100 | ||
42 | /** | 101 | /** |
43 | * Solves the LP problem | 102 | * Solves the LP problem |
103 | * | ||
104 | * @param mlp the MLP Handle | ||
44 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | 105 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure |
45 | */ | 106 | */ |
46 | int | 107 | static int |
47 | mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp) | 108 | mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp) |
48 | { | 109 | { |
49 | int res; | 110 | int res; |
@@ -132,6 +193,8 @@ lp_solv: | |||
132 | 193 | ||
133 | /** | 194 | /** |
134 | * Solves the MLP problem | 195 | * Solves the MLP problem |
196 | * | ||
197 | * @param mlp the MLP Handle | ||
135 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | 198 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure |
136 | */ | 199 | */ |
137 | int | 200 | int |
@@ -201,6 +264,8 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) | |||
201 | 264 | ||
202 | /** | 265 | /** |
203 | * Solves the MLP problem | 266 | * Solves the MLP problem |
267 | * | ||
268 | * @param mlp the MLP Handle | ||
204 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | 269 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure |
205 | */ | 270 | */ |
206 | int | 271 | int |
@@ -220,47 +285,50 @@ mlp_solve_problem (struct GAS_MLP_Handle *mlp) | |||
220 | * @param stats the GNUNET_STATISTICS handle | 285 | * @param stats the GNUNET_STATISTICS handle |
221 | * @param max_duration maximum numbers of iterations for the LP/MLP Solver | 286 | * @param max_duration maximum numbers of iterations for the LP/MLP Solver |
222 | * @param max_iterations maximum time limit for the LP/MLP Solver | 287 | * @param max_iterations maximum time limit for the LP/MLP Solver |
223 | * @return GNUNET_OK on success, GNUNET_SYSERR on fail | 288 | * @return struct GAS_MLP_Handle * on success, NULL on fail |
224 | */ | 289 | */ |
225 | int | 290 | struct GAS_MLP_Handle * |
226 | GAS_mlp_init (const struct GNUNET_STATISTICS_Handle *stats, | 291 | GAS_mlp_init (const struct GNUNET_STATISTICS_Handle *stats, |
227 | struct GNUNET_TIME_Relative max_duration, | 292 | struct GNUNET_TIME_Relative max_duration, |
228 | unsigned int max_iterations) | 293 | unsigned int max_iterations) |
229 | { | 294 | { |
230 | GAS_mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle)); | 295 | struct GAS_MLP_Handle * mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle)); |
231 | 296 | ||
232 | /* Init GLPK environment */ | 297 | /* Init GLPK environment */ |
233 | GNUNET_assert (glp_init_env() == 0); | 298 | GNUNET_assert (glp_init_env() == 0); |
234 | 299 | ||
235 | /* Create initial MLP problem */ | 300 | /* Create initial MLP problem */ |
236 | GAS_mlp->prob = glp_create_prob(); | 301 | mlp->prob = glp_create_prob(); |
237 | GNUNET_assert (GAS_mlp->prob != NULL); | 302 | GNUNET_assert (mlp->prob != NULL); |
238 | 303 | ||
239 | GAS_mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats; | 304 | mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats; |
240 | GAS_mlp->max_iterations = max_iterations; | 305 | mlp->max_iterations = max_iterations; |
241 | GAS_mlp->max_exec_duration = max_duration; | 306 | mlp->max_exec_duration = max_duration; |
242 | 307 | ||
243 | /* Init LP solving parameters */ | 308 | /* Init LP solving parameters */ |
244 | glp_init_smcp(&GAS_mlp->control_param_lp); | 309 | glp_init_smcp(&mlp->control_param_lp); |
245 | #if DEBUG_MLP | 310 | #if DEBUG_MLP |
246 | GAS_mlp->control_param_lp.msg_lev = GLP_MSG_ALL; | 311 | mlp->control_param_lp.msg_lev = GLP_MSG_ALL; |
247 | #else | 312 | #else |
248 | GAS_mlp->control_param_lp.msg_lev = GLP_MSG_OFF; | 313 | mlp->control_param_lp.msg_lev = GLP_MSG_OFF; |
249 | #endif | 314 | #endif |
250 | GAS_mlp->control_param_lp.it_lim = max_iterations; | 315 | mlp->control_param_lp.it_lim = max_iterations; |
251 | GAS_mlp->control_param_lp.tm_lim = max_duration.rel_value; | 316 | mlp->control_param_lp.tm_lim = max_duration.rel_value; |
252 | 317 | ||
253 | /* Init MLP solving parameters */ | 318 | /* Init MLP solving parameters */ |
254 | glp_init_iocp(&GAS_mlp->control_param_mlp); | 319 | glp_init_iocp(&mlp->control_param_mlp); |
255 | #if DEBUG_MLP | 320 | #if DEBUG_MLP |
256 | GAS_mlp->control_param_mlp.msg_lev = GLP_MSG_ALL; | 321 | mlp->control_param_mlp.msg_lev = GLP_MSG_ALL; |
257 | #else | 322 | #else |
258 | GAS_mlp->control_param_mlp.msg_lev = GLP_MSG_OFF; | 323 | mlp->control_param_mlp.msg_lev = GLP_MSG_OFF; |
259 | #endif | 324 | #endif |
260 | GAS_mlp->control_param_mlp.tm_lim = max_duration.rel_value; | 325 | mlp->control_param_mlp.tm_lim = max_duration.rel_value; |
261 | 326 | ||
262 | GAS_mlp->last_execution = GNUNET_TIME_absolute_get_forever(); | 327 | mlp->last_execution = GNUNET_TIME_absolute_get_forever(); |
263 | return GNUNET_OK; | 328 | |
329 | |||
330 | mlp_create_problem (mlp); | ||
331 | return mlp; | ||
264 | } | 332 | } |
265 | 333 | ||
266 | /** | 334 | /** |
@@ -271,19 +339,28 @@ GAS_mlp_init (const struct GNUNET_STATISTICS_Handle *stats, | |||
271 | * | 339 | * |
272 | * Otherwise the addresses' values can be updated and the existing base can | 340 | * Otherwise the addresses' values can be updated and the existing base can |
273 | * be reused | 341 | * be reused |
342 | * | ||
343 | * @param mlp the MLP Handle | ||
344 | * @param addresses the address hashmap | ||
345 | * @param address the address to update | ||
274 | */ | 346 | */ |
275 | void | 347 | void |
276 | GAS_mlp_address_update (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) | 348 | GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) |
277 | { | 349 | { |
278 | int new; | 350 | int new; |
279 | 351 | ||
280 | GNUNET_STATISTICS_update (GAS_mlp->stats,"# LP address updates", 1, GNUNET_NO); | 352 | GNUNET_STATISTICS_update (mlp->stats,"# LP address updates", 1, GNUNET_NO); |
281 | 353 | ||
282 | /* We update a new address */ | 354 | /* We add a new address */ |
283 | if (address->mlp_information == NULL) | 355 | if (address->mlp_information == NULL) |
284 | { | 356 | { |
285 | new = GNUNET_YES; | 357 | new = GNUNET_YES; |
286 | address->mlp_information = GNUNET_malloc (sizeof (struct MLP_information)); | 358 | address->mlp_information = GNUNET_malloc (sizeof (struct MLP_information)); |
359 | |||
360 | /* Add bandwidth columns */ | ||
361 | |||
362 | |||
363 | /* Add */ | ||
287 | } | 364 | } |
288 | else | 365 | else |
289 | new = GNUNET_NO; | 366 | new = GNUNET_NO; |
@@ -292,19 +369,23 @@ GAS_mlp_address_update (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct | |||
292 | 369 | ||
293 | /* Recalculate */ | 370 | /* Recalculate */ |
294 | if (new == GNUNET_YES) | 371 | if (new == GNUNET_YES) |
295 | GAS_mlp->presolver_required = GNUNET_YES; | 372 | mlp->presolver_required = GNUNET_YES; |
296 | mlp_solve_problem (GAS_mlp); | 373 | mlp_solve_problem (mlp); |
297 | } | 374 | } |
298 | 375 | ||
299 | /** | 376 | /** |
300 | * Deletes a single address in the MLP problem | 377 | * Deletes a single address in the MLP problem |
301 | * | 378 | * |
302 | * The MLP problem has to be recreated and the problem has to be resolved | 379 | * The MLP problem has to be recreated and the problem has to be resolved |
380 | * | ||
381 | * @param mlp the MLP Handle | ||
382 | * @param addresses the address hashmap | ||
383 | * @param address the address to delete | ||
303 | */ | 384 | */ |
304 | void | 385 | void |
305 | GAS_mlp_address_delete (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) | 386 | GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) |
306 | { | 387 | { |
307 | GNUNET_STATISTICS_update (GAS_mlp->stats,"# LP address deletions", 1, GNUNET_NO); | 388 | GNUNET_STATISTICS_update (mlp->stats,"# LP address deletions", 1, GNUNET_NO); |
308 | 389 | ||
309 | /* Free resources */ | 390 | /* Free resources */ |
310 | if (address->mlp_information != NULL) | 391 | if (address->mlp_information != NULL) |
@@ -316,34 +397,40 @@ GAS_mlp_address_delete (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct | |||
316 | /* Update problem */ | 397 | /* Update problem */ |
317 | 398 | ||
318 | /* Recalculate */ | 399 | /* Recalculate */ |
319 | GAS_mlp->presolver_required = GNUNET_YES; | 400 | mlp->presolver_required = GNUNET_YES; |
320 | mlp_solve_problem (GAS_mlp); | 401 | mlp_solve_problem (mlp); |
321 | } | 402 | } |
322 | 403 | ||
323 | /** | 404 | /** |
324 | * Deletes a single address in the MLP problem | 405 | * Deletes a single address in the MLP problem |
406 | * | ||
407 | * @param mlp the MLP Handle | ||
408 | * @param addresses the address hashmap | ||
409 | * @param address the address to change the preference | ||
325 | */ | 410 | */ |
326 | void | 411 | void |
327 | GAS_mlp_address_change_preference (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) | 412 | GAS_mlp_address_change_preference (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) |
328 | { | 413 | { |
329 | GNUNET_STATISTICS_update (GAS_mlp->stats,"# LP address preference changes", 1, GNUNET_NO); | 414 | GNUNET_STATISTICS_update (mlp->stats,"# LP address preference changes", 1, GNUNET_NO); |
330 | |||
331 | |||
332 | } | 415 | } |
333 | 416 | ||
334 | /** | 417 | /** |
335 | * Shutdown the MLP problem solving component | 418 | * Shutdown the MLP problem solving component |
419 | * @param mlp the MLP handle | ||
336 | */ | 420 | */ |
337 | void | 421 | void |
338 | GAS_mlp_done () | 422 | GAS_mlp_done (struct GAS_MLP_Handle *mlp) |
339 | { | 423 | { |
340 | if (GAS_mlp != NULL) | 424 | if (mlp != NULL) |
341 | glp_delete_prob(GAS_mlp->prob); | 425 | glp_delete_prob(mlp->prob); |
426 | |||
427 | if (mlp->co_Q != NULL) | ||
428 | GNUNET_free (mlp->co_Q); | ||
342 | 429 | ||
343 | /* Clean up GLPK environment */ | 430 | /* Clean up GLPK environment */ |
344 | glp_free_env(); | 431 | glp_free_env(); |
345 | 432 | ||
346 | GNUNET_free (GAS_mlp); | 433 | GNUNET_free (mlp); |
347 | } | 434 | } |
348 | 435 | ||
349 | 436 | ||