aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-01-20 13:08:24 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-01-20 13:08:24 +0000
commit557f97011bc9c0f01f12217e683e78344dc46bf3 (patch)
tree3da8a6f305c09c89e551b582950d2fe7b94b21c8 /src/ats
parent94d8bba6dea46db5cc5ead1770b0c5c0a1811b02 (diff)
downloadgnunet-557f97011bc9c0f01f12217e683e78344dc46bf3.tar.gz
gnunet-557f97011bc9c0f01f12217e683e78344dc46bf3.zip
- quality updates
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c101
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.h25
-rw-r--r--src/ats/test_ats_mlp.c11
3 files changed, 124 insertions, 13 deletions
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c
index 0de6ec3b3..3c57110f5 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.c
+++ b/src/ats/gnunet-service-ats_addresses_mlp.c
@@ -593,6 +593,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
593 593
594 while (addr != NULL) 594 while (addr != NULL)
595 { 595 {
596 mlpi = addr->mlp_information;
596 /* lookup ATS information */ 597 /* lookup ATS information */
597 int index = mlp_lookup_ats(addr, mlp->q[c]); 598 int index = mlp_lookup_ats(addr, mlp->q[c]);
598 599
@@ -607,8 +608,12 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
607 else 608 else
608 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Quality %i with ATS property `%s' not existing\n", c, mlp_ats_to_string(mlp->q[c]), index); 609 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Quality %i with ATS property `%s' not existing\n", c, mlp_ats_to_string(mlp->q[c]), index);
609#endif 610#endif
610
611 mlpi = addr->mlp_information; 611 mlpi = addr->mlp_information;
612
613 mlpi->r_q[c] = mlp->r_q[c];
614 mlpi->c_q[c] = mlpi->c_b;
615 mlpi->q[c] = value;
616
612 ia[mlp->ci] = mlp->r_q[c]; 617 ia[mlp->ci] = mlp->r_q[c];
613 ja[mlp->ci] = mlpi->c_b; 618 ja[mlp->ci] = mlpi->c_b;
614 ar[mlp->ci] = p->f * value; 619 ar[mlp->ci] = p->f * value;
@@ -924,7 +929,7 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp)
924 return GNUNET_OK; 929 return GNUNET_OK;
925} 930}
926 931
927int mlp_solve_problem (struct GAS_MLP_Handle *mlp); 932int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp);
928 933
929static void 934static void
930mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 935mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -940,7 +945,7 @@ mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduled problem solving\n"); 945 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scheduled problem solving\n");
941#endif 946#endif
942 if (mlp->addr_in_problem != 0) 947 if (mlp->addr_in_problem != 0)
943 mlp_solve_problem(mlp); 948 GAS_mlp_solve_problem(mlp);
944} 949}
945 950
946 951
@@ -951,7 +956,7 @@ mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
951 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure 956 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
952 */ 957 */
953int 958int
954mlp_solve_problem (struct GAS_MLP_Handle *mlp) 959GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp)
955{ 960{
956 int res; 961 int res;
957 mlp->last_execution = GNUNET_TIME_absolute_get (); 962 mlp->last_execution = GNUNET_TIME_absolute_get ();
@@ -1128,6 +1133,7 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
1128 mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats; 1133 mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats;
1129 mlp->max_iterations = max_iterations; 1134 mlp->max_iterations = max_iterations;
1130 mlp->max_exec_duration = max_duration; 1135 mlp->max_exec_duration = max_duration;
1136 mlp->auto_solve = GNUNET_YES;
1131 1137
1132 /* Redirect GLPK output to GNUnet logging */ 1138 /* Redirect GLPK output to GNUnet logging */
1133 glp_error_hook((void *) mlp, &mlp_term_hook); 1139 glp_error_hook((void *) mlp, &mlp_term_hook);
@@ -1165,6 +1171,7 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
1165 return mlp; 1171 return mlp;
1166} 1172}
1167 1173
1174
1168/** 1175/**
1169 * Updates a single address in the MLP problem 1176 * Updates a single address in the MLP problem
1170 * 1177 *
@@ -1184,7 +1191,6 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1184{ 1191{
1185 int new; 1192 int new;
1186 struct MLP_information *mlpi; 1193 struct MLP_information *mlpi;
1187 int c;
1188 1194
1189 GNUNET_STATISTICS_update (mlp->stats,"# LP address updates", 1, GNUNET_NO); 1195 GNUNET_STATISTICS_update (mlp->stats,"# LP address updates", 1, GNUNET_NO);
1190 1196
@@ -1198,6 +1204,15 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1198 if (new == GNUNET_YES) 1204 if (new == GNUNET_YES)
1199 { 1205 {
1200 mlpi = GNUNET_malloc (sizeof (struct MLP_information)); 1206 mlpi = GNUNET_malloc (sizeof (struct MLP_information));
1207
1208 int c;
1209 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
1210 {
1211 mlpi->c_q[c] = 0;
1212 mlpi->r_q[c] = 0;
1213 mlpi->q[c] = 0.0;
1214 }
1215
1201 address->mlp_information = mlpi; 1216 address->mlp_information = mlpi;
1202 mlp->addr_in_problem ++; 1217 mlp->addr_in_problem ++;
1203 1218
@@ -1206,12 +1221,14 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1206 if (peer == NULL) 1221 if (peer == NULL)
1207 { 1222 {
1208#if DEBUG_ATS 1223#if DEBUG_ATS
1209 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding new peer `%s'\n", GNUNET_i2s (&address->peer)); 1224 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding new peer `%s'\n",
1225 GNUNET_i2s (&address->peer));
1210#endif 1226#endif
1211 peer = GNUNET_malloc (sizeof (struct ATS_Peer)); 1227 peer = GNUNET_malloc (sizeof (struct ATS_Peer));
1212 peer->head = NULL; 1228 peer->head = NULL;
1213 peer->tail = NULL; 1229 peer->tail = NULL;
1214 1230
1231 int c;
1215 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++) 1232 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
1216 { 1233 {
1217 peer->f_q[c] = 1.0; 1234 peer->f_q[c] = 1.0;
@@ -1228,7 +1245,8 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1228 else 1245 else
1229 { 1246 {
1230#if DEBUG_ATS 1247#if DEBUG_ATS
1231 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding address to peer `%s'\n", GNUNET_i2s (&address->peer)); 1248 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding address to peer `%s'\n",
1249 GNUNET_i2s (&address->peer));
1232#endif 1250#endif
1233 GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address); 1251 GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address);
1234 } 1252 }
@@ -1236,10 +1254,71 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1236 else 1254 else
1237 { 1255 {
1238#if DEBUG_ATS 1256#if DEBUG_ATS
1239 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating existing address to peer `%s'\n", GNUNET_i2s (&address->peer)); 1257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating existing address to peer `%s'\n",
1258 GNUNET_i2s (&address->peer));
1240#endif 1259#endif
1241 mlpi = address->mlp_information; 1260 mlpi = address->mlp_information;
1261 int c;
1262 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
1263 {
1264 int index = mlp_lookup_ats(address, mlp->q[c]);
1265 if ((index != GNUNET_SYSERR) && (mlpi->c_q[c] != 0) && (mlpi->r_q[c] != 0))
1266 {
1267 if (mlpi->q[c] == (double) address->ats[index].value)
1268 break;
1269#if DEBUG_ATS
1270 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating address for peer `%s' value `%s'from %f to %f\n",
1271 GNUNET_i2s (&address->peer),
1272 mlp_ats_to_string(mlp->q[c]),
1273 mlpi->q[c],
1274 (double) address->ats[index].value);
1275#endif
1276 switch (mlp->q[c])
1277 {
1278 case GNUNET_ATS_QUALITY_NET_DELAY:
1279 mlpi->q[c] = (double) address->ats[index].value;
1280 break;
1281 case GNUNET_ATS_QUALITY_NET_DISTANCE:
1282 mlpi->q[c] = (double) address->ats[index].value;
1283 break;
1284 default:
1285 break;
1286 }
1287
1288 /* Get current number of columns */
1289 int cols = glp_get_num_cols(mlp->prob);
1290 int *ind = GNUNET_malloc (cols * sizeof (int));
1291 double *val = GNUNET_malloc (cols * sizeof (double));
1292
1293 /* Get the matrix row of quality */
1294 cols = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
1295
1296 int c2;
1297 /* Get the index if matrix row of quality */
1298 for (c2 = 1; c2 <= cols; c2++ )
1299 {
1300#if DEBUG_ATS
1301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Existing element column %i : %f\n",
1302 ind[c2], val[c2]);
1303#endif
1304 if ((mlpi->c_b == ind[c2]) && (val[c2] != mlpi->q[c]))
1305 {
1306 /* Update the value */
1307 val[c2] = mlpi->q[c];
1308#if DEBUG_ATS
1309 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "New element column %i : %f\n",
1310 ind[c2], val[c2]);
1311#endif
1312 }
1313 }
1242 1314
1315 /* Get the index if matrix row of quality */
1316 glp_set_mat_row (mlp->prob, mlpi->r_q[c], cols, ind, val);
1317
1318 GNUNET_free (ind);
1319 GNUNET_free (val);
1320 }
1321 }
1243 } 1322 }
1244 1323
1245 /* Recalculate */ 1324 /* Recalculate */
@@ -1249,7 +1328,8 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1249 mlp_create_problem (mlp, addresses); 1328 mlp_create_problem (mlp, addresses);
1250 mlp->presolver_required = GNUNET_YES; 1329 mlp->presolver_required = GNUNET_YES;
1251 } 1330 }
1252 mlp_solve_problem (mlp); 1331 if (mlp->auto_solve == GNUNET_YES)
1332 GAS_mlp_solve_problem (mlp);
1253} 1333}
1254 1334
1255/** 1335/**
@@ -1302,7 +1382,8 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
1302 1382
1303 /* Recalculate */ 1383 /* Recalculate */
1304 mlp->presolver_required = GNUNET_YES; 1384 mlp->presolver_required = GNUNET_YES;
1305 mlp_solve_problem (mlp); 1385 if (mlp->auto_solve == GNUNET_YES)
1386 GAS_mlp_solve_problem (mlp);
1306 } 1387 }
1307} 1388}
1308 1389
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h
index d4ae089b4..43c2b66ad 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.h
+++ b/src/ats/gnunet-service-ats_addresses_mlp.h
@@ -112,6 +112,13 @@ struct GAS_MLP_Handle
112 */ 112 */
113 unsigned int max_iterations; 113 unsigned int max_iterations;
114 114
115 /**
116 * Solve the problem automatically when updates occur?
117 * Default: GNUNET_YES
118 * Can be disabled for test and measurements
119 */
120 int auto_solve;
121
115 /* state information */ 122 /* state information */
116 123
117 /** 124 /**
@@ -257,6 +264,15 @@ struct MLP_information
257 264
258 /* constraint 3: minimum bandwidth */ 265 /* constraint 3: minimum bandwidth */
259 unsigned int r_c3; 266 unsigned int r_c3;
267
268 /* Quality information row indices */
269 unsigned int r_q[GNUNET_ATS_QualityPropertiesCount];
270
271 /* Quality information column indices */
272 unsigned int c_q[GNUNET_ATS_QualityPropertiesCount];
273
274 /* Quality information */
275 double q[GNUNET_ATS_QualityPropertiesCount];
260}; 276};
261 277
262 278
@@ -275,6 +291,15 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
275 struct GNUNET_TIME_Relative max_duration, 291 struct GNUNET_TIME_Relative max_duration,
276 unsigned int max_iterations); 292 unsigned int max_iterations);
277 293
294/**
295 * Solves the MLP problem on demand
296 *
297 * @param mlp the MLP Handle
298 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
299 */
300int
301GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp);
302
278 303
279/** 304/**
280 * Updates a single address in the MLP problem 305 * Updates a single address in the MLP problem
diff --git a/src/ats/test_ats_mlp.c b/src/ats/test_ats_mlp.c
index 0ff5bed4b..ac5b08f9d 100644
--- a/src/ats/test_ats_mlp.c
+++ b/src/ats/test_ats_mlp.c
@@ -88,14 +88,16 @@ check (void *cls, char *const *args, const char *cfgfile,
88 88
89 GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &addr[1].peer.hashPubKey); 89 GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &addr[1].peer.hashPubKey);
90 struct GNUNET_ATS_Information a2_ats[3]; 90 struct GNUNET_ATS_Information a2_ats[3];
91 set_ats (&a2_ats[0], GNUNET_ATS_QUALITY_NET_DELAY, 32); 91 set_ats (&a2_ats[0], GNUNET_ATS_ARRAY_TERMINATOR, 0);
92 set_ats (&a2_ats[1], GNUNET_ATS_QUALITY_NET_DISTANCE, 1); 92 set_ats (&a2_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 32);
93 set_ats (&a2_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0); 93 set_ats (&a2_ats[2], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
94
94 create_address (&addr[1], "dummy2", 3, &a2_ats[0]); 95 create_address (&addr[1], "dummy2", 3, &a2_ats[0]);
95 96
96 GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 97 GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
97 98
98 mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS); 99 mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
100 mlp->auto_solve = GNUNET_NO;
99 101
100 /* Add a new address */ 102 /* Add a new address */
101 GAS_mlp_address_update (mlp, addresses, &addr[0]); 103 GAS_mlp_address_update (mlp, addresses, &addr[0]);
@@ -104,6 +106,7 @@ check (void *cls, char *const *args, const char *cfgfile,
104 GNUNET_assert (mlp->addr_in_problem == 1); 106 GNUNET_assert (mlp->addr_in_problem == 1);
105 107
106 /* Update an new address */ 108 /* Update an new address */
109 set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 20);
107 GAS_mlp_address_update (mlp, addresses, &addr[0]); 110 GAS_mlp_address_update (mlp, addresses, &addr[0]);
108 GNUNET_assert (mlp->addr_in_problem == 1); 111 GNUNET_assert (mlp->addr_in_problem == 1);
109 112
@@ -112,6 +115,8 @@ check (void *cls, char *const *args, const char *cfgfile,
112 GAS_mlp_address_update (mlp, addresses, &addr[1]); 115 GAS_mlp_address_update (mlp, addresses, &addr[1]);
113 GNUNET_assert (mlp->addr_in_problem == 2); 116 GNUNET_assert (mlp->addr_in_problem == 2);
114 117
118 GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp));
119
115 /* Delete an address */ 120 /* Delete an address */
116 GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]); 121 GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]);
117 GAS_mlp_address_delete (mlp, addresses, &addr[0]); 122 GAS_mlp_address_delete (mlp, addresses, &addr[0]);