diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-01-11 10:28:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-01-11 10:28:07 +0000 |
commit | 9dccfed7fc149542bb836da4243f105dec485114 (patch) | |
tree | 5d361d801a29e8410159fb9fe551536d271d28ee /src/fs/fs_namespace.c | |
parent | a6192b717590e4850a28591383775dd56e403a94 (diff) | |
download | gnunet-9dccfed7fc149542bb836da4243f105dec485114.tar.gz gnunet-9dccfed7fc149542bb836da4243f105dec485114.zip |
trying to fix SVN 1640
Diffstat (limited to 'src/fs/fs_namespace.c')
-rw-r--r-- | src/fs/fs_namespace.c | 127 |
1 files changed, 69 insertions, 58 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index 91502e1de..bc66bb21f 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c | |||
@@ -1032,9 +1032,9 @@ process_update_node (void *cls, | |||
1032 | 1032 | ||
1033 | 1033 | ||
1034 | /** | 1034 | /** |
1035 | * Closure for 'find_sccs'. | 1035 | * Closure for 'find_trees'. |
1036 | */ | 1036 | */ |
1037 | struct FindSccClosure | 1037 | struct FindTreeClosure |
1038 | { | 1038 | { |
1039 | /** | 1039 | /** |
1040 | * Namespace we are operating on. | 1040 | * Namespace we are operating on. |
@@ -1042,14 +1042,14 @@ struct FindSccClosure | |||
1042 | struct GNUNET_FS_Namespace *namespace; | 1042 | struct GNUNET_FS_Namespace *namespace; |
1043 | 1043 | ||
1044 | /** | 1044 | /** |
1045 | * Array with 'head's of SCCs. | 1045 | * Array with 'head's of TREEs. |
1046 | */ | 1046 | */ |
1047 | struct NamespaceUpdateNode **scc_array; | 1047 | struct NamespaceUpdateNode **tree_array; |
1048 | 1048 | ||
1049 | /** | 1049 | /** |
1050 | * Size of 'scc_array' | 1050 | * Size of 'tree_array' |
1051 | */ | 1051 | */ |
1052 | unsigned int scc_array_size; | 1052 | unsigned int tree_array_size; |
1053 | 1053 | ||
1054 | /** | 1054 | /** |
1055 | * Current generational ID used. | 1055 | * Current generational ID used. |
@@ -1057,7 +1057,7 @@ struct FindSccClosure | |||
1057 | unsigned int nug; | 1057 | unsigned int nug; |
1058 | 1058 | ||
1059 | /** | 1059 | /** |
1060 | * Identifier for the current SCC, or UINT_MAX for none yet. | 1060 | * Identifier for the current TREE, or UINT_MAX for none yet. |
1061 | */ | 1061 | */ |
1062 | unsigned int id; | 1062 | unsigned int id; |
1063 | }; | 1063 | }; |
@@ -1065,15 +1065,18 @@ struct FindSccClosure | |||
1065 | 1065 | ||
1066 | /** | 1066 | /** |
1067 | * Find all nodes reachable from the current node (including the | 1067 | * Find all nodes reachable from the current node (including the |
1068 | * current node itself). If they are in no SCC, add them to the | 1068 | * current node itself). If they are in no tree, add them to the |
1069 | * current one. If they are the head of another SCC, merge the | 1069 | * current one. If they are the head of another tree, merge the |
1070 | * SCCs. If they are in the middle of another SCC, let them be. | 1070 | * trees. If they are in the middle of another tree, let them be. |
1071 | * We can tell that a node is already in an SCC by checking if | 1071 | * We can tell that a node is already in an tree by checking if |
1072 | * its 'nug' field is set to the current 'nug' value. It is the | 1072 | * its 'nug' field is set to the current 'nug' value. It is the |
1073 | * head of an SCC if it is in the 'scc_array' under its respective | 1073 | * head of an tree if it is in the 'tree_array' under its respective |
1074 | * 'scc_id'. | 1074 | * 'tree_id'. |
1075 | * | 1075 | * |
1076 | * @param cls closure (of type 'struct FindSccClosure') | 1076 | * In short, we're trying to find the smallest number of tree to |
1077 | * cover a directed graph. | ||
1078 | * | ||
1079 | * @param cls closure (of type 'struct FindTreeClosure') | ||
1077 | * @param key current key code | 1080 | * @param key current key code |
1078 | * @param value value in the hash map | 1081 | * @param value value in the hash map |
1079 | * @return GNUNET_YES if we should continue to | 1082 | * @return GNUNET_YES if we should continue to |
@@ -1081,34 +1084,40 @@ struct FindSccClosure | |||
1081 | * GNUNET_NO if not. | 1084 | * GNUNET_NO if not. |
1082 | */ | 1085 | */ |
1083 | static int | 1086 | static int |
1084 | find_sccs (void *cls, | 1087 | find_trees (void *cls, |
1085 | const GNUNET_HashCode * key, | 1088 | const GNUNET_HashCode * key, |
1086 | void *value) | 1089 | void *value) |
1087 | { | 1090 | { |
1088 | struct FindSccClosure *fc = cls; | 1091 | struct FindTreeClosure *fc = cls; |
1089 | struct NamespaceUpdateNode *nsn = value; | 1092 | struct NamespaceUpdateNode *nsn = value; |
1090 | GNUNET_HashCode hc; | 1093 | GNUNET_HashCode hc; |
1091 | 1094 | ||
1092 | if (nsn->nug == fc->nug) | 1095 | if (nsn->nug == fc->nug) |
1093 | { | 1096 | { |
1094 | if (fc->scc_array[nsn->scc_id] != nsn) | 1097 | if (nsn->tree_id == UINT_MAX) |
1095 | return GNUNET_YES; /* part of another SCC, end trace */ | 1098 | return GNUNET_YES; /* circular */ |
1096 | if (nsn->scc_id == fc->id) | 1099 | GNUNET_assert (nsn->tree_id < fc->tree_array_size); |
1097 | return GNUNET_YES; /* that's us */ | 1100 | if (fc->tree_array[nsn->tree_id] != nsn) |
1098 | fc->scc_array[nsn->scc_id] = NULL; | 1101 | return GNUNET_YES; /* part of "another" (directed) TREE, |
1102 | and not root of it, end trace */ | ||
1103 | if (nsn->tree_id == fc->id) | ||
1104 | return GNUNET_YES; /* that's our own root (can this be?) */ | ||
1105 | /* merge existing TREE, we have a root for both */ | ||
1106 | fc->tree_array[nsn->tree_id] = NULL; | ||
1099 | if (fc->id == UINT_MAX) | 1107 | if (fc->id == UINT_MAX) |
1100 | fc->id = nsn->scc_id; /* take over ID */ | 1108 | fc->id = nsn->tree_id; /* take over ID */ |
1101 | } | 1109 | } |
1102 | else | 1110 | else |
1103 | { | 1111 | { |
1104 | nsn->nug = fc->nug; | 1112 | nsn->nug = fc->nug; |
1113 | nsn->tree_id = UINT_MAX; /* mark as undef */ | ||
1105 | /* trace */ | 1114 | /* trace */ |
1106 | GNUNET_CRYPTO_hash (nsn->update, | 1115 | GNUNET_CRYPTO_hash (nsn->update, |
1107 | strlen (nsn->update), | 1116 | strlen (nsn->update), |
1108 | &hc); | 1117 | &hc); |
1109 | GNUNET_CONTAINER_multihashmap_get_multiple (fc->namespace->update_map, | 1118 | GNUNET_CONTAINER_multihashmap_get_multiple (fc->namespace->update_map, |
1110 | &hc, | 1119 | &hc, |
1111 | &find_sccs, | 1120 | &find_trees, |
1112 | fc); | 1121 | fc); |
1113 | } | 1122 | } |
1114 | return GNUNET_YES; | 1123 | return GNUNET_YES; |
@@ -1123,15 +1132,17 @@ find_sccs (void *cls, | |||
1123 | * | 1132 | * |
1124 | * Calling this function with "next_id" NULL will cause the library to | 1133 | * Calling this function with "next_id" NULL will cause the library to |
1125 | * call "ip" with a root for each strongly connected component of the | 1134 | * call "ip" with a root for each strongly connected component of the |
1126 | * graph (a root being a node from which all other nodes in the Scc | 1135 | * graph (a root being a node from which all other nodes in the Tree |
1127 | * are reachable). | 1136 | * are reachable). |
1128 | * | 1137 | * |
1129 | * Calling this function with "next_id" being the name of a node will | 1138 | * Calling this function with "next_id" being the name of a node will |
1130 | * cause the library to call "ip" with all children of the node. Note | 1139 | * cause the library to call "ip" with all children of the node. Note |
1131 | * that cycles within an SCC are possible (including self-loops). | 1140 | * that cycles within the final tree are possible (including self-loops). |
1141 | * I know, odd definition of a tree, but the GUI will display an actual | ||
1142 | * tree (GtkTreeView), so that's what counts for the term here. | ||
1132 | * | 1143 | * |
1133 | * @param namespace namespace to inspect for updateable content | 1144 | * @param namespace namespace to inspect for updateable content |
1134 | * @param next_id ID to look for; use NULL to look for SCC roots | 1145 | * @param next_id ID to look for; use NULL to look for tree roots |
1135 | * @param ip function to call on each updateable identifier | 1146 | * @param ip function to call on each updateable identifier |
1136 | * @param ip_cls closure for ip | 1147 | * @param ip_cls closure for ip |
1137 | */ | 1148 | */ |
@@ -1146,7 +1157,7 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1146 | GNUNET_HashCode hc; | 1157 | GNUNET_HashCode hc; |
1147 | struct NamespaceUpdateNode *nsn; | 1158 | struct NamespaceUpdateNode *nsn; |
1148 | struct ProcessUpdateClosure pc; | 1159 | struct ProcessUpdateClosure pc; |
1149 | struct FindSccClosure fc; | 1160 | struct FindTreeClosure fc; |
1150 | 1161 | ||
1151 | if (namespace->update_nodes == NULL) | 1162 | if (namespace->update_nodes == NULL) |
1152 | read_update_information_graph (namespace); | 1163 | read_update_information_graph (namespace); |
@@ -1190,12 +1201,12 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1190 | } | 1201 | } |
1191 | #if DEBUG_NAMESPACE | 1202 | #if DEBUG_NAMESPACE |
1192 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1203 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1193 | "Calculating SCCs to find roots of update trees\n"); | 1204 | "Calculating TREEs to find roots of update trees\n"); |
1194 | #endif | 1205 | #endif |
1195 | /* Find heads of SCCs in update graph */ | 1206 | /* Find heads of TREEs in update graph */ |
1196 | nug = ++namespace->nug_gen; | 1207 | nug = ++namespace->nug_gen; |
1197 | fc.scc_array = NULL; | 1208 | fc.tree_array = NULL; |
1198 | fc.scc_array_size = 0; | 1209 | fc.tree_array_size = 0; |
1199 | 1210 | ||
1200 | for (i=0;i<namespace->update_node_count;i++) | 1211 | for (i=0;i<namespace->update_node_count;i++) |
1201 | { | 1212 | { |
@@ -1204,11 +1215,11 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1204 | { | 1215 | { |
1205 | #if DEBUG_NAMESPACE | 1216 | #if DEBUG_NAMESPACE |
1206 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1217 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1207 | "SCC of node `%s' is %u\n", | 1218 | "TREE of node `%s' is %u\n", |
1208 | nsn->id, | 1219 | nsn->id, |
1209 | nsn->nug); | 1220 | nsn->nug); |
1210 | #endif | 1221 | #endif |
1211 | continue; /* already placed in SCC */ | 1222 | continue; /* already placed in TREE */ |
1212 | } | 1223 | } |
1213 | GNUNET_CRYPTO_hash (nsn->update, | 1224 | GNUNET_CRYPTO_hash (nsn->update, |
1214 | strlen (nsn->update), | 1225 | strlen (nsn->update), |
@@ -1219,66 +1230,66 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1219 | fc.namespace = namespace; | 1230 | fc.namespace = namespace; |
1220 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, | 1231 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, |
1221 | &hc, | 1232 | &hc, |
1222 | &find_sccs, | 1233 | &find_trees, |
1223 | &fc); | 1234 | &fc); |
1224 | if (fc.id == UINT_MAX) | 1235 | if (fc.id == UINT_MAX) |
1225 | { | 1236 | { |
1226 | /* start new SCC */ | 1237 | /* start new TREE */ |
1227 | for (fc.id=0;fc.id<fc.scc_array_size;fc.id++) | 1238 | for (fc.id=0;fc.id<fc.tree_array_size;fc.id++) |
1228 | { | 1239 | { |
1229 | if (fc.scc_array[fc.id] == NULL) | 1240 | if (fc.tree_array[fc.id] == NULL) |
1230 | { | 1241 | { |
1231 | fc.scc_array[fc.id] = nsn; | 1242 | fc.tree_array[fc.id] = nsn; |
1232 | nsn->scc_id = fc.id; | 1243 | nsn->tree_id = fc.id; |
1233 | break; | 1244 | break; |
1234 | } | 1245 | } |
1235 | } | 1246 | } |
1236 | if (fc.id == fc.scc_array_size) | 1247 | if (fc.id == fc.tree_array_size) |
1237 | { | 1248 | { |
1238 | GNUNET_array_append (fc.scc_array, | 1249 | GNUNET_array_append (fc.tree_array, |
1239 | fc.scc_array_size, | 1250 | fc.tree_array_size, |
1240 | nsn); | 1251 | nsn); |
1241 | nsn->scc_id = fc.id; | 1252 | nsn->tree_id = fc.id; |
1242 | } | 1253 | } |
1243 | #if DEBUG_NAMESPACE | 1254 | #if DEBUG_NAMESPACE |
1244 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1255 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1245 | "Starting new SCC %u with node `%s'\n", | 1256 | "Starting new TREE %u with node `%s'\n", |
1246 | nsn->scc_id, | 1257 | nsn->tree_id, |
1247 | nsn->id); | 1258 | nsn->id); |
1248 | #endif | 1259 | #endif |
1249 | /* put all nodes with same identifier into this SCC */ | 1260 | /* put all nodes with same identifier into this TREE */ |
1250 | GNUNET_CRYPTO_hash (nsn->id, | 1261 | GNUNET_CRYPTO_hash (nsn->id, |
1251 | strlen (nsn->id), | 1262 | strlen (nsn->id), |
1252 | &hc); | 1263 | &hc); |
1253 | fc.id = nsn->scc_id; | 1264 | fc.id = nsn->tree_id; |
1254 | fc.nug = nug; | 1265 | fc.nug = nug; |
1255 | fc.namespace = namespace; | 1266 | fc.namespace = namespace; |
1256 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, | 1267 | GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, |
1257 | &hc, | 1268 | &hc, |
1258 | &find_sccs, | 1269 | &find_trees, |
1259 | &fc); | 1270 | &fc); |
1260 | } | 1271 | } |
1261 | else | 1272 | else |
1262 | { | 1273 | { |
1263 | /* make head of SCC "id" */ | 1274 | /* make head of TREE "id" */ |
1264 | fc.scc_array[fc.id] = nsn; | 1275 | fc.tree_array[fc.id] = nsn; |
1265 | nsn->scc_id = fc.id; | 1276 | nsn->tree_id = fc.id; |
1266 | } | 1277 | } |
1267 | #if DEBUG_NAMESPACE | 1278 | #if DEBUG_NAMESPACE |
1268 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1279 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1269 | "SCC of node `%s' is %u\n", | 1280 | "TREE of node `%s' is %u\n", |
1270 | nsn->id, | 1281 | nsn->id, |
1271 | fc.id); | 1282 | fc.id); |
1272 | #endif | 1283 | #endif |
1273 | } | 1284 | } |
1274 | for (i=0;i<fc.scc_array_size;i++) | 1285 | for (i=0;i<fc.tree_array_size;i++) |
1275 | { | 1286 | { |
1276 | nsn = fc.scc_array[i]; | 1287 | nsn = fc.tree_array[i]; |
1277 | if (NULL != nsn) | 1288 | if (NULL != nsn) |
1278 | { | 1289 | { |
1279 | #if DEBUG_NAMESPACE | 1290 | #if DEBUG_NAMESPACE |
1280 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1291 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1281 | "Root of SCC %u is node `%s'\n", | 1292 | "Root of TREE %u is node `%s'\n", |
1282 | i, | 1293 | i, |
1283 | nsn->id); | 1294 | nsn->id); |
1284 | #endif | 1295 | #endif |
@@ -1290,12 +1301,12 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, | |||
1290 | nsn->update); | 1301 | nsn->update); |
1291 | } | 1302 | } |
1292 | } | 1303 | } |
1293 | GNUNET_array_grow (fc.scc_array, | 1304 | GNUNET_array_grow (fc.tree_array, |
1294 | fc.scc_array_size, | 1305 | fc.tree_array_size, |
1295 | 0); | 1306 | 0); |
1296 | #if DEBUG_NAMESPACE | 1307 | #if DEBUG_NAMESPACE |
1297 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1308 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1298 | "Done processing SCCs\n"); | 1309 | "Done processing TREEs\n"); |
1299 | #endif | 1310 | #endif |
1300 | } | 1311 | } |
1301 | 1312 | ||