aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-02-27 16:10:30 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-02-27 16:10:30 +0000
commitbe03b31aa11333f56ba62009709fc955ecdf46fd (patch)
tree655ec6d675f909e3204205287f6d604cd29795d0
parentc8dec9576290c75aae918564f27be6636c4f4e2f (diff)
downloadgnunet-be03b31aa11333f56ba62009709fc955ecdf46fd.tar.gz
gnunet-be03b31aa11333f56ba62009709fc955ecdf46fd.zip
quality update
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c209
-rw-r--r--src/ats/test_ats_mlp_update.c10
2 files changed, 50 insertions, 169 deletions
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c
index 64c1fde82..ecc6f95f0 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.c
+++ b/src/ats/gnunet-service-ats_addresses_mlp.c
@@ -143,7 +143,7 @@
143/** 143/**
144 * Print debug output for mlp problem creation 144 * Print debug output for mlp problem creation
145 */ 145 */
146#define DEBUG_MLP_PROBLEM_CREATION GNUNET_NO 146#define DEBUG_MLP_PROBLEM_CREATION GNUNET_YES
147 147
148/** 148/**
149 * Enable GLPK verbose output 149 * Enable GLPK verbose output
@@ -930,6 +930,7 @@ GAS_mlp_solve_problem (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addr
930 else 930 else
931 { 931 {
932 LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n"); 932 LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n");
933 duration_build.rel_value = 0;
933 } 934 }
934 935
935 /* Run LP solver */ 936 /* Run LP solver */
@@ -1016,8 +1017,11 @@ GAS_mlp_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addres
1016 address->solver_information = GNUNET_malloc (sizeof (struct MLP_information)); 1017 address->solver_information = GNUNET_malloc (sizeof (struct MLP_information));
1017 mlpi = address->solver_information; 1018 mlpi = address->solver_information;
1018 for (c1 = 0; c1 < mlp->pv.m_q; c1++) 1019 for (c1 = 0; c1 < mlp->pv.m_q; c1++)
1020 {
1021 mlpi->q_averaged[c1] = DEFAULT_QUALITY;
1019 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++) 1022 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
1020 mlpi->q[c1][c2] = NaN; 1023 mlpi->q[c1][c2] = NaN;
1024 }
1021 } 1025 }
1022 else 1026 else
1023 LOG (GNUNET_ERROR_TYPE_ERROR, _("Adding address for peer `%s' multiple times\n"), GNUNET_i2s(&address->peer)); 1027 LOG (GNUNET_ERROR_TYPE_ERROR, _("Adding address for peer `%s' multiple times\n"), GNUNET_i2s(&address->peer));
@@ -1046,12 +1050,18 @@ mlp_update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address,
1046 unsigned int c_queue_entries; 1050 unsigned int c_queue_entries;
1047 unsigned int c_cmp; 1051 unsigned int c_cmp;
1048 unsigned int c_queue_it; 1052 unsigned int c_queue_it;
1053 unsigned int c_row;
1054 unsigned int c_qual;
1055 int qual_changed;
1049 int type_index; 1056 int type_index;
1050 int avg_index; 1057 int avg_index;
1051 uint32_t type; 1058 uint32_t type;
1052 uint32_t value; 1059 uint32_t value;
1053 double avg; 1060 double avg;
1054 double * queue; 1061 double *queue;
1062 int rows;
1063 double *val;
1064 int *ind;
1055 1065
1056 LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating %u quality metrics for peer `%s'\n", 1066 LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating %u quality metrics for peer `%s'\n",
1057 ats_count, GNUNET_i2s (&address->peer)); 1067 ats_count, GNUNET_i2s (&address->peer));
@@ -1059,7 +1069,7 @@ mlp_update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address,
1059 GNUNET_assert (NULL != address); 1069 GNUNET_assert (NULL != address);
1060 GNUNET_assert (NULL != address->solver_information); 1070 GNUNET_assert (NULL != address->solver_information);
1061 GNUNET_assert (NULL != ats); 1071 GNUNET_assert (NULL != ats);
1062 1072 qual_changed = GNUNET_NO;
1063 for (c_ats_entry = 0; c_ats_entry < ats_count; c_ats_entry++) 1073 for (c_ats_entry = 0; c_ats_entry < ats_count; c_ats_entry++)
1064 { 1074 {
1065 type = ntohl (ats[c_ats_entry].type); 1075 type = ntohl (ats[c_ats_entry].type);
@@ -1077,10 +1087,7 @@ mlp_update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address,
1077 } 1087 }
1078 } 1088 }
1079 if (-1 == type_index) 1089 if (-1 == type_index)
1080 {
1081 LOG (GNUNET_ERROR_TYPE_DEBUG, "Index not found \n");
1082 continue; /* quality index not found */ 1090 continue; /* quality index not found */
1083 }
1084 1091
1085 /* Get average queue index */ 1092 /* Get average queue index */
1086 avg_index = mlpi->q_avg_i[type_index]; 1093 avg_index = mlpi->q_avg_i[type_index];
@@ -1088,11 +1095,6 @@ mlp_update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address,
1088 /* Update averaging queue */ 1095 /* Update averaging queue */
1089 mlpi->q[type_index][avg_index] = value; 1096 mlpi->q[type_index][avg_index] = value;
1090 1097
1091 LOG (GNUNET_ERROR_TYPE_DEBUG, "Update `%s' with value `%u', in q[%u][%u]\n",
1092 mlp_ats_to_string(type), value,
1093 type_index, avg_index);
1094
1095
1096 /* Update averaging index */ 1098 /* Update averaging index */
1097 if (mlpi->q_avg_i[type_index] + 1 < (MLP_AVERAGING_QUEUE_LENGTH)) 1099 if (mlpi->q_avg_i[type_index] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
1098 mlpi->q_avg_i[type_index] ++; 1100 mlpi->q_avg_i[type_index] ++;
@@ -1121,179 +1123,54 @@ mlp_update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address,
1121 else 1123 else
1122 mlpi->q_averaged[type_index] = 0.0; 1124 mlpi->q_averaged[type_index] = 0.0;
1123 1125
1124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum of %u elements == %f, average == %f, weight == %f\n", 1126 LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating peer `%s': `%s' average sum of %u elements == %f, average == %f, weight == %f\n",
1125 GNUNET_i2s (&address->peer), 1127 GNUNET_i2s (&address->peer),
1126 mlp_ats_to_string(mlp->pv.q[type_index]), 1128 mlp_ats_to_string(mlp->pv.q[type_index]),
1127 c_queue_entries, 1129 c_queue_entries,
1128 avg, 1130 avg,
1129 avg / (double) c_queue_entries, 1131 avg / (double) c_queue_entries,
1130 mlpi->q_averaged[type_index]); 1132 mlpi->q_averaged[type_index]);
1133 qual_changed = GNUNET_YES;
1131 break; 1134 break;
1132 default: 1135 default:
1133 GNUNET_break (0); 1136 GNUNET_break (0);
1134 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Update for ATS type `%s' not implemented!\n"), 1137 LOG (GNUNET_ERROR_TYPE_DEBUG, _("Update for ATS type `%s' not implemented!\n"),
1135 mlp_ats_to_string(type)); 1138 mlp_ats_to_string(type));
1136 } 1139 }
1137
1138
1139 /* Update problem matrix */
1140
1141 } 1140 }
1142 1141
1142 /* Update problem matrix if required */
1143 if (GNUNET_NO == qual_changed)
1144 return;
1143 1145
1144#if 0 1146 /* Changed, but quality will be automatically set during rebuild */
1145// GNUNET_assert (NULL != address->ats); 1147 if (GNUNET_YES == mlp->mlp_prob_changed)
1146 1148 return;
1147
1148 //struct GNUNET_ATS_Information *ats = address->ats;
1149 GNUNET_assert (mlpi != NULL);
1150
1151 int c_ats_entry;
1152 for (c_ats_entry = 0; c_ats_entry < GNUNET_ATS_QualityPropertiesCount; c_ats_entry++)
1153 {
1154
1155 /* FIXME int index = mlp_lookup_ats(address, mlp->q[c]); */
1156 int type_index = GNUNET_SYSERR;
1157
1158 if (type_index == GNUNET_SYSERR)
1159 continue;
1160 /* FIXME
1161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n",
1162 GNUNET_i2s (&address->peer),
1163 mlp_ats_to_string(mlp->q[c]),
1164 (double) ats[index].value);
1165
1166 int i = mlpi->q_avg_i[c_ats_entry];*/
1167 double * qp = mlpi->q[c_ats_entry];
1168 /* FIXME
1169 qp[i] = (double) ats[index].value;
1170 */
1171
1172 int t;
1173 for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
1174 {
1175 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
1176 GNUNET_i2s (&address->peer),
1177 mlp_ats_to_string(mlp->q[c_ats_entry]),
1178 t,
1179 qp[t]);
1180 }
1181
1182 if (mlpi->q_avg_i[c_ats_entry] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
1183 mlpi->q_avg_i[c_ats_entry] ++;
1184 else
1185 mlpi->q_avg_i[c_ats_entry] = 0;
1186
1187
1188 int c_queue_entries;
1189 int c_queue_it;
1190 double avg = 0.0;
1191 switch (mlp->q[c_ats_entry])
1192 {
1193 case GNUNET_ATS_QUALITY_NET_DELAY:
1194 c_queue_it = 0;
1195 for (c_queue_entries = 0; c_queue_entries < MLP_AVERAGING_QUEUE_LENGTH; c_queue_entries++)
1196 {
1197 if (mlpi->q[c][c_queue_entries] != -1)
1198 {
1199 double * t2 = mlpi->q[c_ats_entry] ;
1200 avg += t2[c_queue_entries];
1201 c_queue_it ++;
1202 }
1203 }
1204 if ((c_queue_it > 0) && (avg > 0))
1205 /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
1206 mlpi->q_averaged[c_ats_entry] = (double) c_queue_it / avg;
1207 else
1208 mlpi->q_averaged[c_ats_entry] = 0.0;
1209
1210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
1211 GNUNET_i2s (&address->peer),
1212 mlp_ats_to_string(mlp->q[c_ats_entry]),
1213 avg,
1214 avg / (double) c_queue_it,
1215 mlpi->q_averaged[c_ats_entry]);
1216
1217 break;
1218 case GNUNET_ATS_QUALITY_NET_DISTANCE:
1219 c_queue_it = 0;
1220 for (c_queue_entries = 0; c_queue_entries < MLP_AVERAGING_QUEUE_LENGTH; queue_entries++)
1221 {
1222 if (mlpi->q[c_ats_entry][c_queue_entries] != -1)
1223 {
1224 double * t2 = mlpi->q[c_ats_entry] ;
1225 avg += t2[c_queue_entries];
1226 c_queue_it ++;
1227 }
1228 }
1229 if ((c_queue_it > 0) && (avg > 0))
1230 /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
1231 mlpi->q_averaged[c_ats_entry] = (double) c_queue_it / avg;
1232 else
1233 mlpi->q_averaged[c_ats_entry] = 0.0;
1234
1235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
1236 GNUNET_i2s (&address->peer),
1237 mlp_ats_to_string(mlp->q[c_ats_entry]),
1238 avg,
1239 avg / (double) c_queue_it,
1240 mlpi->q_averaged[c_ats_entry]);
1241
1242 break;
1243 default:
1244 break;
1245 }
1246
1247 if ((mlpi->c_b != 0) && (mlpi->r_q[c_ats_entry] != 0))
1248 {
1249
1250 /* Get current number of columns */
1251 int found = GNUNET_NO;
1252 int cols = glp_get_num_cols(mlp->prob);
1253 int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
1254 double *val = GNUNET_malloc (cols * sizeof (double) + 1);
1255
1256 /* Get the matrix row of quality */
1257 int length = glp_get_mat_row(mlp->prob, mlp->r_q[c_ats_entry], ind, val);
1258 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b);
1259 int c4;
1260 /* Get the index if matrix row of quality */
1261 for (c4 = 1; c4 <= length; c4++ )
1262 {
1263 if (mlpi->c_b == ind[c4])
1264 {
1265 /* Update the value */
1266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n",
1267 mlp_ats_to_string(mlp->q[c_ats_entry]),
1268 glp_get_col_name (mlp->prob, ind[c4]),
1269 glp_get_row_name (mlp->prob, mlp->r_q[c_ats_entry]),
1270 val[c4],
1271 mlpi->q_averaged[c_ats_entry]);
1272 val[c4] = mlpi->q_averaged[c];
1273 found = GNUNET_YES;
1274 break;
1275 }
1276 }
1277 1149
1278 if (found == GNUNET_NO) 1150 /* Address not yet included in matrix */
1279 { 1151 if (0 == mlpi->c_b)
1152 return;
1280 1153
1281 ind[length+1] = mlpi->c_b; 1154 /* Update c7) [r_q[index]][c_b] = f_q * q_averaged[type_index]
1282 val[length+1] = mlpi->q_averaged[c_ats_entry]; 1155 * Get column mlpi->c_b */
1283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]: %i %f\n", length+1, length+1, length+1, mlpi->c_b, mlpi->q_averaged[c_ats_entry]); 1156 rows = glp_get_num_rows(mlp->p.prob);
1284 glp_set_mat_row (mlp->prob, mlpi->r_q[c_ats_entry], length+1, ind, val); 1157 ind = GNUNET_malloc (rows * sizeof (int) + 1);
1285 } 1158 val = GNUNET_malloc (rows * sizeof (double) + 1);
1286 else 1159 int length = glp_get_mat_col (mlp->p.prob, mlpi->c_b, ind, val);
1287 {
1288 /* Get the index if matrix row of quality */
1289 glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
1290 }
1291 1160
1292 GNUNET_free (ind); 1161 for (c_qual = 0; c_qual < mlp->pv.m_q; c_qual++)
1293 GNUNET_free (val); 1162 {
1294 } 1163 for (c_row = 0; c_row <= length; c_row ++)
1295 } 1164 {
1296#endif 1165 if (ind[c_row] == mlp->p.r_q[c_qual])
1166 val[c_row] = mlpi->q_averaged[c_qual];
1167 }
1168 }
1169 /* Set updated column */
1170 glp_set_mat_col (mlp->p.prob, mlpi->c_b, length, ind, val);
1171 GNUNET_free (ind);
1172 GNUNET_free (val);
1173 mlp->mlp_prob_updated = GNUNET_YES;
1297} 1174}
1298 1175
1299/** 1176/**
diff --git a/src/ats/test_ats_mlp_update.c b/src/ats/test_ats_mlp_update.c
index 95ff2fffe..ed48337e5 100644
--- a/src/ats/test_ats_mlp_update.c
+++ b/src/ats/test_ats_mlp_update.c
@@ -222,6 +222,12 @@ check (void *cls, char *const *args, const char *cfgfile,
222 /* Adding address 0 */ 222 /* Adding address 0 */
223 GAS_mlp_address_add (mlp, addresses, address[0]); 223 GAS_mlp_address_add (mlp, addresses, address[0]);
224 224
225 /* Retrieving preferred address for peer and wait for callback */
226 GAS_mlp_get_preferred_address (mlp, addresses, &p[0]);
227
228 /* Solve problem to build matrix */
229 GAS_mlp_solve_problem (mlp, addresses);
230
225 /* Updating address 0*/ 231 /* Updating address 0*/
226 ats[0].type = htonl (GNUNET_ATS_NETWORK_TYPE); 232 ats[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
227 ats[0].value = htonl (GNUNET_ATS_NET_WAN); 233 ats[0].value = htonl (GNUNET_ATS_NET_WAN);
@@ -233,9 +239,7 @@ check (void *cls, char *const *args, const char *cfgfile,
233 ats[3].value = htonl (GNUNET_ATS_ARRAY_TERMINATOR); 239 ats[3].value = htonl (GNUNET_ATS_ARRAY_TERMINATOR);
234 GAS_mlp_address_update (mlp, addresses, address[0], 1, GNUNET_NO, ats, 4); 240 GAS_mlp_address_update (mlp, addresses, address[0], 1, GNUNET_NO, ats, 4);
235 241
236 /* Retrieving preferred address for peer and wait for callback */ 242 /* Solve problem to build matrix */
237 GAS_mlp_get_preferred_address (mlp, addresses, &p[0]);
238
239 GAS_mlp_solve_problem (mlp, addresses); 243 GAS_mlp_solve_problem (mlp, addresses);
240} 244}
241 245