diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-20 13:08:24 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-01-20 13:08:24 +0000 |
commit | 557f97011bc9c0f01f12217e683e78344dc46bf3 (patch) | |
tree | 3da8a6f305c09c89e551b582950d2fe7b94b21c8 /src/ats | |
parent | 94d8bba6dea46db5cc5ead1770b0c5c0a1811b02 (diff) | |
download | gnunet-557f97011bc9c0f01f12217e683e78344dc46bf3.tar.gz gnunet-557f97011bc9c0f01f12217e683e78344dc46bf3.zip |
- quality updates
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.c | 101 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_mlp.h | 25 | ||||
-rw-r--r-- | src/ats/test_ats_mlp.c | 11 |
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 | ||
927 | int mlp_solve_problem (struct GAS_MLP_Handle *mlp); | 932 | int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp); |
928 | 933 | ||
929 | static void | 934 | static void |
930 | mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 935 | mlp_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 | */ |
953 | int | 958 | int |
954 | mlp_solve_problem (struct GAS_MLP_Handle *mlp) | 959 | GAS_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 | */ | ||
300 | int | ||
301 | GAS_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]); |