-/* *************************** FLOYD ROUTING ******************************** */
-
-#define TO_FLOYD_COST(i,j) 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;
- route_extended_t *link_table; /* char* -> int* */
- xbt_dict_t to_index;
- xbt_dict_t bypassRoutes;
- /* store data during the parse process */
- xbt_dict_t parse_routes;
-} s_routing_component_floyd_t,*routing_component_floyd_t;
-
-/* Business methods */
-static xbt_dynar_t floyd_get_onelink_routes(routing_component_t rc)
-{
- xbt_die("\"floyd_get_onelink_routes\" function not implemented yet");
-}
-
-static int floyd_is_router(const char *name)
-{
- xbt_die("\"floyd_is_router\" function not implemented yet");
-}
-
-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;
- int table_size = xbt_dict_length(routing->to_index);
-
- generic_src_dst_check(rc,src,dst);
- int *src_id = xbt_dict_get_or_null(routing->to_index,src);
- int *dst_id = xbt_dict_get_or_null(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,table_size;
- if (routing) {
- table_size = xbt_dict_length(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->bypassRoutes);
- /* Delete index dict */
- xbt_dict_free(&(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 = generic_set_route;
- new_component->generic_routing.set_ASroute = generic_set_ASroute;
- new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
- new_component->generic_routing.get_route = floyd_get_route;
- new_component->generic_routing.get_onelink_routes = floyd_get_onelink_routes;
- new_component->generic_routing.is_router = floyd_is_router;
- new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
- new_component->generic_routing.finalize = floyd_finalize;
- new_component->to_index = xbt_dict_new();
- new_component->bypassRoutes = xbt_dict_new();
- new_component->parse_routes = xbt_dict_new();
- 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);
- xbt_dict_cursor_t cursor = NULL;
- double * cost_table;
- char *key,*data, *end;
- const char *sep = "#";
- xbt_dynar_t keys;
- int src_id, dst_id;
- unsigned int i,j,a,b,c;
-
- /* set the size of inicial table */
- int table_size = xbt_dict_length(routing->to_index);
-
- /* Create Cost, Predecessor and Link tables */
- 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 */
- }
-
- /* Put the routes in position */
- xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
- keys = xbt_str_split_str(key, sep);
- src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
- dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
- TO_FLOYD_LINK(src_id,dst_id) = generic_new_extended_route(current_routing->hierarchy,data,0);
- TO_FLOYD_PRED(src_id,dst_id) = src_id;
- /* set link cost */
- 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 */
- xbt_dynar_free(&keys);
- }
-
- /* 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);
- }
- }
- }
- }
- }
-
- /* delete the parse table */
- xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
- route_t route = (route_t)data;
- xbt_dynar_free(&(route->link_list));
- xbt_free(data);
- }
-
- /* delete parse dict */
- xbt_dict_free(&(routing->parse_routes));
-
- /* cleanup */
- xbt_free(cost_table);
-}
-
-/* ************************************************************************** */
-/* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
-
-typedef struct {
- s_routing_component_t generic_routing;
- xbt_dict_t to_index;
- xbt_dict_t bypassRoutes;
- 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;
- xbt_dict_t parse_routes;
-} 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;
-
-typedef struct route_cache_element {
- int * pred_arr;
- int size;
-} s_route_cache_element_t, * route_cache_element_t;
-
-/* Free functions */
-
-static void route_cache_elem_free(void *e) {
- route_cache_element_t elm=(route_cache_element_t)e;
- if (elm) {
- xbt_free(elm->pred_arr);
- xbt_free(elm);
- }
-}
-
-static void graph_node_map_elem_free(void *e) {
- graph_node_map_element_t elm = (graph_node_map_element_t)e;
- if(elm) {
- xbt_free(elm);
- }
-}
-
-static void graph_edge_data_free(void *e) {
- route_extended_t e_route = (route_extended_t)e;
- if(e_route) {
- xbt_dynar_free(&(e_route->generic_route.link_list));
- if(e_route->src_gateway) xbt_free(e_route->src_gateway);
- if(e_route->dst_gateway) xbt_free(e_route->dst_gateway);
- xbt_free(e_route);
- }
-}
-
-/* Utility functions */
-
-static xbt_node_t route_graph_new_node(routing_component_dijkstra_t rc, int id, int graph_id) {
- routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
- xbt_node_t node = NULL;
- graph_node_data_t data = NULL;
- graph_node_map_element_t elm = NULL;
-
- data = xbt_new0(struct graph_node_data, 1);
- data->id = id;
- data->graph_id = graph_id;
- node = xbt_graph_new_node(routing->route_graph, data);
-
- elm = xbt_new0(struct graph_node_map_element, 1);
- elm->node = node;
- xbt_dict_set_ext(routing->graph_node_map, (char*)(&id), sizeof(int), (xbt_set_elm_t)elm, &graph_node_map_elem_free);
-
- return node;
-}
-
-static graph_node_map_element_t graph_node_map_search(routing_component_dijkstra_t rc, int id) {
- routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
- graph_node_map_element_t elm = (graph_node_map_element_t)xbt_dict_get_or_null_ext(routing->graph_node_map, (char*)(&id), sizeof(int));
- return elm;
-}
-
-/* Parsing */
-
-static void route_new_dijkstra(routing_component_dijkstra_t rc, int src_id, int dst_id, route_extended_t e_route ) {
- routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
-
- xbt_node_t src = NULL;
- xbt_node_t dst = NULL;
- graph_node_map_element_t src_elm = (graph_node_map_element_t)xbt_dict_get_or_null_ext(routing->graph_node_map, (char*)(&src_id), sizeof(int));
- graph_node_map_element_t dst_elm = (graph_node_map_element_t)xbt_dict_get_or_null_ext(routing->graph_node_map, (char*)(&dst_id), sizeof(int));
-
- if(src_elm)
- src = src_elm->node;
-
- if(dst_elm)
- dst = dst_elm->node;
-
- /* add nodes if they don't exist in the graph */
- if(src_id == dst_id && src == NULL && dst == NULL) {
- src = route_graph_new_node(rc,src_id, -1);
- dst = src;
- } else {
- if(src == NULL) {
- src = route_graph_new_node(rc,src_id, -1);
- }
- if(dst == NULL) {
- dst = route_graph_new_node(rc,dst_id, -1);
- }
- }
-
- /* add link as edge to graph */
- xbt_graph_new_edge(routing->route_graph, src, dst, e_route);
-}
-
-static void add_loopback_dijkstra(routing_component_dijkstra_t rc) {
- routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
-
- xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
-
- xbt_node_t node = NULL;
- unsigned int cursor2;
- xbt_dynar_foreach(nodes, cursor2, node) {
- xbt_dynar_t out_edges = xbt_graph_node_get_outedges(node);
- xbt_edge_t edge = NULL;
- unsigned int cursor;
-
- int found = 0;
- xbt_dynar_foreach(out_edges, cursor, edge) {
- xbt_node_t other_node = xbt_graph_edge_get_target(edge);
- if(other_node == node) {
- found = 1;
- break;
- }
- }
-
- if(!found) {
- route_extended_t 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);
- xbt_graph_new_edge(routing->route_graph, node, node, e_route);
- }
- }
-}
-
-/* Business methods */
-static xbt_dynar_t dijkstra_get_onelink_routes(routing_component_t rc)
-{
- xbt_die("\"dijkstra_get_onelink_routes\" function not implemented yet");
-}
-
-static int dijkstra_is_router(const char *name)
-{
- xbt_die("\"dijkstra_is_router\" function not implemented yet");
-}
-
-static route_extended_t dijkstra_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_dijkstra_t routing = (routing_component_dijkstra_t) rc;
-
- generic_src_dst_check(rc,src,dst);
- int *src_id = xbt_dict_get_or_null(routing->to_index,src);
- int *dst_id = xbt_dict_get_or_null(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 *pred_arr = NULL;
- int src_node_id = 0;
- int dst_node_id = 0;
- int * nodeid = NULL;
- int v;
- route_extended_t e_route;
- int size = 0;
- unsigned int cpt;
- void* link;
- xbt_dynar_t links = NULL;
- route_cache_element_t elm = NULL;
- xbt_dynar_t nodes = xbt_graph_get_nodes(routing->route_graph);
-
- /* Use the graph_node id mapping set to quickly find the nodes */
- graph_node_map_element_t src_elm = graph_node_map_search(routing,*src_id);
- graph_node_map_element_t dst_elm = graph_node_map_search(routing,*dst_id);
- xbt_assert2(src_elm != NULL && dst_elm != NULL, "src %d or dst %d does not exist", *src_id, *dst_id);
- src_node_id = ((graph_node_data_t)xbt_graph_node_get_data(src_elm->node))->graph_id;
- dst_node_id = ((graph_node_data_t)xbt_graph_node_get_data(dst_elm->node))->graph_id;
-
- /* if the src and dst are the same */ /* fixed, missing in the previous version */
- if( src_node_id == dst_node_id ) {
-
- xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
- xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
- xbt_edge_t edge = xbt_graph_get_edge(routing->route_graph, node_s_v, node_e_v);
-
- xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id, *dst_id);
-
- e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
-
- links = e_route->generic_route.link_list;
- xbt_dynar_foreach(links, cpt, link) {
- xbt_dynar_unshift(new_e_route->generic_route.link_list,&link);
- }
-
- return new_e_route;
- }
-
- if(routing->cached) {
- /*check if there is a cached predecessor list avail */
- elm = (route_cache_element_t)xbt_dict_get_or_null_ext(routing->route_cache, (char*)(&src_id), sizeof(int));
- }
-
- if(elm) { /* cached mode and cache hit */
- pred_arr = elm->pred_arr;
- } else { /* not cached mode or cache miss */
- double * cost_arr = NULL;
- xbt_heap_t pqueue = NULL;
- int i = 0;
-
- int nr_nodes = xbt_dynar_length(nodes);
- cost_arr = xbt_new0(double, nr_nodes); /* link cost from src to other hosts */
- pred_arr = xbt_new0(int, nr_nodes); /* predecessors in path from src */
- pqueue = xbt_heap_new(nr_nodes, xbt_free);
-
- /* initialize */
- cost_arr[src_node_id] = 0.0;
-
- for(i = 0; i < nr_nodes; i++) {
- if(i != src_node_id) {
- cost_arr[i] = DBL_MAX;
- }
-
- pred_arr[i] = 0;
-
- /* initialize priority queue */
- nodeid = xbt_new0(int, 1);
- *nodeid = i;
- xbt_heap_push(pqueue, nodeid, cost_arr[i]);
-
- }
-
- /* apply dijkstra using the indexes from the graph's node array */
- while(xbt_heap_size(pqueue) > 0) {
- int * v_id = xbt_heap_pop(pqueue);
- xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
- xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node);
- xbt_edge_t edge = NULL;
- unsigned int cursor;
-
- xbt_dynar_foreach(out_edges, cursor, edge) {
- xbt_node_t u_node = xbt_graph_edge_get_target(edge);
- graph_node_data_t data = xbt_graph_node_get_data(u_node);
- int u_id = data->graph_id;
- route_extended_t tmp_e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
- int cost_v_u = (tmp_e_route->generic_route.link_list)->used; /* count of links, old model assume 1 */
-
- if(cost_v_u + cost_arr[*v_id] < cost_arr[u_id]) {
- pred_arr[u_id] = *v_id;
- cost_arr[u_id] = cost_v_u + cost_arr[*v_id];
- nodeid = xbt_new0(int, 1);
- *nodeid = u_id;
- xbt_heap_push(pqueue, nodeid, cost_arr[u_id]);
- }
- }
-
- /* free item popped from pqueue */
- xbt_free(v_id);
- }
-
- xbt_free(cost_arr);
- xbt_heap_free(pqueue);
- }
-
- /* compose route path with links */
- char *gw_src=NULL,*gw_dst=NULL, *prev_gw_src,*prev_gw_dst, *first_gw=NULL;
-
- for(v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
- xbt_node_t node_pred_v = xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
- xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
- xbt_edge_t edge = xbt_graph_get_edge(routing->route_graph, node_pred_v, node_v);
-
- xbt_assert2(edge != NULL, "no route between host %d and %d", *src_id, *dst_id);
-
- prev_gw_src = gw_src;
- prev_gw_dst = gw_dst;
-
- e_route = (route_extended_t)xbt_graph_edge_get_data(edge);
- gw_src = e_route->src_gateway;
- gw_dst = e_route->dst_gateway;
-
- if(v==dst_node_id) first_gw = gw_dst;
-
- if(rc->hierarchy == SURF_ROUTING_RECURSIVE && v!=dst_node_id && 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);
- }
- size++;
- }
-
- if(rc->hierarchy == SURF_ROUTING_RECURSIVE) {
- new_e_route->src_gateway = xbt_strdup(gw_src);
- new_e_route->dst_gateway = xbt_strdup(first_gw);
- }
-
- if(routing->cached && elm == NULL) {
- /* add to predecessor list of the current src-host to cache */
- elm = xbt_new0(struct route_cache_element, 1);
- elm->pred_arr = pred_arr;
- elm->size = size;
- xbt_dict_set_ext(routing->route_cache, (char*)(&src_id), sizeof(int), (xbt_set_elm_t)elm, &route_cache_elem_free);
- }
-
- if(!routing->cached)
- xbt_free(pred_arr);
-
- return new_e_route;
-}
-
-static void dijkstra_finalize(routing_component_t rc) {
- routing_component_dijkstra_t routing = (routing_component_dijkstra_t) rc;
-
- if (routing) {
- xbt_graph_free_graph(routing->route_graph, &xbt_free, &graph_edge_data_free, &xbt_free);
- xbt_dict_free(&routing->graph_node_map);
- if(routing->cached)
- xbt_dict_free(&routing->route_cache);
- /* Delete bypass dict */
- xbt_dict_free(&routing->bypassRoutes);
- /* Delete index dict */
- xbt_dict_free(&(routing->to_index));
- /* Delete structure */
- xbt_free(routing);
- }
-}
-
-/* Creation routing model functions */
-
-static void* model_dijkstra_both_create(int cached) {
- routing_component_dijkstra_t new_component = xbt_new0(s_routing_component_dijkstra_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 = generic_set_route;
- new_component->generic_routing.set_ASroute = generic_set_ASroute;
- new_component->generic_routing.set_bypassroute = generic_set_bypassroute;
- new_component->generic_routing.get_route = dijkstra_get_route;
- new_component->generic_routing.get_onelink_routes = dijkstra_get_onelink_routes;
- new_component->generic_routing.is_router = dijkstra_is_router;
- new_component->generic_routing.get_bypass_route = generic_get_bypassroute;
- new_component->generic_routing.finalize = dijkstra_finalize;
- new_component->cached = cached;
- new_component->to_index = xbt_dict_new();
- new_component->bypassRoutes = xbt_dict_new();
- new_component->parse_routes = xbt_dict_new();
- return new_component;
-}
-
-static void* model_dijkstra_create(void) {
- return model_dijkstra_both_create(0);
-}
-
-static void* model_dijkstracache_create(void) {
- return model_dijkstra_both_create(1);
-}
-
-static void model_dijkstra_both_load(void) {
- /* use "surfxml_add_callback" to add a parse function call */
-}
-
-static void model_dijkstra_both_unload(void) {
- /* use "surfxml_del_callback" to remove a parse function call */
-}
-
-static void model_dijkstra_both_end(void) {
- routing_component_dijkstra_t routing = (routing_component_dijkstra_t) current_routing;
- xbt_dict_cursor_t cursor = NULL;
- char *key, *data, *end;
- const char *sep = "#";
- xbt_dynar_t keys;
- xbt_node_t node = NULL;
- unsigned int cursor2;
- xbt_dynar_t nodes = NULL;
- int src_id, dst_id;
- route_t route;
-
- /* Create the topology graph */
- routing->route_graph = xbt_graph_new_graph(1, NULL);
- routing->graph_node_map = xbt_dict_new();
-
- if(routing->cached)
- routing->route_cache = xbt_dict_new();
-
- /* Put the routes in position */
- xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
- keys = xbt_str_split_str(key, sep);
- src_id = strtol(xbt_dynar_get_as(keys, 0, char *), &end, 10);
- dst_id = strtol(xbt_dynar_get_as(keys, 1, char *), &end, 10);
- route_extended_t e_route = generic_new_extended_route(current_routing->hierarchy,data,0);
- route_new_dijkstra(routing,src_id,dst_id,e_route);
- xbt_dynar_free(&keys);
- }
-
- /* delete the parse table */
- xbt_dict_foreach(routing->parse_routes, cursor, key, data) {
- route = (route_t)data;
- xbt_dynar_free(&(route->link_list));
- xbt_free(data);
- }
-
- /* delete parse dict */
- xbt_dict_free(&(routing->parse_routes));
-
- /* Add the loopback if needed */
- if(current_routing->hierarchy == SURF_ROUTING_BASE)
- add_loopback_dijkstra(routing);
-
- /* initialize graph indexes in nodes after graph has been built */
- nodes = xbt_graph_get_nodes(routing->route_graph);
-
- xbt_dynar_foreach(nodes, cursor2, node) {
- graph_node_data_t data = xbt_graph_node_get_data(node);
- data->graph_id = cursor2;
- }
-
-}
-
-/* ************************************************** */
-/* ************** RULE-BASED ROUTING **************** */
-
-/* Routing model structure */
-
-typedef struct {
- s_routing_component_t generic_routing;
- xbt_dict_t dict_processing_units;
- xbt_dict_t dict_autonomous_systems;
- xbt_dynar_t list_route;
- xbt_dynar_t list_ASroute;
-} s_routing_component_rulebased_t,*routing_component_rulebased_t;
-
-typedef struct s_rule_route s_rule_route_t, *rule_route_t;
-typedef struct s_rule_route_extended s_rule_route_extended_t, *rule_route_extended_t;
-
-struct s_rule_route {
- xbt_dynar_t re_str_link; // dynar of char*
- pcre* re_src;
- pcre* re_dst;
-};
-
-struct s_rule_route_extended {
- s_rule_route_t generic_rule_route;
- char* re_src_gateway;
- char* re_dst_gateway;
-};
-
-static void rule_route_free(void *e) {
- rule_route_t* elem = (rule_route_t*)(e);
- if (*elem) {
- xbt_dynar_free(&(*elem)->re_str_link);
- pcre_free((*elem)->re_src);
- pcre_free((*elem)->re_dst);
- xbt_free((*elem));
- }
- (*elem) = NULL;
-}
-
-static void rule_route_extended_free(void *e) {
- rule_route_extended_t* elem = (rule_route_extended_t*)e;
- if (*elem) {
- xbt_dynar_free(&(*elem)->generic_rule_route.re_str_link);
- pcre_free((*elem)->generic_rule_route.re_src);
- pcre_free((*elem)->generic_rule_route.re_dst);
- xbt_free((*elem)->re_src_gateway);
- xbt_free((*elem)->re_dst_gateway);
- xbt_free((*elem));
- }
-}
-
-/* Parse routing model functions */
-
-static void model_rulebased_set_processing_unit(routing_component_t rc, const char* name) {
- routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
- xbt_dict_set(routing->dict_processing_units, name, (void*)(-1), NULL);
-}
-
-static void model_rulebased_set_autonomous_system(routing_component_t rc, const char* name) {
- routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
- xbt_dict_set(routing->dict_autonomous_systems, name, (void*)(-1), NULL);
-}
-
-static void model_rulebased_set_route(routing_component_t rc, const char* src, const char* dst, route_t route) {
- routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
- rule_route_t ruleroute = xbt_new0(s_rule_route_t,1);
- const char *error;
- int erroffset;
- ruleroute->re_src = pcre_compile(src,0,&error,&erroffset,NULL);
- xbt_assert3(ruleroute->re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, src, error);
- ruleroute->re_dst = pcre_compile(dst,0,&error,&erroffset,NULL);
- xbt_assert3(ruleroute->re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, dst, error);
- ruleroute->re_str_link = route->link_list;
- xbt_dynar_push(routing->list_route,&ruleroute);
- xbt_free(route);
-}
-
-static void model_rulebased_set_ASroute(routing_component_t rc, const char* src, const char* dst, route_extended_t route) {
- routing_component_rulebased_t routing = (routing_component_rulebased_t) rc;
- rule_route_extended_t ruleroute_e = xbt_new0(s_rule_route_extended_t,1);
- const char *error;
- int erroffset;
- ruleroute_e->generic_rule_route.re_src = pcre_compile(src,0,&error,&erroffset,NULL);
- xbt_assert3(ruleroute_e->generic_rule_route.re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, src, error);
- ruleroute_e->generic_rule_route.re_dst = pcre_compile(dst,0,&error,&erroffset,NULL);
- xbt_assert3(ruleroute_e->generic_rule_route.re_src,"PCRE compilation failed at offset %d (\"%s\"): %s\n", erroffset, dst, error);
- ruleroute_e->generic_rule_route.re_str_link = route->generic_route.link_list;
- ruleroute_e->re_src_gateway = route->src_gateway;
- ruleroute_e->re_dst_gateway = route->dst_gateway;
- xbt_dynar_push(routing->list_ASroute,&ruleroute_e);
- xbt_free(route->src_gateway);
- xbt_free(route->dst_gateway);
- xbt_free(route);
-}
-
-static void model_rulebased_set_bypassroute(routing_component_t rc, const char* src, const char* dst, route_extended_t e_route) {
- xbt_die("bypass routing not supported for Route-Based model");
-}
-
-#define BUFFER_SIZE 4096 /* result buffer size */
-#define OVECCOUNT 30 /* should be a multiple of 3 */
-
-static char* remplace(char* value, const char** src_list, int src_size, const char** dst_list, int dst_size ) {
-
- char result_result[BUFFER_SIZE];
- int i_result_buffer;
- int value_length = (int)strlen(value);
- int number=0;
-
- int i=0;
- i_result_buffer = 0;
- do {
- if( value[i] == '$' ) {
- i++; // skip $
-
- // find the number
- int number_length = 0;
- while( '0' <= value[i+number_length] && value[i+number_length] <= '9' ) {
- number_length++;
- }
- xbt_assert2( number_length!=0, "bad string parameter, no number indication, at offset: %d (\"%s\")",i,value);
-
- // solve number
- number = atoi(value+i);
- i=i+number_length;
- xbt_assert2(i+2<value_length,"bad string parameter, too few chars, at offset: %d (\"%s\")",i,value);
-
- // solve the indication
- const char** param_list;
- int param_size;
- if( value[i] == 's' && value[i+1] == 'r' && value[i+2] == 'c' ) {
- param_list = src_list;
- param_size = src_size;
- } else if( value[i] == 'd' && value[i+1] == 's' && value[i+2] == 't' ) {
- param_list = dst_list;
- param_size = dst_size;
- } else {
- xbt_assert2(0,"bad string parameter, support only \"src\" and \"dst\", at offset: %d (\"%s\")",i,value);
- }
- i=i+3;
-
- xbt_assert4( param_size >= number, "bad string parameter, not enough length param_size, at offset: %d (\"%s\") %d %d",i,value,param_size,number);
-
- const char* param = param_list[number];
- int size = strlen(param);
- int cp;
- for(cp = 0; cp < size; cp++ ) {
- result_result[i_result_buffer] = param[cp];
- i_result_buffer++;
- if( i_result_buffer >= BUFFER_SIZE ) break;
- }
- } else {
- result_result[i_result_buffer] = value[i];
- i_result_buffer++;
- i++; // next char
- }
-
- } while(i<value_length && i_result_buffer < BUFFER_SIZE);
-
- xbt_assert2( i_result_buffer < BUFFER_SIZE, "solving string \"%s\", small buffer size (%d)",value,BUFFER_SIZE);
- result_result[i_result_buffer] = 0;
- return xbt_strdup(result_result);
-}
-
-static xbt_dynar_t rulebased_get_onelink_routes(routing_component_t rc)
-{
- xbt_die("\"rulebased_get_onelink_routes\" function not implemented yet");
-}