aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-02-25 14:53:26 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-02-25 14:53:26 +0000
commitc1fc36e99b0d077b660cf6e5c3d3846e30cd4320 (patch)
tree61ec61753aedc8b167ee3ee2981b858d9a666705
parent5778894d72e28da8e1038e2002073c7b4b8d13e1 (diff)
downloadgnunet-c1fc36e99b0d077b660cf6e5c3d3846e30cd4320.tar.gz
gnunet-c1fc36e99b0d077b660cf6e5c3d3846e30cd4320.zip
code cleanup + api extension
-rw-r--r--src/ats/gnunet-service-ats_addresses.c9
-rw-r--r--src/ats/gnunet-service-ats_addresses.h5
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c494
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.h16
-rw-r--r--src/ats/gnunet-service-ats_addresses_simplistic.c16
-rw-r--r--src/ats/gnunet-service-ats_addresses_simplistic.h12
6 files changed, 123 insertions, 429 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 3cb119278..a88ff5681 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -346,6 +346,11 @@ struct GAS_Addresses_Handle
346 GAS_solver_get_preferred_address s_get; 346 GAS_solver_get_preferred_address s_get;
347 347
348 /** 348 /**
349 * Get address from solver
350 */
351 GAS_solver_stop_get_preferred_address s_get_stop;
352
353 /**
349 * Delete address in solver 354 * Delete address in solver
350 */ 355 */
351 GAS_solver_address_delete s_del; 356 GAS_solver_address_delete s_del;
@@ -988,6 +993,7 @@ GAS_addresses_request_address_cancel (struct GAS_Addresses_Handle *handle,
988 "No address requests pending for peer `%s', cannot remove!\n", GNUNET_i2s (peer)); 993 "No address requests pending for peer `%s', cannot remove!\n", GNUNET_i2s (peer));
989 return; 994 return;
990 } 995 }
996 handle->s_get_stop (handle->solver, handle->addresses, peer);
991 GAS_addresses_handle_backoff_reset (handle, peer); 997 GAS_addresses_handle_backoff_reset (handle, peer);
992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
993 "Removed request pending for peer `%s\n", GNUNET_i2s (peer)); 999 "Removed request pending for peer `%s\n", GNUNET_i2s (peer));
@@ -1334,6 +1340,7 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
1334 ah->s_add = &GAS_mlp_address_add; 1340 ah->s_add = &GAS_mlp_address_add;
1335 ah->s_update = &GAS_mlp_address_update; 1341 ah->s_update = &GAS_mlp_address_update;
1336 ah->s_get = &GAS_mlp_get_preferred_address; 1342 ah->s_get = &GAS_mlp_get_preferred_address;
1343 ah->s_get_stop = &GAS_mlp_stop_get_preferred_address;
1337 ah->s_pref = &GAS_mlp_address_change_preference; 1344 ah->s_pref = &GAS_mlp_address_change_preference;
1338 ah->s_del = &GAS_mlp_address_delete; 1345 ah->s_del = &GAS_mlp_address_delete;
1339 ah->s_done = &GAS_mlp_done; 1346 ah->s_done = &GAS_mlp_done;
@@ -1349,6 +1356,7 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
1349 ah->s_add = &GAS_simplistic_address_add; 1356 ah->s_add = &GAS_simplistic_address_add;
1350 ah->s_update = &GAS_simplistic_address_update; 1357 ah->s_update = &GAS_simplistic_address_update;
1351 ah->s_get = &GAS_simplistic_get_preferred_address; 1358 ah->s_get = &GAS_simplistic_get_preferred_address;
1359 ah->s_get_stop = &GAS_simplistic_stop_get_preferred_address;
1352 ah->s_pref = &GAS_simplistic_address_change_preference; 1360 ah->s_pref = &GAS_simplistic_address_change_preference;
1353 ah->s_del = &GAS_simplistic_address_delete; 1361 ah->s_del = &GAS_simplistic_address_delete;
1354 ah->s_done = &GAS_simplistic_done; 1362 ah->s_done = &GAS_simplistic_done;
@@ -1363,6 +1371,7 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
1363 GNUNET_assert (NULL != ah->s_add); 1371 GNUNET_assert (NULL != ah->s_add);
1364 GNUNET_assert (NULL != ah->s_update); 1372 GNUNET_assert (NULL != ah->s_update);
1365 GNUNET_assert (NULL != ah->s_get); 1373 GNUNET_assert (NULL != ah->s_get);
1374 GNUNET_assert (NULL != ah->s_get_stop);
1366 GNUNET_assert (NULL != ah->s_pref); 1375 GNUNET_assert (NULL != ah->s_pref);
1367 GNUNET_assert (NULL != ah->s_del); 1376 GNUNET_assert (NULL != ah->s_del);
1368 GNUNET_assert (NULL != ah->s_done); 1377 GNUNET_assert (NULL != ah->s_done);
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h
index b774cff48..ddb011fce 100644
--- a/src/ats/gnunet-service-ats_addresses.h
+++ b/src/ats/gnunet-service-ats_addresses.h
@@ -222,6 +222,11 @@ typedef const struct ATS_Address *
222 struct GNUNET_CONTAINER_MultiHashMap *addresses, 222 struct GNUNET_CONTAINER_MultiHashMap *addresses,
223 const struct GNUNET_PeerIdentity *peer); 223 const struct GNUNET_PeerIdentity *peer);
224 224
225typedef void
226(*GAS_solver_stop_get_preferred_address) (void *solver,
227 struct GNUNET_CONTAINER_MultiHashMap *addresses,
228 const struct GNUNET_PeerIdentity *peer);
229
225 230
226typedef void 231typedef void
227 (*GAS_solver_done) (void *solver); 232 (*GAS_solver_done) (void *solver);
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c
index f7273f8ee..5d92be3a6 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.c
+++ b/src/ats/gnunet-service-ats_addresses_mlp.c
@@ -135,10 +135,29 @@
135 135
136#define LOG(kind,...) GNUNET_log_from (kind, "ats-mlp",__VA_ARGS__) 136#define LOG(kind,...) GNUNET_log_from (kind, "ats-mlp",__VA_ARGS__)
137 137
138/**
139 * Write MLP problem to disk
140 */
138#define WRITE_MLP GNUNET_NO 141#define WRITE_MLP GNUNET_NO
142
143/**
144 * Print debug output for mlp problem creation
145 */
139#define DEBUG_MLP_PROBLEM_CREATION GNUNET_NO 146#define DEBUG_MLP_PROBLEM_CREATION GNUNET_NO
147
148/**
149 * Enable GLPK verbose output
150 */
140#define VERBOSE_GLPK GNUNET_NO 151#define VERBOSE_GLPK GNUNET_NO
141#define TEST_MAX_BW_ASSIGNMENT GNUNET_YES 152
153/**
154 * Maximize bandwidth assigned
155 *
156 * This option can be used to test if problem can be solved at all without
157 * optimizing for utility, diversity or relativity
158 *
159 */
160#define MAXIMIZE_FOR_BANDWIDTH_ASSIGNED GNUNET_NO
142 161
143/** 162/**
144 * Intercept GLPK terminal output 163 * Intercept GLPK terminal output
@@ -330,27 +349,6 @@ mlp_solve_to_string (int retcode)
330 349
331 350
332#if 0 351#if 0
333/**
334 * Find a peer in the DLL
335 *
336 * @param mlp the mlp handle
337 * @param peer the peer to find
338 * @return the peer struct
339 */
340static struct ATS_Peer *
341mlp_find_peer (struct GAS_MLP_Handle *mlp, const struct GNUNET_PeerIdentity *peer)
342{
343 struct ATS_Peer *res = mlp->peer_head;
344 while (res != NULL)
345 {
346 if (0 == memcmp (peer, &res->id, sizeof (struct GNUNET_PeerIdentity)))
347 break;
348 res = res->next;
349 }
350 return res;
351}
352
353
354 352
355#if 0 353#if 0
356/** 354/**
@@ -546,221 +544,6 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
546#endif 544#endif
547 545
548 546
549
550/**
551 * Adds the problem constraints for all addresses
552 * Required for problem recreation after address deletion
553 *
554 * @param mlp the mlp handle
555 * @param addresses all addresses
556 */
557
558static void
559mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses)
560{
561 unsigned int n_addresses;
562 struct MLP_Problem *p = &mlp->p;
563 int c;
564 char *name;
565
566 /* Problem matrix*/
567 n_addresses = p->num_addresses;
568
569 /* Required indices in the constrain matrix
570 *
571 * feasibility constraints:
572 *
573 * c 1) bandwidth capping
574 * #rows: |n_addresses|
575 * #indices: 2 * |n_addresses|
576 *
577 * c 2) one active address per peer
578 * #rows: |peers|
579 * #indices: |n_addresses|
580 *
581 * c 3) minium bandwidth assigned
582 * #rows: |n_addresses|
583 * #indices: 2 * |n_addresses|
584 *
585 * c 4) minimum number of active connections
586 * #rows: 1
587 * #indices: |n_addresses|
588 *
589 * c 5) maximum ressource consumption
590 * #rows: |ressources|
591 * #indices: |n_addresses|
592 *
593 * c 10) obey network specific quota
594 * #rows: |network types
595 * #indices: |n_addresses|
596 *
597 * Sum for feasibility constraints:
598 * #rows: 3 * |n_addresses| + |ressources| + |peers| + 1
599 * #indices: 7 * |n_addresses|
600 *
601 * optimality constraints:
602 *
603 * c 6) diversity
604 * #rows: 1
605 * #indices: |n_addresses| + 1
606 *
607 * c 7) quality
608 * #rows: |quality properties|
609 * #indices: |n_addresses| + |quality properties|
610 *
611 * c 8) utilization
612 * #rows: 1
613 * #indices: |n_addresses| + 1
614 *
615 * c 9) relativity
616 * #rows: |peers|
617 * #indices: |n_addresses| + |peers|
618 * */
619
620 /* last +1 caused by glpk index starting with one: [1..pi]*/
621 int pi = ((7 * n_addresses) + (5 * n_addresses + mlp->pv.m_q + p->num_peers + 2) + 1);
622 p->ci = 1;
623
624 /* row index */
625 int *ia = GNUNET_malloc (pi * sizeof (int));
626 p->ia = ia;
627
628 /* column index */
629 int *ja = GNUNET_malloc (pi * sizeof (int));
630 p->ja = ja;
631
632 /* coefficient */
633 double *ar= GNUNET_malloc (pi * sizeof (double));
634 p->ar = ar;
635
636 /* Adding constraint rows
637 * This constraints are kind of "for all addresses"
638 * Feasibility constraints:
639 *
640 * c 1) bandwidth capping
641 * c 3) minimum bandwidth
642 * c 4) minimum number of connections
643 * c 6) maximize diversity
644 * c 10) obey network specific quota
645 */
646
647
648 /* Adding constraint rows
649 * This constraints are kind of "for all peers"
650 * Feasibility constraints:
651 *
652 * c 2) 1 address per peer
653 * sum (n_p1_1 + ... + n_p1_n) = 1
654 *
655 * c 8) utilization
656 * sum (f_p * b_p1_1 + ... + f_p * b_p1_n) - u = 0
657 *
658 * c 9) relativity
659 * V p : sum (bt_1 + ... +bt_n) - f_p * r = 0
660 * */
661
662#if 0
663 struct ATS_Peer * peer = mlp->peer_head;
664 /* For all peers */
665 while (peer != NULL)
666 {
667 struct ATS_Address *addr = peer->head;
668 struct MLP_information *mlpi = NULL;
669
670
671 /* For all addresses of this peer */
672 while (addr != NULL)
673 {
674 mlpi = (struct MLP_information *) addr->solver_information;
675
676 /* coefficient for c 2) */
677 ia[p->ci] = peer->r_c2;
678 ja[p->ci] = mlpi->c_n;
679 ar[p->ci] = 1;
680#if DEBUG_MLP_PROBLEM_CREATION
681 LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Set value [%u,%u] == %.2f\n",
682 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]);
683#endif
684 p->ci++;
685
686 /* coefficient for c 8) */
687 ia[p->ci] = p->r_c8;
688 ja[p->ci] = mlpi->c_b;
689 ar[p->ci] = peer->f;
690#if DEBUG_MLP_PROBLEM_CREATION
691 LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Set value [%u,%u] == %.2f\n",
692 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]);
693#endif
694 p->ci++;
695
696 /* coefficient for c 9) */
697 ia[p->ci] = peer->r_c9;
698 ja[p->ci] = mlpi->c_b;
699 ar[p->ci] = 1;
700#if DEBUG_MLP_PROBLEM_CREATION
701 LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Set value [%u,%u] == %.2f\n",
702 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]);
703#endif
704 p->ci++;
705 addr = addr->next;
706 }
707 peer = peer->next;
708 }
709#endif
710
711 /* c 7) For all quality metrics */
712 for (c = 0; c < mlp->pv.m_q; c++)
713 {
714 struct ATS_Peer *tp;
715 struct ATS_Address *ta;
716 struct MLP_information * mlpi;
717 double value = 1.0;
718
719 /* Adding rows for c 7) */
720 p->r_q[c] = glp_add_rows (p->prob, 1);
721 GNUNET_asprintf(&name, "c7_q%i_%s", c, mlp_ats_to_string(mlp->pv.q[c]));
722 glp_set_row_name (p->prob, p->r_q[c], name);
723 /* Set row bound == 0 */
724 glp_set_row_bnds (p->prob, p->r_q[c], GLP_FX, 0.0, 0.0);
725#if DEBUG_MLP_PROBLEM_CREATION
726 LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Added row [%u] `%s': %s %u\n",
727 p->r_q[c], name,
728 "<=", 0);
729#endif
730 GNUNET_free (name);
731
732 ia[p->ci] = p->r_q[c];
733 ja[p->ci] = p->c_q[c];
734 ar[p->ci] = -1;
735#if DEBUG_MLP_PROBLEM_CREATION
736 LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Set value [%u,%u] == %.2f\n",
737 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]);
738#endif
739 p->ci++;
740#if 0
741 for (tp = mlp->peer_head; tp != NULL; tp = tp->next)
742 for (ta = tp->head; ta != NULL; ta = ta->next)
743 {
744 mlpi = ta->solver_information;
745 value = mlpi->q_averaged[c];
746
747 mlpi->r_q[c] = p->r_q[c];
748
749 ia[p->ci] = p->r_q[c];
750 ja[p->ci] = mlpi->c_b;
751 ar[p->ci] = tp->f_q[c] * value;
752#if DEBUG_MLP_PROBLEM_CREATION
753 LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Set value [%u,%u] == %.2f\n",
754 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]);
755#endif
756 p->ci++;
757 }
758#endif
759 }
760}
761
762
763
764struct CountContext 547struct CountContext
765{ 548{
766 struct GNUNET_CONTAINER_MultiHashMap * peers; 549 struct GNUNET_CONTAINER_MultiHashMap * peers;
@@ -1001,7 +784,6 @@ mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Pr
1001 int c; 784 int c;
1002 785
1003 /* Row for c4) minimum connection */ 786 /* Row for c4) minimum connection */
1004
1005 /* Number of minimum connections is min(|Peers|, n_min) */ 787 /* Number of minimum connections is min(|Peers|, n_min) */
1006 p->r_c4 = mlp_create_problem_create_constraint (p, "c4", GLP_LO, (mlp->pv.n_min > p->num_peers) ? p->num_peers : mlp->pv.n_min, 0.0); 788 p->r_c4 = mlp_create_problem_create_constraint (p, "c4", GLP_LO, (mlp->pv.n_min > p->num_peers) ? p->num_peers : mlp->pv.n_min, 0.0);
1007 789
@@ -1047,8 +829,9 @@ mlp_create_problem_add_invariant_columns (struct GAS_MLP_Handle *mlp, struct MLP
1047#if TEST_MAX_BW_ASSIGNMENT 829#if TEST_MAX_BW_ASSIGNMENT
1048 mlp->pv.co_D = 0.0; 830 mlp->pv.co_D = 0.0;
1049 mlp->pv.co_U = 0.0; 831 mlp->pv.co_U = 0.0;
1050 mlp->pv.co_R = 0.0; 832
1051#endif 833#endif
834 //mlp->pv.co_R = 0.0;
1052 835
1053 /* Diversity d column */ 836 /* Diversity d column */
1054 p->c_d = mlp_create_problem_create_column (p, "d", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_D); 837 p->c_d = mlp_create_problem_create_column (p, "d", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_D);
@@ -1205,11 +988,11 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp)
1205 case GLP_OPT: 988 case GLP_OPT:
1206 /* solution is feasible */ 989 /* solution is feasible */
1207 case GLP_FEAS: 990 case GLP_FEAS:
1208 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving MLP problem: %s\n", mlp_status_to_string(res)); 991 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving MLP problem: 0x%02X %s\n", res, mlp_status_to_string(res));
1209 return GNUNET_OK; 992 return GNUNET_OK;
1210 /* Problem was ill-defined, no way to handle that */ 993 /* Problem was ill-defined, no way to handle that */
1211 default: 994 default:
1212 LOG (GNUNET_ERROR_TYPE_DEBUG,"Solving MLP problem failed, %s\n\n", mlp_status_to_string(res)); 995 LOG (GNUNET_ERROR_TYPE_DEBUG,"Solving MLP problem failed, 0x%02X %s\n\n", res, mlp_status_to_string(res));
1213 return GNUNET_SYSERR; 996 return GNUNET_SYSERR;
1214 } 997 }
1215} 998}
@@ -1291,6 +1074,8 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1291{ 1074{
1292 struct GAS_MLP_Handle *mlp = solver; 1075 struct GAS_MLP_Handle *mlp = solver;
1293 int res = 0; 1076 int res = 0;
1077 struct GNUNET_TIME_Absolute start_build;
1078 struct GNUNET_TIME_Relative duration_build;
1294 struct GNUNET_TIME_Absolute start_lp; 1079 struct GNUNET_TIME_Absolute start_lp;
1295 struct GNUNET_TIME_Relative duration_lp; 1080 struct GNUNET_TIME_Relative duration_lp;
1296 struct GNUNET_TIME_Absolute start_mlp; 1081 struct GNUNET_TIME_Absolute start_mlp;
@@ -1307,7 +1092,10 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1307 { 1092 {
1308 LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem size changed, rebuilding\n"); 1093 LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem size changed, rebuilding\n");
1309 mlp_delete_problem (mlp); 1094 mlp_delete_problem (mlp);
1095 start_build = GNUNET_TIME_absolute_get();
1310 mlp_create_problem (mlp, addresses); 1096 mlp_create_problem (mlp, addresses);
1097 duration_build = GNUNET_TIME_absolute_get_duration (start_build);
1098 mlp->control_param_lp.presolve = GLP_YES;
1311 } 1099 }
1312 else 1100 else
1313 { 1101 {
@@ -1316,7 +1104,7 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1316 1104
1317 1105
1318 /* Run LP solver */ 1106 /* Run LP solver */
1319 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running LP solver \n"); 1107 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running LP solver %s\n", (GLP_YES == mlp->control_param_lp.presolve)? "with presolver": "without presolver");
1320 start_lp = GNUNET_TIME_absolute_get(); 1108 start_lp = GNUNET_TIME_absolute_get();
1321 res = mlp_solve_lp_problem (mlp); 1109 res = mlp_solve_lp_problem (mlp);
1322 duration_lp = GNUNET_TIME_absolute_get_duration (start_lp); 1110 duration_lp = GNUNET_TIME_absolute_get_duration (start_lp);
@@ -1326,162 +1114,33 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1326 start_mlp = GNUNET_TIME_absolute_get(); 1114 start_mlp = GNUNET_TIME_absolute_get();
1327 res = mlp_solve_mlp_problem (mlp); 1115 res = mlp_solve_mlp_problem (mlp);
1328 duration_mlp = GNUNET_TIME_absolute_get_duration (start_mlp); 1116 duration_mlp = GNUNET_TIME_absolute_get_duration (start_mlp);
1329 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solver took LP %llu ms, MLP %llu ms\n", 1117 LOG (GNUNET_ERROR_TYPE_DEBUG, "Execution time: Build %llu ms, LP %llu ms, MLP %llu ms\n",
1118 (unsigned long long) duration_build.rel_value,
1330 (unsigned long long) duration_lp.rel_value, 1119 (unsigned long long) duration_lp.rel_value,
1331 (unsigned long long) duration_mlp.rel_value); 1120 (unsigned long long) duration_mlp.rel_value);
1332 1121
1333 /* Propagate result*/ 1122 /* Propagate result*/
1334 if (GNUNET_OK == res) 1123 if (GNUNET_OK == res)
1335 {
1336 GNUNET_CONTAINER_multihashmap_iterate (addresses, &mlp_propagate_results, mlp); 1124 GNUNET_CONTAINER_multihashmap_iterate (addresses, &mlp_propagate_results, mlp);
1337 }
1338 1125
1339 /* Store LP */ 1126 /* Write problem and solution to disk */
1340#if WRITE_MLP 1127#if WRITE_MLP
1341 char *filename; 1128 char *filename;
1342 struct GNUNET_TIME_Absolute time = GNUNET_TIME_absolute_get(); 1129 struct GNUNET_TIME_Absolute time = GNUNET_TIME_absolute_get();
1343 GNUNET_asprintf (&filename, "problem_%llu.lp", time.abs_value); 1130 GNUNET_asprintf (&filename, "problem_%llu.lp", time.abs_value);
1344 glp_write_prob (mlp->p.prob, 0, filename); 1131 glp_write_lp(mlp->p.prob, 0, filename);
1345 GNUNET_free (filename); 1132 GNUNET_free (filename);
1346 GNUNET_asprintf (&filename, "problem_%llu.sol", time.abs_value); 1133 GNUNET_asprintf (&filename, "problem_%llu.mip", time.abs_value);
1347 glp_print_sol(mlp->p.prob, filename); 1134 glp_print_mip (mlp->p.prob, filename );
1348 GNUNET_free (filename); 1135 GNUNET_free (filename);
1349#endif 1136#endif
1350 1137
1351 /* Reset change and update marker */ 1138 /* Reset change and update marker */
1139 mlp->control_param_lp.presolve = GLP_NO;
1352 mlp->mlp_prob_updated = GNUNET_NO; 1140 mlp->mlp_prob_updated = GNUNET_NO;
1353 mlp->mlp_prob_changed = GNUNET_NO; 1141 mlp->mlp_prob_changed = GNUNET_NO;
1354 1142
1355 return res; 1143 return res;
1356
1357 /* Solve problem */
1358#if 0
1359 struct GAS_MLP_Handle *mlp = solver;
1360 int res;
1361
1362 GNUNET_assert (NULL != solver);
1363 GNUNET_assert (NULL != ctx);
1364
1365 /* Check if solving is already running */
1366 if (GNUNET_YES == mlp->semaphore)
1367 {
1368 if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK)
1369 {
1370 GNUNET_SCHEDULER_cancel(mlp->mlp_task);
1371 mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
1372 }
1373 mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp);
1374 return GNUNET_SYSERR;
1375 }
1376 mlp->semaphore = GNUNET_YES;
1377
1378 mlp->last_execution = GNUNET_TIME_absolute_get ();
1379
1380 ctx->lp_result = GNUNET_SYSERR;
1381 ctx->mlp_result = GNUNET_SYSERR;
1382 ctx->lp_duration = GNUNET_TIME_UNIT_FOREVER_REL;
1383 ctx->mlp_duration = GNUNET_TIME_UNIT_FOREVER_REL;
1384
1385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve LP problem\n");
1386#if WRITE_MLP
1387 char * name;
1388 static int i;
1389 i++;
1390 GNUNET_asprintf(&name, "problem_%i", i);
1391 glp_write_lp (mlp->prob, 0, name);
1392 GNUNET_free (name);
1393# endif
1394
1395 res = mlp_solve_lp_problem (mlp, ctx);
1396 ctx->lp_result = res;
1397 if (res != GNUNET_OK)
1398 {
1399 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "LP Problem solving failed\n");
1400 mlp->semaphore = GNUNET_NO;
1401 return GNUNET_SYSERR;
1402 }
1403
1404#if WRITE_MLP
1405 GNUNET_asprintf(&name, "problem_%i_lp_solution", i);
1406 glp_print_sol (mlp->prob, name);
1407 GNUNET_free (name);
1408# endif
1409
1410
1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve MLP problem\n");
1412 res = mlp_solve_mlp_problem (mlp, ctx);
1413 ctx->mlp_result = res;
1414 if (res != GNUNET_OK)
1415 {
1416 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP Problem solving failed\n");
1417 mlp->semaphore = GNUNET_NO;
1418 return GNUNET_SYSERR;
1419 }
1420#if WRITE_MLP
1421 GNUNET_asprintf(&name, "problem_%i_mlp_solution", i);
1422 glp_print_mip (mlp->prob, name);
1423 GNUNET_free (name);
1424# endif
1425
1426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved %s (LP duration %llu / MLP duration %llu)\n",
1427 (GNUNET_OK == res) ? "successfully" : "failed",
1428 ctx->lp_duration.rel_value,
1429 ctx->mlp_duration.rel_value);
1430 /* Process result */
1431 struct ATS_Peer *p = NULL;
1432 struct ATS_Address *a = NULL;
1433 struct MLP_information *mlpi = NULL;
1434
1435 for (p = mlp->peer_head; p != NULL; p = p->next)
1436 {
1437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s'\n", GNUNET_i2s (&p->id));
1438 for (a = p->head; a != NULL; a = a->next)
1439 {
1440 double b = 0.0;
1441 double n = 0.0;
1442
1443 mlpi = a->solver_information;
1444
1445 b = glp_mip_col_val(mlp->prob, mlpi->c_b);
1446 mlpi->b = b;
1447
1448 n = glp_mip_col_val(mlp->prob, mlpi->c_n);
1449 if (n == 1.0)
1450 {
1451 /* This is the address to be used */
1452 mlpi->n = GNUNET_YES;
1453 }
1454 else
1455 {
1456 /* This is the address not used */
1457 mlpi->n = GNUNET_NO;
1458 }
1459
1460 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tAddress %s %f\n",
1461 (n == 1.0) ? "[x]" : "[ ]", b);
1462
1463 /* Notify addresses */
1464 if ((ntohl(a->assigned_bw_in.value__) != b) ||
1465 (ntohl(a->assigned_bw_out.value__) != b) ||
1466 (mlpi->n != a->active))
1467 {
1468 a->assigned_bw_in.value__ = htonl(b);
1469 a->assigned_bw_out.value__ = htonl(b);
1470 a->active = mlpi->n;
1471 mlp->bw_changed_cb (mlp->bw_changed_cb_cls, a);
1472 }
1473 }
1474 }
1475
1476 if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK)
1477 {
1478 GNUNET_SCHEDULER_cancel(mlp->mlp_task);
1479 mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
1480 }
1481 mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp);
1482 mlp->semaphore = GNUNET_NO;
1483 return res;
1484#endif
1485} 1144}
1486 1145
1487/** 1146/**
@@ -1501,8 +1160,6 @@ GAS_mlp_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addres
1501 GNUNET_assert (NULL != addresses); 1160 GNUNET_assert (NULL != addresses);
1502 GNUNET_assert (NULL != address); 1161 GNUNET_assert (NULL != address);
1503 1162
1504 /* TODO Add address here */
1505
1506 /* Is this peer included in the problem? */ 1163 /* Is this peer included in the problem? */
1507 if (NULL == (p = GNUNET_CONTAINER_multihashmap_get (mlp->peers, &address->peer.hashPubKey))) 1164 if (NULL == (p = GNUNET_CONTAINER_multihashmap_get (mlp->peers, &address->peer.hashPubKey)))
1508 { 1165 {
@@ -1683,7 +1340,6 @@ GAS_mlp_address_delete (void *solver,
1683 GNUNET_assert (NULL != addresses); 1340 GNUNET_assert (NULL != addresses);
1684 GNUNET_assert (NULL != address); 1341 GNUNET_assert (NULL != address);
1685 1342
1686 /* TODO Delete address here */
1687 if (NULL != address->solver_information) 1343 if (NULL != address->solver_information)
1688 { 1344 {
1689 GNUNET_free (address->solver_information); 1345 GNUNET_free (address->solver_information);
@@ -1703,54 +1359,6 @@ GAS_mlp_address_delete (void *solver,
1703 if (GNUNET_YES == mlp->mlp_auto_solve) 1359 if (GNUNET_YES == mlp->mlp_auto_solve)
1704 GAS_mlp_solve_problem (solver, addresses); 1360 GAS_mlp_solve_problem (solver, addresses);
1705 return; 1361 return;
1706
1707#if 0
1708 GNUNET_STATISTICS_update (mlp->stats,"# LP address deletions", 1, GNUNET_NO);
1709 struct GAS_MLP_SolutionContext ctx;
1710
1711 /* Free resources */
1712 if (address->solver_information != NULL)
1713 {
1714 GNUNET_free (address->solver_information);
1715 address->solver_information = NULL;
1716
1717 mlp->num_addresses --;
1718 GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", -1, GNUNET_NO);
1719 }
1720
1721 /* Remove from peer list */
1722 struct ATS_Peer *head = mlp_find_peer (mlp, &address->peer);
1723 GNUNET_assert (head != NULL);
1724
1725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting address for `%s'\n", GNUNET_i2s (&address->peer));
1726
1727 GNUNET_CONTAINER_DLL_remove (head->head, head->tail, address);
1728 if ((head->head == NULL) && (head->tail == NULL))
1729 {
1730 /* No address for peer left, remove peer */
1731
1732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting peer `%s'\n", GNUNET_i2s (&address->peer));
1733
1734 GNUNET_CONTAINER_DLL_remove (mlp->peer_head, mlp->peer_tail, head);
1735 GNUNET_free (head);
1736 mlp->c_p --;
1737 GNUNET_STATISTICS_update (mlp->stats, "# peers in MLP", -1, GNUNET_NO);
1738 }
1739
1740 /* Update problem */
1741 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Recreating problem: new address\n");
1742
1743 mlp_delete_problem (mlp);
1744 if ((GNUNET_CONTAINER_multihashmap_size (peers) > 0) && (mlp->c_p > 0))
1745 {
1746 mlp_create_problem (mlp, peers);
1747
1748 /* Recalculate */
1749 mlp->presolver_required = GNUNET_YES;
1750 if (mlp->auto_solve == GNUNET_YES)
1751 GAS_mlp_solve_problem (mlp, &ctx);
1752 }
1753#endif
1754} 1362}
1755 1363
1756 1364
@@ -1816,6 +1424,7 @@ GAS_mlp_get_preferred_address (void *solver,
1816 1424
1817 p = GNUNET_malloc (sizeof (struct ATS_Peer)); 1425 p = GNUNET_malloc (sizeof (struct ATS_Peer));
1818 p->id = (*peer); 1426 p->id = (*peer);
1427 p->f = DEFAULT_PEER_PREFERENCE;
1819 GNUNET_CONTAINER_multihashmap_put (mlp->peers, &peer->hashPubKey, p, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 1428 GNUNET_CONTAINER_multihashmap_put (mlp->peers, &peer->hashPubKey, p, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1820 1429
1821 /* Added new peer, we have to rebuild problem before solving */ 1430 /* Added new peer, we have to rebuild problem before solving */
@@ -1832,6 +1441,33 @@ GAS_mlp_get_preferred_address (void *solver,
1832 1441
1833 1442
1834/** 1443/**
1444 * Stop notifying about address and bandwidth changes for this peer
1445 *
1446 * @param solver the MLP handle
1447 * @param addresses address hashmap
1448 * @param peer the peer
1449 */
1450void
1451GAS_mlp_stop_get_preferred_address (void *solver,
1452 struct GNUNET_CONTAINER_MultiHashMap *addresses,
1453 const struct GNUNET_PeerIdentity *peer)
1454{
1455 struct GAS_MLP_Handle *mlp = solver;
1456 struct ATS_Peer *p = NULL;
1457
1458 GNUNET_assert (NULL != solver);
1459 GNUNET_assert (NULL != addresses);
1460 GNUNET_assert (NULL != peer);
1461
1462 if (NULL != (p = GNUNET_CONTAINER_multihashmap_get (mlp->peers, &peer->hashPubKey)))
1463 {
1464 GNUNET_CONTAINER_multihashmap_remove (mlp->peers, &peer->hashPubKey, p);
1465 GNUNET_free (p);
1466 }
1467}
1468
1469
1470/**
1835 * Changes the preferences for a peer in the MLP problem 1471 * Changes the preferences for a peer in the MLP problem
1836 * 1472 *
1837 * @param solver the MLP Handle 1473 * @param solver the MLP Handle
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h
index 15e509849..efffa7320 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.h
+++ b/src/ats/gnunet-service-ats_addresses_mlp.h
@@ -47,6 +47,7 @@
47#define DEFAULT_U 1.0 47#define DEFAULT_U 1.0
48#define DEFAULT_QUALITY 1.0 48#define DEFAULT_QUALITY 1.0
49#define DEFAULT_MIN_CONNECTIONS 4 49#define DEFAULT_MIN_CONNECTIONS 4
50#define DEFAULT_PEER_PREFERENCE 1.0
50 51
51#define NaN -1 52#define NaN -1
52#define GLP_YES 1.0 53#define GLP_YES 1.0
@@ -491,6 +492,21 @@ GAS_mlp_get_preferred_address (void *solver,
491 struct GNUNET_CONTAINER_MultiHashMap * addresses, 492 struct GNUNET_CONTAINER_MultiHashMap * addresses,
492 const struct GNUNET_PeerIdentity *peer); 493 const struct GNUNET_PeerIdentity *peer);
493 494
495
496/**
497 * Stop notifying about address and bandwidth changes for this peer
498 *
499 * @param solver the MLP handle
500 * @param addresses address hashmap
501 * @param peer the peer
502 */
503
504void
505GAS_mlp_stop_get_preferred_address (void *solver,
506 struct GNUNET_CONTAINER_MultiHashMap *addresses,
507 const struct GNUNET_PeerIdentity *peer);
508
509
494/** 510/**
495 * Shutdown the MLP problem solving component 511 * Shutdown the MLP problem solving component
496 * 512 *
diff --git a/src/ats/gnunet-service-ats_addresses_simplistic.c b/src/ats/gnunet-service-ats_addresses_simplistic.c
index 0d7df4f67..d88aa4838 100644
--- a/src/ats/gnunet-service-ats_addresses_simplistic.c
+++ b/src/ats/gnunet-service-ats_addresses_simplistic.c
@@ -1226,6 +1226,22 @@ GAS_simplistic_get_preferred_address (void *solver,
1226 return cur; 1226 return cur;
1227} 1227}
1228 1228
1229
1230/**
1231 * Stop notifying about address and bandwidth changes for this peer
1232 *
1233 * @param solver the MLP handle
1234 * @param addresses address hashmap
1235 * @param peer the peer
1236 */
1237void
1238GAS_simplistic_stop_get_preferred_address (void *solver,
1239 struct GNUNET_CONTAINER_MultiHashMap *addresses,
1240 const struct GNUNET_PeerIdentity *peer)
1241{
1242 return;
1243}
1244
1229static void 1245static void
1230recalculate_preferences (struct PreferencePeer *p) 1246recalculate_preferences (struct PreferencePeer *p)
1231{ 1247{
diff --git a/src/ats/gnunet-service-ats_addresses_simplistic.h b/src/ats/gnunet-service-ats_addresses_simplistic.h
index 42c09b078..c50454191 100644
--- a/src/ats/gnunet-service-ats_addresses_simplistic.h
+++ b/src/ats/gnunet-service-ats_addresses_simplistic.h
@@ -126,6 +126,18 @@ GAS_simplistic_address_delete (void *solver,
126 126
127 127
128/** 128/**
129 * Stop notifying about address and bandwidth changes for this peer
130 *
131 * @param solver the MLP handle
132 * @param addresses address hashmap
133 * @param peer the peer
134 */
135void
136GAS_simplistic_stop_get_preferred_address (void *solver,
137 struct GNUNET_CONTAINER_MultiHashMap *addresses,
138 const struct GNUNET_PeerIdentity *peer);
139
140/**
129 * Get the prefered address for a specific peer 141 * Get the prefered address for a specific peer
130 * 142 *
131 * @param solver the solver handle 143 * @param solver the solver handle