diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-02-21 15:12:21 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-02-21 15:12:21 +0000 |
commit | 2e7a719b552a1729684e90c6620553c42260576a (patch) | |
tree | ab756de7143a47e64fb156754cc7ac5cd7c58f7e /src | |
parent | f3738485c15930fc8c1386ed8d2b9734087403fa (diff) | |
download | gnunet-2e7a719b552a1729684e90c6620553c42260576a.tar.gz gnunet-2e7a719b552a1729684e90c6620553c42260576a.zip |
result propagation
Diffstat (limited to 'src')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.c | 232 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.h | 2 |
2 files changed, 67 insertions, 167 deletions
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c index 6af971179..ac82a6a12 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.c +++ b/src/ats/gnunet-service-ats_addresses_mlp.c | |||
@@ -366,173 +366,6 @@ mlp_lookup_ats (struct ATS_Address *addr, int ats_index) | |||
366 | } | 366 | } |
367 | #endif | 367 | #endif |
368 | 368 | ||
369 | /** | ||
370 | * Solves the LP problem | ||
371 | * | ||
372 | * @param mlp the MLP Handle | ||
373 | * @param s_ctx context to return results | ||
374 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | ||
375 | */ | ||
376 | static int | ||
377 | mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) | ||
378 | { | ||
379 | int res; | ||
380 | struct GNUNET_TIME_Relative duration; | ||
381 | struct GNUNET_TIME_Absolute end; | ||
382 | struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get(); | ||
383 | |||
384 | /* LP presolver? | ||
385 | * Presolver is required if the problem was modified and an existing | ||
386 | * valid basis is now invalid */ | ||
387 | if (mlp->presolver_required == GNUNET_YES) | ||
388 | mlp->control_param_lp.presolve = GLP_ON; | ||
389 | else | ||
390 | mlp->control_param_lp.presolve = GLP_OFF; | ||
391 | |||
392 | /* Solve LP problem to have initial valid solution */ | ||
393 | lp_solv: | ||
394 | res = glp_simplex(mlp->prob, &mlp->control_param_lp); | ||
395 | if (res == 0) | ||
396 | { | ||
397 | /* The LP problem instance has been successfully solved. */ | ||
398 | } | ||
399 | else if (res == GLP_EITLIM) | ||
400 | { | ||
401 | /* simplex iteration limit has been exceeded. */ | ||
402 | // TODO Increase iteration limit? | ||
403 | } | ||
404 | else if (res == GLP_ETMLIM) | ||
405 | { | ||
406 | /* Time limit has been exceeded. */ | ||
407 | // TODO Increase time limit? | ||
408 | } | ||
409 | else | ||
410 | { | ||
411 | /* Problem was ill-defined, retry with presolver */ | ||
412 | if (mlp->presolver_required == GNUNET_NO) | ||
413 | { | ||
414 | mlp->presolver_required = GNUNET_YES; | ||
415 | goto lp_solv; | ||
416 | } | ||
417 | else | ||
418 | { | ||
419 | /* Problem was ill-defined, no way to handle that */ | ||
420 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
421 | "ats-mlp", | ||
422 | "Solving LP problem failed: %i %s\n", res, mlp_solve_to_string(res)); | ||
423 | return GNUNET_SYSERR; | ||
424 | } | ||
425 | } | ||
426 | |||
427 | end = GNUNET_TIME_absolute_get (); | ||
428 | duration = GNUNET_TIME_absolute_get_difference (start, end); | ||
429 | mlp->lp_solved++; | ||
430 | mlp->lp_total_duration += duration.rel_value; | ||
431 | s_ctx->lp_duration = duration; | ||
432 | |||
433 | GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO); | ||
434 | GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", duration.rel_value, GNUNET_NO); | ||
435 | GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)", | ||
436 | mlp->lp_total_duration / mlp->lp_solved, GNUNET_NO); | ||
437 | |||
438 | /* Analyze problem status */ | ||
439 | res = glp_get_status (mlp->prob); | ||
440 | switch (res) { | ||
441 | /* solution is optimal */ | ||
442 | case GLP_OPT: | ||
443 | /* solution is feasible */ | ||
444 | case GLP_FEAS: | ||
445 | break; | ||
446 | |||
447 | /* Problem was ill-defined, no way to handle that */ | ||
448 | default: | ||
449 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
450 | "ats-mlp", | ||
451 | "Solving LP problem failed, no solution: %s\n", mlp_status_to_string(res)); | ||
452 | return GNUNET_SYSERR; | ||
453 | break; | ||
454 | } | ||
455 | |||
456 | /* solved sucessfully, no presolver required next time */ | ||
457 | mlp->presolver_required = GNUNET_NO; | ||
458 | |||
459 | return GNUNET_OK; | ||
460 | } | ||
461 | |||
462 | |||
463 | /** | ||
464 | * Solves the MLP problem | ||
465 | * | ||
466 | * @param mlp the MLP Handle | ||
467 | * @param s_ctx context to return results | ||
468 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | ||
469 | */ | ||
470 | int | ||
471 | mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx) | ||
472 | { | ||
473 | int res; | ||
474 | struct GNUNET_TIME_Relative duration; | ||
475 | struct GNUNET_TIME_Absolute end; | ||
476 | struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get(); | ||
477 | |||
478 | /* solve MLP problem */ | ||
479 | res = glp_intopt(mlp->prob, &mlp->control_param_mlp); | ||
480 | |||
481 | if (res == 0) | ||
482 | { | ||
483 | /* The MLP problem instance has been successfully solved. */ | ||
484 | } | ||
485 | else if (res == GLP_EITLIM) | ||
486 | { | ||
487 | /* simplex iteration limit has been exceeded. */ | ||
488 | // TODO Increase iteration limit? | ||
489 | } | ||
490 | else if (res == GLP_ETMLIM) | ||
491 | { | ||
492 | /* Time limit has been exceeded. */ | ||
493 | // TODO Increase time limit? | ||
494 | } | ||
495 | else | ||
496 | { | ||
497 | /* Problem was ill-defined, no way to handle that */ | ||
498 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
499 | "ats-mlp", | ||
500 | "Solving MLP problem failed: %s\n", mlp_solve_to_string(res)); | ||
501 | return GNUNET_SYSERR; | ||
502 | } | ||
503 | |||
504 | end = GNUNET_TIME_absolute_get (); | ||
505 | duration = GNUNET_TIME_absolute_get_difference (start, end); | ||
506 | mlp->mlp_solved++; | ||
507 | mlp->mlp_total_duration += duration.rel_value; | ||
508 | s_ctx->mlp_duration = duration; | ||
509 | |||
510 | GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO); | ||
511 | GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", duration.rel_value, GNUNET_NO); | ||
512 | GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)", | ||
513 | mlp->mlp_total_duration / mlp->mlp_solved, GNUNET_NO); | ||
514 | |||
515 | /* Analyze problem status */ | ||
516 | res = glp_mip_status(mlp->prob); | ||
517 | switch (res) { | ||
518 | /* solution is optimal */ | ||
519 | case GLP_OPT: | ||
520 | /* solution is feasible */ | ||
521 | case GLP_FEAS: | ||
522 | break; | ||
523 | |||
524 | /* Problem was ill-defined, no way to handle that */ | ||
525 | default: | ||
526 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
527 | "ats-mlp", | ||
528 | "Solving MLP problem failed, %s\n\n", mlp_status_to_string(res)); | ||
529 | return GNUNET_SYSERR; | ||
530 | break; | ||
531 | } | ||
532 | |||
533 | return GNUNET_OK; | ||
534 | } | ||
535 | |||
536 | int GAS_mlp_solve_problem (void *solver, struct GAS_MLP_SolutionContext *ctx); | 369 | int GAS_mlp_solve_problem (void *solver, struct GAS_MLP_SolutionContext *ctx); |
537 | 370 | ||
538 | 371 | ||
@@ -1470,6 +1303,64 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp) | |||
1470 | /** | 1303 | /** |
1471 | * Solves the MLP problem | 1304 | * Solves the MLP problem |
1472 | * | 1305 | * |
1306 | * @param mlp the MLP Handle | ||
1307 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | ||
1308 | */ | ||
1309 | int | ||
1310 | mlp_propagate_results (void *cls, const struct GNUNET_HashCode *key, void *value) | ||
1311 | { | ||
1312 | struct GAS_MLP_Handle *mlp = cls; | ||
1313 | struct ATS_Address *address; | ||
1314 | struct MLP_information *mlpi; | ||
1315 | double mlp_bw; | ||
1316 | double mlp_use; | ||
1317 | |||
1318 | /* Check if we have to add this peer due to a pending request */ | ||
1319 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(mlp->peers, key)) | ||
1320 | return GNUNET_OK; | ||
1321 | |||
1322 | address = value; | ||
1323 | GNUNET_assert (address->solver_information != NULL); | ||
1324 | mlpi = address->solver_information; | ||
1325 | |||
1326 | mlp_bw = glp_mip_col_val(mlp->p.prob, mlpi->c_b); | ||
1327 | mlp_use = glp_mip_col_val(mlp->p.prob, mlpi->c_n); | ||
1328 | |||
1329 | if ((GLP_YES == mlp_use) && (GNUNET_NO == address->active)) | ||
1330 | { | ||
1331 | /* Address switch: Activate address*/ | ||
1332 | address->active = GNUNET_YES; | ||
1333 | address->assigned_bw_in.value__ = htonl (0); | ||
1334 | address->assigned_bw_out.value__ = htonl (0); | ||
1335 | mlp->bw_changed_cb (mlp->bw_changed_cb_cls, address); | ||
1336 | } | ||
1337 | else if ((GLP_NO == mlp_use) && (GNUNET_YES == address->active)) | ||
1338 | { | ||
1339 | /* Address switch: Disable address*/ | ||
1340 | address->active = GNUNET_NO; | ||
1341 | /* Set bandwidth to 0 */ | ||
1342 | address->assigned_bw_in.value__ = htonl (0); | ||
1343 | address->assigned_bw_out.value__ = htonl (0); | ||
1344 | mlp->bw_changed_cb (mlp->bw_changed_cb_cls, address); | ||
1345 | } | ||
1346 | else if ((mlp_bw != ntohl(address->assigned_bw_out.value__)) || | ||
1347 | (mlp_bw != ntohl(address->assigned_bw_in.value__))) | ||
1348 | { | ||
1349 | /* Bandwidth changed */ | ||
1350 | address->assigned_bw_in.value__ = htonl (mlp_bw); | ||
1351 | address->assigned_bw_out.value__ = htonl (mlp_bw); | ||
1352 | mlp->bw_changed_cb (mlp->bw_changed_cb_cls, address); | ||
1353 | } | ||
1354 | |||
1355 | return GNUNET_OK; | ||
1356 | } | ||
1357 | |||
1358 | |||
1359 | |||
1360 | |||
1361 | /** | ||
1362 | * Solves the MLP problem | ||
1363 | * | ||
1473 | * @param solver the MLP Handle | 1364 | * @param solver the MLP Handle |
1474 | * @param addresses the address hashmap | 1365 | * @param addresses the address hashmap |
1475 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure | 1366 | * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure |
@@ -1502,6 +1393,7 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr | |||
1502 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n"); | 1393 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n"); |
1503 | } | 1394 | } |
1504 | 1395 | ||
1396 | |||
1505 | /* Run LP solver */ | 1397 | /* Run LP solver */ |
1506 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Running LP solver \n"); | 1398 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Running LP solver \n"); |
1507 | start_lp = GNUNET_TIME_absolute_get(); | 1399 | start_lp = GNUNET_TIME_absolute_get(); |
@@ -1517,6 +1409,12 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr | |||
1517 | (unsigned long long) duration_lp.rel_value, | 1409 | (unsigned long long) duration_lp.rel_value, |
1518 | (unsigned long long) duration_mlp.rel_value); | 1410 | (unsigned long long) duration_mlp.rel_value); |
1519 | 1411 | ||
1412 | /* Propagate result*/ | ||
1413 | if (GNUNET_OK == res) | ||
1414 | { | ||
1415 | GNUNET_CONTAINER_multihashmap_iterate (addresses, &mlp_propagate_results, mlp); | ||
1416 | } | ||
1417 | |||
1520 | /* Reset change and update marker */ | 1418 | /* Reset change and update marker */ |
1521 | mlp->mlp_prob_updated = GNUNET_NO; | 1419 | mlp->mlp_prob_updated = GNUNET_NO; |
1522 | mlp->mlp_prob_changed = GNUNET_NO; | 1420 | mlp->mlp_prob_changed = GNUNET_NO; |
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h index 920bea405..efb819c60 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.h +++ b/src/ats/gnunet-service-ats_addresses_mlp.h | |||
@@ -49,6 +49,8 @@ | |||
49 | #define DEFAULT_MIN_CONNECTIONS 4 | 49 | #define DEFAULT_MIN_CONNECTIONS 4 |
50 | 50 | ||
51 | #define NaN -1 | 51 | #define NaN -1 |
52 | #define GLP_YES 1.0 | ||
53 | #define GLP_NO 0.0 | ||
52 | 54 | ||
53 | struct ATS_Peer | 55 | struct ATS_Peer |
54 | { | 56 | { |