+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 support 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);
+}