- }
-
- /* 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");