aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-02-21 14:38:26 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-02-21 14:38:26 +0000
commitf3738485c15930fc8c1386ed8d2b9734087403fa (patch)
treeb49a4e5b37874b4fc721c6a442f078e7e47e396d /src
parenta6312a8a926cded91ff48ef2fb673954941f1ff5 (diff)
downloadgnunet-f3738485c15930fc8c1386ed8d2b9734087403fa.tar.gz
gnunet-f3738485c15930fc8c1386ed8d2b9734087403fa.zip
changes
Diffstat (limited to 'src')
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c217
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.h16
2 files changed, 148 insertions, 85 deletions
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c
index a9eefbdee..6af971179 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.c
+++ b/src/ats/gnunet-service-ats_addresses_mlp.c
@@ -230,7 +230,32 @@ mlp_ats_to_string (int ats_index)
230 } 230 }
231} 231}
232 232
233#if 0 233/**
234 * Translate glpk status error codes to text
235 * @param retcode return code
236 * @return string with result
237 */
238const char *
239mlp_status_to_string (int retcode)
240{
241 switch (retcode) {
242 case GLP_UNDEF:
243 return "solution is undefined";
244 case GLP_FEAS:
245 return "solution is feasible";
246 case GLP_INFEAS:
247 return "solution is infeasible";
248 case GLP_NOFEAS:
249 return "no feasible solution exists";
250 case GLP_OPT:
251 return "solution is optimal";
252 case GLP_UNBND:
253 return "solution is unbounded";
254 default:
255 GNUNET_break (0);
256 return "unknown error";
257 }
258}
234 259
235/** 260/**
236 * Translate glpk solver error codes to text 261 * Translate glpk solver error codes to text
@@ -263,6 +288,8 @@ mlp_solve_to_string (int retcode)
263 return "time limit exceeded"; 288 return "time limit exceeded";
264 case GLP_ENOPFS: 289 case GLP_ENOPFS:
265 return "no primal feasible solution"; 290 return "no primal feasible solution";
291 case GLP_ENODFS:
292 return "no dual feasible solution";
266 case GLP_EROOT: 293 case GLP_EROOT:
267 return "root LP optimum not provided"; 294 return "root LP optimum not provided";
268 case GLP_ESTOP: 295 case GLP_ESTOP:
@@ -286,34 +313,7 @@ mlp_solve_to_string (int retcode)
286} 313}
287 314
288 315
289/** 316#if 0
290 * Translate glpk status error codes to text
291 * @param retcode return code
292 * @return string with result
293 */
294const char *
295mlp_status_to_string (int retcode)
296{
297 switch (retcode) {
298 case GLP_UNDEF:
299 return "solution is undefined";
300 case GLP_FEAS:
301 return "solution is feasible";
302 case GLP_INFEAS:
303 return "solution is infeasible";
304 case GLP_NOFEAS:
305 return "no feasible solution exists";
306 case GLP_OPT:
307 return "solution is optimal";
308 case GLP_UNBND:
309 return "solution is unbounded";
310 default:
311 GNUNET_break (0);
312 return "unknown error";
313 }
314}
315
316
317/** 317/**
318 * Find a peer in the DLL 318 * Find a peer in the DLL
319 * 319 *
@@ -1175,7 +1175,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
1175 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]); 1175 p->ia[p->ci], p->ja[p->ci], p->ar[p->ci]);
1176#endif 1176#endif
1177 p->ci++; 1177 p->ci++;
1178 1178#if 0
1179 for (tp = mlp->peer_head; tp != NULL; tp = tp->next) 1179 for (tp = mlp->peer_head; tp != NULL; tp = tp->next)
1180 for (ta = tp->head; ta != NULL; ta = ta->next) 1180 for (ta = tp->head; ta != NULL; ta = ta->next)
1181 { 1181 {
@@ -1193,6 +1193,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
1193#endif 1193#endif
1194 p->ci++; 1194 p->ci++;
1195 } 1195 }
1196#endif
1196 } 1197 }
1197} 1198}
1198 1199
@@ -1212,6 +1213,7 @@ mlp_create_address_columns_it (void *cls, const struct GNUNET_HashCode * key, vo
1212 struct GAS_MLP_Handle *mlp = cls; 1213 struct GAS_MLP_Handle *mlp = cls;
1213 struct MLP_Problem *p = &mlp->p; 1214 struct MLP_Problem *p = &mlp->p;
1214 struct ATS_Address *address = value; 1215 struct ATS_Address *address = value;
1216 struct ATS_Peer *peer;
1215 struct MLP_information *mlpi; 1217 struct MLP_information *mlpi;
1216 unsigned int col; 1218 unsigned int col;
1217 char *name; 1219 char *name;
@@ -1226,6 +1228,10 @@ mlp_create_address_columns_it (void *cls, const struct GNUNET_HashCode * key, vo
1226 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(mlp->peers, key)) 1228 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(mlp->peers, key))
1227 return GNUNET_OK; 1229 return GNUNET_OK;
1228 1230
1231 /* Get peer */
1232 peer = GNUNET_CONTAINER_multihashmap_get (mlp->peers, key);
1233 peer->processed = GNUNET_NO;
1234
1229 p->num_addresses ++; 1235 p->num_addresses ++;
1230 mlpi = GNUNET_malloc (sizeof (struct MLP_information)); 1236 mlpi = GNUNET_malloc (sizeof (struct MLP_information));
1231 address->solver_information = mlpi; 1237 address->solver_information = mlpi;
@@ -1378,11 +1384,88 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHas
1378 1384
1379 /* Load the matrix */ 1385 /* Load the matrix */
1380 LOG (GNUNET_ERROR_TYPE_DEBUG, "Loading matrix\n"); 1386 LOG (GNUNET_ERROR_TYPE_DEBUG, "Loading matrix\n");
1381 //glp_load_matrix(mlp->prob, (mlp->ci-1), mlp->ia, mlp->ja, mlp->ar); 1387 glp_load_matrix(p->prob, (p->ci)-1, p->ia, p->ja, p->ar);
1382 1388
1383 return res; 1389 return res;
1384} 1390}
1385 1391
1392/**
1393 * Solves the LP problem
1394 *
1395 * @param mlp the MLP Handle
1396 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
1397 */
1398static int
1399mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp)
1400{
1401 int res = 0;
1402 if (GNUNET_YES == mlp->mlp_prob_changed)
1403 {
1404 /* Problem was recreated: use LP presolver */
1405 mlp->control_param_lp.presolve = GLP_ON;
1406 }
1407 else
1408 {
1409 /* Problem was not recreated: do not use LP presolver */
1410 mlp->control_param_lp.presolve = GLP_OFF;
1411 }
1412
1413 res = glp_simplex(mlp->p.prob, &mlp->control_param_lp);
1414 if (0 == res)
1415 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem: 0x%02X %s\n", res, mlp_solve_to_string(res));
1416 else
1417 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem failed: 0x%02X %s\n", res, mlp_solve_to_string(res));
1418
1419 /* Analyze problem status */
1420 res = glp_get_status (mlp->p.prob);
1421 switch (res) {
1422 /* solution is optimal */
1423 case GLP_OPT:
1424 /* solution is feasible */
1425 case GLP_FEAS:
1426 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem: 0x%02X %s\n",
1427 res, mlp_status_to_string(res));
1428 return GNUNET_OK;
1429 /* Problem was ill-defined, no way to handle that */
1430 default:
1431 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem failed, no solution: 0x%02X %s\n",
1432 res, mlp_status_to_string(res));
1433 return GNUNET_SYSERR;
1434 }
1435}
1436
1437
1438/**
1439 * Solves the MLP problem
1440 *
1441 * @param mlp the MLP Handle
1442 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
1443 */
1444int
1445mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp)
1446{
1447 int res = 0;
1448 res = glp_intopt(mlp->p.prob, &mlp->control_param_mlp);
1449 if (0 == res)
1450 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving MLP problem: 0x%02X %s\n", res, mlp_solve_to_string(res));
1451 else
1452 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving MLP problem failed: 0x%02X %s\n", res, mlp_solve_to_string(res));
1453 /* Analyze problem status */
1454 res = glp_mip_status(mlp->p.prob);
1455 switch (res) {
1456 /* solution is optimal */
1457 case GLP_OPT:
1458 /* solution is feasible */
1459 case GLP_FEAS:
1460 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem: %s\n", mlp_status_to_string(res));
1461 return GNUNET_OK;
1462 /* Problem was ill-defined, no way to handle that */
1463 default:
1464 LOG (GNUNET_ERROR_TYPE_DEBUG,"Solving MLP problem failed, %s\n\n", mlp_status_to_string(res));
1465 return GNUNET_SYSERR;
1466 }
1467}
1468
1386 1469
1387/** 1470/**
1388 * Solves the MLP problem 1471 * Solves the MLP problem
@@ -1396,7 +1479,10 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1396{ 1479{
1397 struct GAS_MLP_Handle *mlp = solver; 1480 struct GAS_MLP_Handle *mlp = solver;
1398 int res = 0; 1481 int res = 0;
1399 1482 struct GNUNET_TIME_Absolute start_lp;
1483 struct GNUNET_TIME_Relative duration_lp;
1484 struct GNUNET_TIME_Absolute start_mlp;
1485 struct GNUNET_TIME_Relative duration_mlp;
1400 GNUNET_assert (NULL != solver); 1486 GNUNET_assert (NULL != solver);
1401 1487
1402 if ((GNUNET_NO == mlp->mlp_prob_changed) && (GNUNET_NO == mlp->mlp_prob_updated)) 1488 if ((GNUNET_NO == mlp->mlp_prob_changed) && (GNUNET_NO == mlp->mlp_prob_updated))
@@ -1416,6 +1502,27 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1416 LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n"); 1502 LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n");
1417 } 1503 }
1418 1504
1505 /* Run LP solver */
1506 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running LP solver \n");
1507 start_lp = GNUNET_TIME_absolute_get();
1508 mlp_solve_lp_problem (mlp);
1509 duration_lp = GNUNET_TIME_absolute_get_duration (start_lp);
1510
1511 /* Run LP solver */
1512 LOG (GNUNET_ERROR_TYPE_DEBUG, "Running MLP solver \n");
1513 start_mlp = GNUNET_TIME_absolute_get();
1514 mlp_solve_lp_problem (mlp);
1515 duration_mlp = GNUNET_TIME_absolute_get_duration (start_mlp);
1516 LOG (GNUNET_ERROR_TYPE_DEBUG, "Solver took LP %llu ms, MLP %llu ms\n",
1517 (unsigned long long) duration_lp.rel_value,
1518 (unsigned long long) duration_mlp.rel_value);
1519
1520 /* Reset change and update marker */
1521 mlp->mlp_prob_updated = GNUNET_NO;
1522 mlp->mlp_prob_changed = GNUNET_NO;
1523
1524 return res;
1525
1419 /* Solve problem */ 1526 /* Solve problem */
1420#if 0 1527#if 0
1421 struct GAS_MLP_Handle *mlp = solver; 1528 struct GAS_MLP_Handle *mlp = solver;
@@ -1544,12 +1651,6 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
1544 mlp->semaphore = GNUNET_NO; 1651 mlp->semaphore = GNUNET_NO;
1545 return res; 1652 return res;
1546#endif 1653#endif
1547
1548 /* Reset change and update marker */
1549 mlp->mlp_prob_updated = GNUNET_NO;
1550 mlp->mlp_prob_changed = GNUNET_NO;
1551
1552 return res;
1553} 1654}
1554 1655
1555/** 1656/**
@@ -1950,34 +2051,9 @@ void
1950GAS_mlp_done (void *solver) 2051GAS_mlp_done (void *solver)
1951{ 2052{
1952 struct GAS_MLP_Handle *mlp = solver; 2053 struct GAS_MLP_Handle *mlp = solver;
1953 struct ATS_Peer * peer;
1954 struct ATS_Address *addr;
1955
1956 GNUNET_assert (mlp != NULL); 2054 GNUNET_assert (mlp != NULL);
1957 2055
1958 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down mlp solver\n"); 2056 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down mlp solver\n");
1959
1960 if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK)
1961 {
1962 GNUNET_SCHEDULER_cancel(mlp->mlp_task);
1963 mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
1964 }
1965
1966 /* clean up peer list */
1967 peer = mlp->peer_head;
1968 while (peer != NULL)
1969 {
1970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up peer `%s'\n", GNUNET_i2s (&peer->id));
1971 GNUNET_CONTAINER_DLL_remove(mlp->peer_head, mlp->peer_tail, peer);
1972 for (addr = peer->head; NULL != addr; addr = peer->head)
1973 {
1974 GNUNET_CONTAINER_DLL_remove(peer->head, peer->tail, addr);
1975 GNUNET_free (addr->solver_information);
1976 addr->solver_information = NULL;
1977 }
1978 GNUNET_free (peer);
1979 peer = mlp->peer_head;
1980 }
1981 mlp_delete_problem (mlp); 2057 mlp_delete_problem (mlp);
1982 2058
1983 GNUNET_CONTAINER_multihashmap_iterate (mlp->peers, &mlp_free_peers, mlp->peers); 2059 GNUNET_CONTAINER_multihashmap_iterate (mlp->peers, &mlp_free_peers, mlp->peers);
@@ -2023,7 +2099,6 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
2023 unsigned long long tmp; 2099 unsigned long long tmp;
2024 unsigned int b_min; 2100 unsigned int b_min;
2025 unsigned int n_min; 2101 unsigned int n_min;
2026 struct GNUNET_TIME_Relative i_exec;
2027 int c; 2102 int c;
2028 int c2; 2103 int c2;
2029 int found; 2104 int found;
@@ -2214,14 +2289,6 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
2214 } 2289 }
2215 } 2290 }
2216 2291
2217 /* Get minimum number of connections from configuration */
2218 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg, "ats",
2219 "MLP_EXEC_INTERVAL",
2220 &i_exec))
2221 mlp->exec_interval = i_exec;
2222 else
2223 mlp->exec_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30);
2224
2225 /* Assign options to handle */ 2292 /* Assign options to handle */
2226 mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats; 2293 mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats;
2227 mlp->bw_changed_cb = bw_changed_cb; 2294 mlp->bw_changed_cb = bw_changed_cb;
@@ -2233,12 +2300,6 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
2233 mlp->pv.b_min = b_min; 2300 mlp->pv.b_min = b_min;
2234 mlp->pv.n_min = n_min; 2301 mlp->pv.n_min = n_min;
2235 mlp->pv.m_q = GNUNET_ATS_QualityPropertiesCount; 2302 mlp->pv.m_q = GNUNET_ATS_QualityPropertiesCount;
2236
2237 mlp->semaphore = GNUNET_NO;
2238 mlp->max_iterations = max_iterations;
2239 mlp->max_exec_duration = max_duration;
2240 mlp->last_execution = GNUNET_TIME_UNIT_FOREVER_ABS;
2241 mlp->auto_solve = GNUNET_YES;
2242 mlp->mlp_prob_changed = GNUNET_NO; 2303 mlp->mlp_prob_changed = GNUNET_NO;
2243 mlp->mlp_prob_updated = GNUNET_NO; 2304 mlp->mlp_prob_updated = GNUNET_NO;
2244 2305
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h
index ce445964d..920bea405 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.h
+++ b/src/ats/gnunet-service-ats_addresses_mlp.h
@@ -52,10 +52,15 @@
52 52
53struct ATS_Peer 53struct ATS_Peer
54{ 54{
55 struct GNUNET_PeerIdentity id;
56
57 /* Was this peer already added to the current problem? */
58 int processed;
59#if 0
55 struct ATS_Peer *next; 60 struct ATS_Peer *next;
56 struct ATS_Peer *prev; 61 struct ATS_Peer *prev;
57 62
58 struct GNUNET_PeerIdentity id; 63
59 64
60 /* Array of quality preferences */ 65 /* Array of quality preferences */
61 double f_q[GNUNET_ATS_QualityPropertiesCount]; 66 double f_q[GNUNET_ATS_QualityPropertiesCount];
@@ -70,6 +75,7 @@ struct ATS_Peer
70 75
71 struct ATS_Address *head; 76 struct ATS_Address *head;
72 struct ATS_Address *tail; 77 struct ATS_Address *tail;
78#endif
73}; 79};
74 80
75struct GAS_MLP_SolutionContext 81struct GAS_MLP_SolutionContext
@@ -216,8 +222,6 @@ struct GAS_MLP_Handle
216 222
217 struct MLP_Variables pv; 223 struct MLP_Variables pv;
218 224
219
220
221 /** 225 /**
222 * GLPK LP control parameter 226 * GLPK LP control parameter
223 */ 227 */
@@ -251,11 +255,8 @@ struct GAS_MLP_Handle
251 */ 255 */
252 int mlp_prob_changed; 256 int mlp_prob_changed;
253 257
254 /**
255 * Solves the task in an regular interval
256 */
257 GNUNET_SCHEDULER_TaskIdentifier mlp_task;
258 258
259#if 0
259 /** 260 /**
260 * Interval between scheduled problem solving 261 * Interval between scheduled problem solving
261 */ 262 */
@@ -329,6 +330,7 @@ struct GAS_MLP_Handle
329 330
330 struct ATS_Peer *peer_head; 331 struct ATS_Peer *peer_head;
331 struct ATS_Peer *peer_tail; 332 struct ATS_Peer *peer_tail;
333#endif
332}; 334};
333 335
334 336