+ surfxml_add_callback(ETag_surfxml_route_cb_list,
+ &parse_E_route_store_route);
+ surfxml_add_callback(ETag_surfxml_ASroute_cb_list,
+ &parse_E_ASroute_store_route);
+ surfxml_add_callback(ETag_surfxml_bypassRoute_cb_list,
+ &parse_E_bypassRoute_store_route);
+
+ surfxml_add_callback(STag_surfxml_AS_cb_list, &parse_S_AS_XML);
+ surfxml_add_callback(ETag_surfxml_AS_cb_list, &parse_E_AS_XML);
+
+ surfxml_add_callback(STag_surfxml_cluster_cb_list,
+ &routing_parse_Scluster);
+
+ surfxml_add_callback(STag_surfxml_peer_cb_list,
+ &routing_parse_Speer);
+
+#ifdef HAVE_TRACING
+ instr_routing_define_callbacks();
+#endif
+}
+
+void surf_parse_add_callback_config(void)
+{
+ surfxml_add_callback(STag_surfxml_config_cb_list, &routing_parse_Sconfig);
+ surfxml_add_callback(ETag_surfxml_config_cb_list, &routing_parse_Econfig);
+ surfxml_add_callback(STag_surfxml_prop_cb_list, &parse_properties);
+ surfxml_add_callback(STag_surfxml_AS_cb_list, &surf_parse_models_setup);
+}
+
+void surf_parse_models_setup()
+{
+ surfxml_del_callback(STag_surfxml_AS_cb_list, surf_parse_models_setup);
+ surf_config_models_setup(platform_filename);
+ free(platform_filename);
+}
+
+/* ************************************************************************** */
+/* *************************** FULL ROUTING ********************************* */
+
+#define TO_ROUTE_FULL(i,j) routing->routing_table[(i)+(j)*table_size]
+
+/* Routing model structure */
+
+typedef struct {
+ s_routing_component_t generic_routing;
+ route_extended_t *routing_table;
+} s_routing_component_full_t, *routing_component_full_t;
+
+/* Business methods */
+static xbt_dynar_t full_get_onelink_routes(routing_component_t rc)
+{
+ xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
+
+ routing_component_full_t routing = (routing_component_full_t) rc;
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+ xbt_dict_cursor_t c1 = NULL, c2 = NULL;
+ char *k1, *d1, *k2, *d2;
+ xbt_dict_foreach(routing->generic_routing.to_index, c1, k1, d1) {
+ xbt_dict_foreach(routing->generic_routing.to_index, c2, k2, d2) {
+ int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, k1);
+ int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, k2);
+ xbt_assert2(src_id
+ && dst_id,
+ "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
+ src, dst);
+ route_extended_t route = TO_ROUTE_FULL(*src_id, *dst_id);
+ if (route) {
+ if (xbt_dynar_length(route->generic_route.link_list) == 1) {
+ void *link =
+ *(void **) xbt_dynar_get_ptr(route->generic_route.link_list,
+ 0);
+ onelink_t onelink = xbt_new0(s_onelink_t, 1);
+ onelink->link_ptr = link;
+ if (routing->generic_routing.hierarchy == SURF_ROUTING_BASE) {
+ onelink->src = xbt_strdup(k1);
+ onelink->dst = xbt_strdup(k2);
+ } else if (routing->generic_routing.hierarchy ==
+ SURF_ROUTING_RECURSIVE) {
+ onelink->src = xbt_strdup(route->src_gateway);
+ onelink->dst = xbt_strdup(route->dst_gateway);
+ }
+ xbt_dynar_push(ret, &onelink);
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+static route_extended_t full_get_route(routing_component_t rc,
+ const char *src, const char *dst)
+{
+ xbt_assert1(rc && src
+ && dst,
+ "Invalid params for \"get_route\" function at AS \"%s\"",
+ rc->name);
+
+ /* set utils vars */
+ routing_component_full_t routing = (routing_component_full_t) rc;
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+
+ generic_src_dst_check(rc, src, dst);
+ int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
+ int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
+ xbt_assert2(src_id
+ && dst_id,
+ "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
+ src, dst);
+
+ route_extended_t e_route = NULL;
+ route_extended_t new_e_route = NULL;
+ void *link;
+ unsigned int cpt = 0;
+
+ e_route = TO_ROUTE_FULL(*src_id, *dst_id);
+
+ if (e_route) {
+ new_e_route = xbt_new0(s_route_extended_t, 1);
+ new_e_route->src_gateway = xbt_strdup(e_route->src_gateway);
+ new_e_route->dst_gateway = xbt_strdup(e_route->dst_gateway);
+ new_e_route->generic_route.link_list =
+ xbt_dynar_new(global_routing->size_of_link, NULL);
+ xbt_dynar_foreach(e_route->generic_route.link_list, cpt, link) {
+ xbt_dynar_push(new_e_route->generic_route.link_list, &link);
+ }
+ }
+ return new_e_route;
+}
+
+static void full_finalize(routing_component_t rc)
+{
+ routing_component_full_t routing = (routing_component_full_t) rc;
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+ int i, j;
+ if (routing) {
+ /* Delete routing table */
+ for (i = 0; i < table_size; i++)
+ for (j = 0; j < table_size; j++)
+ generic_free_extended_route(TO_ROUTE_FULL(i, j));
+ xbt_free(routing->routing_table);
+ /* Delete bypass dict */
+ xbt_dict_free(&rc->bypassRoutes);
+ /* Delete index dict */
+ xbt_dict_free(&rc->to_index);
+ /* Delete structure */
+ xbt_free(rc);
+ }
+}
+
+/* Creation routing model functions */
+
+static void *model_full_create(void)
+{
+ routing_component_full_t new_component =
+ xbt_new0(s_routing_component_full_t, 1);
+ new_component->generic_routing.set_processing_unit =
+ generic_set_processing_unit;
+ new_component->generic_routing.set_autonomous_system =
+ generic_set_autonomous_system;
+ new_component->generic_routing.set_route = model_full_set_route;
+ new_component->generic_routing.set_ASroute = model_full_set_route;
+ new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
+ new_component->generic_routing.get_route = full_get_route;
+ new_component->generic_routing.get_latency = generic_get_link_latency;
+ new_component->generic_routing.get_onelink_routes =
+ full_get_onelink_routes;
+ new_component->generic_routing.get_bypass_route =
+ generic_get_bypassroute;
+ new_component->generic_routing.finalize = full_finalize;
+ new_component->generic_routing.to_index = xbt_dict_new();
+ new_component->generic_routing.bypassRoutes = xbt_dict_new();
+ new_component->generic_routing.get_network_element_type = get_network_element_type;
+ return new_component;
+}
+
+static void model_full_load(void)
+{
+ /* use "surfxml_add_callback" to add a parse function call */
+}
+
+static void model_full_unload(void)
+{
+ /* use "surfxml_del_callback" to remove a parse function call */
+}
+
+static void model_full_end(void)
+{
+ unsigned int i;
+ route_extended_t e_route;
+
+ /* set utils vars */
+ routing_component_full_t routing =
+ ((routing_component_full_t) current_routing);
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+
+ /* Create table if necessary */
+ if(!routing->routing_table)
+ routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
+
+ /* Add the loopback if needed */
+ if (current_routing->hierarchy == SURF_ROUTING_BASE) {
+ for (i = 0; i < table_size; i++) {
+ e_route = TO_ROUTE_FULL(i, i);
+ if (!e_route) {
+ e_route = xbt_new0(s_route_extended_t, 1);
+ e_route->src_gateway = NULL;
+ e_route->dst_gateway = NULL;
+ e_route->generic_route.link_list =
+ xbt_dynar_new(global_routing->size_of_link, NULL);
+ xbt_dynar_push(e_route->generic_route.link_list,
+ &global_routing->loopback);
+ TO_ROUTE_FULL(i, i) = e_route;
+ }
+ }
+ }
+}
+
+static void model_full_set_route(routing_component_t rc, const char *src,
+ const char *dst, name_route_extended_t route)
+{
+ int *src_id, *dst_id;
+ src_id = xbt_dict_get_or_null(rc->to_index, src);
+ dst_id = xbt_dict_get_or_null(rc->to_index, dst);
+ routing_component_full_t routing = ((routing_component_full_t) rc);
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+
+ xbt_assert2(src_id
+ && dst_id, "Network elements %s or %s not found", src, dst);
+
+ xbt_assert2(xbt_dynar_length(route->generic_route.link_list) > 0,
+ "Invalid count of links, must be greater than zero (%s,%s)",
+ src, dst);
+
+ if(!routing->routing_table)
+ routing->routing_table = xbt_new0(route_extended_t, table_size * table_size);
+
+ if(TO_ROUTE_FULL(*src_id, *dst_id))
+ {
+ char * link_name;
+ unsigned int i;
+ xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
+ xbt_dynar_foreach(route->generic_route.link_list,i,link_name)
+ {
+ void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
+ xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
+ xbt_dynar_push(link_route_to_test,&link);
+ }
+ xbt_assert2(!xbt_dynar_compare(
+ (void*)TO_ROUTE_FULL(*src_id, *dst_id)->generic_route.link_list,
+ (void*)link_route_to_test,
+ (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
+ "The route between \"%s\" and \"%s\" already exists. If you are trying to define a reverse route, you must set the symmetrical=no attribute to your routes tags.", src,dst);
+ xbt_dynar_free(&link_route_to_test);
+ }
+ else
+ {
+ if(!route->dst_gateway && !route->src_gateway)
+ DEBUG2("Load Route from \"%s\" to \"%s\"", src, dst);
+ else
+ DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
+ route->src_gateway, dst, route->dst_gateway);
+ TO_ROUTE_FULL(*src_id, *dst_id) = generic_new_extended_route(rc->hierarchy,route,1);
+ xbt_dynar_shrink(TO_ROUTE_FULL(*src_id, *dst_id)->generic_route.link_list, 0);
+ }
+
+ if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
+ || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
+ {
+ if(route->dst_gateway && route->src_gateway)
+ {
+ char *gw_src = xbt_strdup(route->src_gateway);
+ char *gw_dst = xbt_strdup(route->dst_gateway);
+ route->src_gateway = gw_dst;
+ route->dst_gateway = gw_src;
+ }
+ if(TO_ROUTE_FULL(*dst_id, *src_id))
+ {
+ char * link_name;
+ unsigned int i;
+ xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
+ for(i=xbt_dynar_length(route->generic_route.link_list) ;i>0 ;i--)
+ {
+ link_name = xbt_dynar_get_as(route->generic_route.link_list,i-1,void *);
+ void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
+ xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
+ xbt_dynar_push(link_route_to_test,&link);
+ }
+ xbt_assert2(!xbt_dynar_compare(
+ (void*)TO_ROUTE_FULL(*dst_id, *src_id)->generic_route.link_list,
+ (void*)link_route_to_test,
+ (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
+ "The route between \"%s\" and \"%s\" already exists", src,dst);
+ xbt_dynar_free(&link_route_to_test);
+ }
+ else
+ {
+ if(!route->dst_gateway && !route->src_gateway)
+ DEBUG2("Load Route from \"%s\" to \"%s\"", dst, src);
+ else
+ DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
+ route->src_gateway, src, route->dst_gateway);
+ TO_ROUTE_FULL(*dst_id, *src_id) = generic_new_extended_route(rc->hierarchy,route,0);
+ xbt_dynar_shrink(TO_ROUTE_FULL(*dst_id, *src_id)->generic_route.link_list, 0);
+ }
+
+ }
+}
+
+/* ************************************************************************** */
+/* *************************** FLOYD ROUTING ******************************** */
+
+#define TO_FLOYD_COST(i,j) (routing->cost_table)[(i)+(j)*table_size]
+#define TO_FLOYD_PRED(i,j) (routing->predecessor_table)[(i)+(j)*table_size]
+#define TO_FLOYD_LINK(i,j) (routing->link_table)[(i)+(j)*table_size]
+
+/* Routing model structure */
+
+typedef struct {
+ s_routing_component_t generic_routing;
+ /* vars for calculate the floyd algorith. */
+ int *predecessor_table;
+ double *cost_table;
+ route_extended_t *link_table; /* char* -> int* */
+} s_routing_component_floyd_t, *routing_component_floyd_t;
+
+static route_extended_t floyd_get_route(routing_component_t rc,
+ const char *src, const char *dst);
+
+/* Business methods */
+static xbt_dynar_t floyd_get_onelink_routes(routing_component_t rc)
+{
+ xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
+
+ routing_component_floyd_t routing = (routing_component_floyd_t) rc;
+ //size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+ xbt_dict_cursor_t c1 = NULL, c2 = NULL;
+ char *k1, *d1, *k2, *d2;
+ xbt_dict_foreach(routing->generic_routing.to_index, c1, k1, d1) {
+ xbt_dict_foreach(routing->generic_routing.to_index, c2, k2, d2) {
+ route_extended_t route = floyd_get_route(rc, k1, k2);
+ if (route) {
+ if (xbt_dynar_length(route->generic_route.link_list) == 1) {
+ void *link =
+ *(void **) xbt_dynar_get_ptr(route->generic_route.link_list,
+ 0);
+ onelink_t onelink = xbt_new0(s_onelink_t, 1);
+ onelink->link_ptr = link;
+ if (routing->generic_routing.hierarchy == SURF_ROUTING_BASE) {
+ onelink->src = xbt_strdup(k1);
+ onelink->dst = xbt_strdup(k2);
+ } else if (routing->generic_routing.hierarchy ==
+ SURF_ROUTING_RECURSIVE) {
+ onelink->src = xbt_strdup(route->src_gateway);
+ onelink->dst = xbt_strdup(route->dst_gateway);
+ }
+ xbt_dynar_push(ret, &onelink);
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+static route_extended_t floyd_get_route(routing_component_t rc,
+ const char *src, const char *dst)
+{
+ xbt_assert1(rc && src
+ && dst,
+ "Invalid params for \"get_route\" function at AS \"%s\"",
+ rc->name);
+
+ /* set utils vars */
+ routing_component_floyd_t routing = (routing_component_floyd_t) rc;
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+
+ generic_src_dst_check(rc, src, dst);
+ int *src_id = xbt_dict_get_or_null(routing->generic_routing.to_index, src);
+ int *dst_id = xbt_dict_get_or_null(routing->generic_routing.to_index, dst);
+ xbt_assert2(src_id
+ && dst_id,
+ "Ask for route \"from\"(%s) or \"to\"(%s) no found in the local table",
+ src, dst);
+
+ /* create a result route */
+ route_extended_t new_e_route = xbt_new0(s_route_extended_t, 1);
+ new_e_route->generic_route.link_list =
+ xbt_dynar_new(global_routing->size_of_link, NULL);
+ new_e_route->src_gateway = NULL;
+ new_e_route->dst_gateway = NULL;
+
+ int first = 1;
+ int pred = *dst_id;
+ int prev_pred = 0;
+ char *gw_src = NULL, *gw_dst =
+ NULL, *prev_gw_src, *prev_gw_dst, *first_gw = NULL;
+ unsigned int cpt;
+ void *link;
+ xbt_dynar_t links;
+
+ do {
+ prev_pred = pred;
+ pred = TO_FLOYD_PRED(*src_id, pred);
+ if (pred == -1) /* if no pred in route -> no route to host */
+ break;
+ xbt_assert2(TO_FLOYD_LINK(pred, prev_pred),
+ "Invalid link for the route between \"%s\" or \"%s\"", src,
+ dst);
+
+ prev_gw_src = gw_src;
+ prev_gw_dst = gw_dst;
+
+ route_extended_t e_route = TO_FLOYD_LINK(pred, prev_pred);
+ gw_src = e_route->src_gateway;
+ gw_dst = e_route->dst_gateway;
+
+ if (first)
+ first_gw = gw_dst;
+
+ if (rc->hierarchy == SURF_ROUTING_RECURSIVE && !first
+ && strcmp(gw_dst, prev_gw_src)) {
+ xbt_dynar_t e_route_as_to_as =
+ (*(global_routing->get_route)) (gw_dst, prev_gw_src);
+ xbt_assert2(e_route_as_to_as, "no route between \"%s\" and \"%s\"",
+ gw_dst, prev_gw_src);
+ links = e_route_as_to_as;
+ int pos = 0;
+ xbt_dynar_foreach(links, cpt, link) {
+ xbt_dynar_insert_at(new_e_route->generic_route.link_list, pos,
+ &link);
+ pos++;
+ }
+ }
+
+ links = e_route->generic_route.link_list;
+ xbt_dynar_foreach(links, cpt, link) {
+ xbt_dynar_unshift(new_e_route->generic_route.link_list, &link);
+ }
+ first = 0;
+
+ } while (pred != *src_id);
+ xbt_assert4(pred != -1, "no route from host %d to %d (\"%s\" to \"%s\")",
+ *src_id, *dst_id, src, dst);
+
+ if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
+ new_e_route->src_gateway = xbt_strdup(gw_src);
+ new_e_route->dst_gateway = xbt_strdup(first_gw);
+ }
+
+ return new_e_route;
+}
+
+static void floyd_finalize(routing_component_t rc)
+{
+ routing_component_floyd_t routing = (routing_component_floyd_t) rc;
+ int i, j;
+ size_t table_size;
+ if (routing) {
+ table_size = xbt_dict_length(routing->generic_routing.to_index);
+ /* Delete link_table */
+ for (i = 0; i < table_size; i++)
+ for (j = 0; j < table_size; j++)
+ generic_free_extended_route(TO_FLOYD_LINK(i, j));
+ xbt_free(routing->link_table);
+ /* Delete bypass dict */
+ xbt_dict_free(&routing->generic_routing.bypassRoutes);
+ /* Delete index dict */
+ xbt_dict_free(&(routing->generic_routing.to_index));
+ /* Delete dictionary index dict, predecessor and links table */
+ xbt_free(routing->predecessor_table);
+ /* Delete structure */
+ xbt_free(rc);
+ }
+}
+
+static void *model_floyd_create(void)
+{
+ routing_component_floyd_t new_component =
+ xbt_new0(s_routing_component_floyd_t, 1);
+ new_component->generic_routing.set_processing_unit =
+ generic_set_processing_unit;
+ new_component->generic_routing.set_autonomous_system =
+ generic_set_autonomous_system;
+ new_component->generic_routing.set_route = model_floyd_set_route;
+ new_component->generic_routing.set_ASroute = model_floyd_set_route;
+ new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
+ new_component->generic_routing.get_route = floyd_get_route;
+ new_component->generic_routing.get_latency = generic_get_link_latency;
+ new_component->generic_routing.get_onelink_routes =
+ floyd_get_onelink_routes;
+ new_component->generic_routing.get_bypass_route =
+ generic_get_bypassroute;
+ new_component->generic_routing.finalize = floyd_finalize;
+ new_component->generic_routing.to_index = xbt_dict_new();
+ new_component->generic_routing.bypassRoutes = xbt_dict_new();
+ new_component->generic_routing.get_network_element_type = get_network_element_type;
+ return new_component;
+}
+
+static void model_floyd_load(void)
+{
+ /* use "surfxml_add_callback" to add a parse function call */
+}
+
+static void model_floyd_unload(void)
+{
+ /* use "surfxml_del_callback" to remove a parse function call */
+}
+
+static void model_floyd_end(void)
+{
+
+ routing_component_floyd_t routing =
+ ((routing_component_floyd_t) current_routing);
+
+ unsigned int i, j, a, b, c;
+
+ /* set the size of table routing */
+ size_t table_size = xbt_dict_length(routing->generic_routing.to_index);
+
+ if(!routing->link_table)
+ {
+ /* Create Cost, Predecessor and Link tables */
+ routing->cost_table = xbt_new0(double, table_size * table_size); /* link cost from host to host */
+ routing->predecessor_table = xbt_new0(int, table_size * table_size); /* predecessor host numbers */
+ routing->link_table = xbt_new0(route_extended_t, table_size * table_size); /* actual link between src and dst */
+
+ /* Initialize costs and predecessors */
+ for (i = 0; i < table_size; i++)
+ for (j = 0; j < table_size; j++) {
+ TO_FLOYD_COST(i, j) = DBL_MAX;
+ TO_FLOYD_PRED(i, j) = -1;
+ TO_FLOYD_LINK(i, j) = NULL; /* fixed, missing in the previous version */
+ }
+ }
+
+ /* Add the loopback if needed */
+ if (current_routing->hierarchy == SURF_ROUTING_BASE) {
+ for (i = 0; i < table_size; i++) {
+ route_extended_t e_route = TO_FLOYD_LINK(i, i);
+ if (!e_route) {
+ e_route = xbt_new0(s_route_extended_t, 1);
+ e_route->src_gateway = NULL;
+ e_route->dst_gateway = NULL;
+ e_route->generic_route.link_list =
+ xbt_dynar_new(global_routing->size_of_link, NULL);
+ xbt_dynar_push(e_route->generic_route.link_list,
+ &global_routing->loopback);
+ TO_FLOYD_LINK(i, i) = e_route;
+ TO_FLOYD_PRED(i, i) = i;
+ TO_FLOYD_COST(i, i) = 1;
+ }
+ }
+ }
+ /* Calculate path costs */
+ for (c = 0; c < table_size; c++) {
+ for (a = 0; a < table_size; a++) {
+ for (b = 0; b < table_size; b++) {
+ if (TO_FLOYD_COST(a, c) < DBL_MAX && TO_FLOYD_COST(c, b) < DBL_MAX) {
+ if (TO_FLOYD_COST(a, b) == DBL_MAX ||
+ (TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b) <
+ TO_FLOYD_COST(a, b))) {
+ TO_FLOYD_COST(a, b) =
+ TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b);
+ TO_FLOYD_PRED(a, b) = TO_FLOYD_PRED(c, b);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void model_floyd_set_route(routing_component_t rc, const char *src,
+ const char *dst, name_route_extended_t route)
+{
+ routing_component_floyd_t routing = (routing_component_floyd_t) rc;
+
+ /* set the size of table routing */
+ size_t table_size = xbt_dict_length(rc->to_index);
+ int *src_id, *dst_id;
+ int i,j;
+
+ src_id = xbt_dict_get_or_null(rc->to_index, src);
+ dst_id = xbt_dict_get_or_null(rc->to_index, dst);
+
+ if(!routing->link_table)
+ {
+ /* Create Cost, Predecessor and Link tables */
+ routing->cost_table = xbt_new0(double, table_size * table_size); /* link cost from host to host */
+ routing->predecessor_table = xbt_new0(int, table_size * table_size); /* predecessor host numbers */
+ routing->link_table = xbt_new0(route_extended_t, table_size * table_size); /* actual link between src and dst */
+
+ /* Initialize costs and predecessors */
+ for (i = 0; i < table_size; i++)
+ for (j = 0; j < table_size; j++) {
+ TO_FLOYD_COST(i, j) = DBL_MAX;
+ TO_FLOYD_PRED(i, j) = -1;
+ TO_FLOYD_LINK(i, j) = NULL; /* fixed, missing in the previous version */
+ }
+ }
+
+ if(TO_FLOYD_LINK(*src_id, *dst_id))
+ {
+ if(!route->dst_gateway && !route->src_gateway)
+ DEBUG2("See Route from \"%s\" to \"%s\"", src, dst);
+ else
+ DEBUG4("See ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
+ route->src_gateway, dst, route->dst_gateway);
+ char * link_name;
+ unsigned int cpt;
+ xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
+ xbt_dynar_foreach(route->generic_route.link_list,cpt,link_name)
+ {
+ void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
+ xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
+ xbt_dynar_push(link_route_to_test,&link);
+ }
+ xbt_assert2(!xbt_dynar_compare(
+ (void*)TO_FLOYD_LINK(*src_id, *dst_id)->generic_route.link_list,
+ (void*)link_route_to_test,
+ (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
+ "The route between \"%s\" and \"%s\" already exists", src,dst);
+ xbt_free(link_route_to_test);
+ }
+ else
+ {
+ if(!route->dst_gateway && !route->src_gateway)
+ DEBUG2("Load Route from \"%s\" to \"%s\"", src, dst);
+ else
+ DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
+ route->src_gateway, dst, route->dst_gateway);
+
+ TO_FLOYD_LINK(*src_id, *dst_id) =
+ generic_new_extended_route(rc->hierarchy, route, 1);
+ TO_FLOYD_PRED(*src_id, *dst_id) = *src_id;
+ TO_FLOYD_COST(*src_id, *dst_id) =
+ ((TO_FLOYD_LINK(*src_id, *dst_id))->generic_route.link_list)->used; /* count of links, old model assume 1 */
+ }
+
+ if( A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES
+ || A_surfxml_ASroute_symmetrical == A_surfxml_ASroute_symmetrical_YES )
+ {
+ if(TO_FLOYD_LINK(*dst_id, *src_id))
+ {
+ if(!route->dst_gateway && !route->src_gateway)
+ DEBUG2("See Route from \"%s\" to \"%s\"", dst, src);
+ else
+ DEBUG4("See ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
+ route->src_gateway, src, route->dst_gateway);
+ char * link_name;
+ unsigned int i;
+ xbt_dynar_t link_route_to_test = xbt_dynar_new(global_routing->size_of_link, NULL);
+ for(i=xbt_dynar_length(route->generic_route.link_list) ;i>0 ;i--)
+ {
+ link_name = xbt_dynar_get_as(route->generic_route.link_list,i-1,void *);
+ void *link = xbt_dict_get_or_null(surf_network_model->resource_set, link_name);
+ xbt_assert1(link,"Link : '%s' doesn't exists.",link_name);
+ xbt_dynar_push(link_route_to_test,&link);
+ }
+ xbt_assert2(!xbt_dynar_compare(
+ (void*)TO_FLOYD_LINK(*dst_id, *src_id)->generic_route.link_list,
+ (void*)link_route_to_test,
+ (int_f_cpvoid_cpvoid_t) surf_pointer_resource_cmp),
+ "The route between \"%s\" and \"%s\" already exists", src,dst);
+ xbt_free(link_route_to_test);
+ }
+ else
+ {
+ if(route->dst_gateway && route->src_gateway)
+ {
+ char *gw_src = xbt_strdup(route->src_gateway);
+ char *gw_dst = xbt_strdup(route->dst_gateway);
+ route->src_gateway = gw_dst;
+ route->dst_gateway = gw_src;
+ }
+
+ if(!route->dst_gateway && !route->src_gateway)
+ DEBUG2("Load Route from \"%s\" to \"%s\"", dst, src);
+ else
+ DEBUG4("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
+ route->src_gateway, src, route->dst_gateway);
+
+ TO_FLOYD_LINK(*dst_id, *src_id) =
+ generic_new_extended_route(rc->hierarchy, route, 0);
+ TO_FLOYD_PRED(*dst_id, *src_id) = *dst_id;
+ TO_FLOYD_COST(*dst_id, *src_id) =
+ ((TO_FLOYD_LINK(*dst_id, *src_id))->generic_route.link_list)->used; /* count of links, old model assume 1 */
+ }
+ }
+}
+
+/* ************************************************************************** */
+/* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
+
+typedef struct {
+ s_routing_component_t generic_routing;
+ xbt_graph_t route_graph; /* xbt_graph */
+ xbt_dict_t graph_node_map; /* map */
+ xbt_dict_t route_cache; /* use in cache mode */
+ int cached;
+} s_routing_component_dijkstra_t, *routing_component_dijkstra_t;
+
+
+typedef struct graph_node_data {
+ int id;
+ int graph_id; /* used for caching internal graph id's */
+} s_graph_node_data_t, *graph_node_data_t;
+
+typedef struct graph_node_map_element {
+ xbt_node_t node;
+} s_graph_node_map_element_t, *graph_node_map_element_t;