aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats_addresses_mlp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses_mlp.c')
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c167
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 */
39static struct GAS_MLP_Handle *GAS_mlp;
40 43
44static int
45mlp_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 */
46int 107static int
47mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp) 108mlp_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 */
137int 200int
@@ -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 */
206int 271int
@@ -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 */
225int 290struct GAS_MLP_Handle *
226GAS_mlp_init (const struct GNUNET_STATISTICS_Handle *stats, 291GAS_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 */
275void 347void
276GAS_mlp_address_update (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) 348GAS_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 */
304void 385void
305GAS_mlp_address_delete (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) 386GAS_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 */
326void 411void
327GAS_mlp_address_change_preference (struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address) 412GAS_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 */
337void 421void
338GAS_mlp_done () 422GAS_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