diff --git a/src/pathcomp/backend/pathComp_RESTapi.c b/src/pathcomp/backend/pathComp_RESTapi.c index 1780cfde2039b5907ab0f5696885e17deb56644c..5e22136e7dd753cdf2a7f4a66289be740accb2a7 100644 --- a/src/pathcomp/backend/pathComp_RESTapi.c +++ b/src/pathcomp/backend/pathComp_RESTapi.c @@ -281,7 +281,6 @@ void add_comp_path_deviceId_endpointId_json(cJSON* pathObj, struct path_t* p, st return; } - //////////////////////////////////////////////////////////////////////////////////////// /** * @file pathComp_RESTapi.c @@ -812,12 +811,18 @@ void parsing_json_serviceList_array(cJSON* serviceArray) { parse_service_constraints(constraintArray, service); } - // Get the maximum number of paths to be computed (kPaths) - cJSON* kPathsObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths"); - if (cJSON_IsNumber(kPathsObj)){ - service->kPaths = (guint)(kPathsObj->valuedouble); + // Get the maximum number of paths to be computed (kPaths) inspected/explored + cJSON* kPathsInspObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_inspection"); + if (cJSON_IsNumber(kPathsInspObj)){ + service->kPaths_inspected = (guint)(kPathsInspObj->valuedouble); } + // Get the maximum number of paths to be computed (kPaths) returned + cJSON* kPathsRetpObj = cJSON_GetObjectItemCaseSensitive(item, "kPaths_return"); + if (cJSON_IsNumber(kPathsRetpObj)){ + service->kPaths_returned = (guint)(kPathsRetpObj->valuedouble); + } + // Append the requested service to the serviceList serviceList = g_list_append(serviceList, service); } diff --git a/src/pathcomp/backend/pathComp_ksp.c b/src/pathcomp/backend/pathComp_ksp.c index 00ebaf5b8b7e0a888720a4092a0d23d75a3eb04b..f5e3c8fb8ea854c9acc9fb9f8bc00e3f34a3141a 100644 --- a/src/pathcomp/backend/pathComp_ksp.c +++ b/src/pathcomp/backend/pathComp_ksp.c @@ -63,15 +63,14 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { gint i = 0; for (GList* listnode = g_list_first(serviceList); listnode; - listnode = g_list_next(listnode), i++){ - //struct service_t* service = &(serviceList->services[i]); + listnode = g_list_next(listnode), i++){ struct service_t* service = (struct service_t*)(listnode->data); DEBUG_PC("Starting the Computation for ServiceId: %s [ContextId: %s]", service->serviceId.service_uuid, service->serviceId.contextId); struct compRouteOutput_t* pathService = &(outputList->compRouteConnection[i]); // check endpoints of the service are different (PE devices/nodes are different) if (same_src_dst_pe_nodeid(service) == 0) { - DEBUG_PC("PEs are the same... no path computation"); + DEBUG_PC("PEs are the same... NO PATH COMPUTATION"); comp_route_connection_issue_handler(pathService, service); outputList->numCompRouteConnList++; continue; @@ -84,6 +83,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { outputList->numCompRouteConnList++; continue; } + alg_comp(service, pathService, g, NO_OPTIMIZATION_ARGUMENT); // last parameter 0 is related to an optimization computation argument outputList->numCompRouteConnList++; @@ -92,7 +92,8 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { if (pathService->noPathIssue == NO_PATH_CONS_ISSUE) { continue; } - struct path_t* path = &(pathService->paths[pathService->numPaths - 1]); + // Out of the comnputed paths for the pathservice, the first one is chosen to be locally allocated + struct path_t* path = &(pathService->paths[0]); allocate_graph_resources(path, service, g); allocate_graph_reverse_resources(path, service, g); print_graph(g); @@ -111,8 +112,7 @@ void ksp_alg_execution_services(struct compRouteOutputList_t* outputList) { * @date 2022 */ ///////////////////////////////////////////////////////////////////////////////////////// -gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) -{ +gint pathComp_ksp_alg(struct compRouteOutputList_t * routeConnList) { g_assert(routeConnList); gint numSuccesPathComp = 0, numPathCompIntents = 0; diff --git a/src/pathcomp/backend/pathComp_tools.c b/src/pathcomp/backend/pathComp_tools.c index 321821f45ea54d1208fd0fa32b3c2f8201616b38..e5d4ac846b42c7d0d18532a6d3555b8fc689f382 100644 --- a/src/pathcomp/backend/pathComp_tools.c +++ b/src/pathcomp/backend/pathComp_tools.c @@ -3221,6 +3221,18 @@ void set_path_attributes(struct compRouteOutputItem_t* p, struct map_t* mapV) { void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_t* g, guint arg) { g_assert(s); g_assert(path); g_assert(g); + // Check if the service specifies a nuumber of K paths to be explored/computed for the + // service. If not, compute that number; otherwise set the max number of explored + // computed paths to MAX_KSP_VALUE + guint maxK = 0; + if(s->kPaths_inspected == 0) { + maxK = MAX_KSP_VALUE; + } + else { + maxK = s->kPaths_inspected; + } + DEBUG_PC("The KSP considers K: %d", maxK); + // create map of devices/nodes to handle the path computation using the context struct map_nodes_t* mapNodes = create_map_node(); build_map_node(mapNodes, g); @@ -3265,14 +3277,14 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ } path->num_service_endpoints_id = s->num_service_endpoints_id; - DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", MAX_KSP_VALUE); + DEBUG_PC("COMPUTE UP TO K Feasible Paths A[%d]", maxK); // Create A and B sets of paths to handle the YEN algorithm struct path_set_t *A = create_path_set(), *B = create_path_set(); // Add 1st Computed path into A->paths[0] duplicate_path(p, &A->paths[0]); A->numPaths++; g_free(predecessors); g_free(p); - for (gint k = 1; k < MAX_KSP_VALUE; k++) { + for (gint k = 1; k < maxK; k++) { DEBUG_PC("*************************** kth (%d) ***********************************", k); struct compRouteOutputItem_t* p = create_path_item(); duplicate_path(&A->paths[k - 1], p); @@ -3377,8 +3389,8 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ DEBUG_PC("Number of paths: %d", path->numPaths); // For all the computed paths in A, pick the one being feasible wrt the service constraints for (gint ksp = 0; ksp < A->numPaths; ksp++) { - if (ksp >= MAX_KSP_VALUE) { - DEBUG_PC("Number Requested paths (%d) REACHED - STOP", ksp); + if (ksp >= s->kPaths_returned) { + DEBUG_PC("Number Requested/returned paths (%d) REACHED - STOP", ksp); break; } gdouble feasibleRoute = check_computed_path_feasibility(s, &A->paths[ksp]); @@ -3390,13 +3402,18 @@ void alg_comp(struct service_t* s, struct compRouteOutput_t* path, struct graph_ struct path_t* targetedPath = &path->paths[path->numPaths - 1]; duplicate_path_t(pathaux, targetedPath); print_path_t(targetedPath); - remove_path_set(A); - remove_path_set(B); - return; + //remove_path_set(A); + //remove_path_set(B); + //return; } } remove_path_set(A); remove_path_set(B); + // At least 1 out (K) paths was found, then K-SP succeded + if (path->numPaths > 0) { + DEBUG_PC("K-SP succeeded"); + return; + } // No paths found --> Issue DEBUG_PC("K-SP failed!!!"); comp_route_connection_issue_handler(path, s); diff --git a/src/pathcomp/backend/pathComp_tools.h b/src/pathcomp/backend/pathComp_tools.h index fb458d8c0d75940ddd72e5c8255cc68fafaa7296..fde38f66b75506d16321911607df0ff9f05dcd9d 100644 --- a/src/pathcomp/backend/pathComp_tools.h +++ b/src/pathcomp/backend/pathComp_tools.h @@ -354,11 +354,10 @@ struct constraint_t { #define MAX_NUM_SERVICE_ENPOINTS_ID 2 #define MAX_NUM_SERVICE_CONSTRAINTS 10 -struct service_t { - // Indentifier used to determine the used Algorithm Id, e.g., KSP - gchar algId[MAX_ALG_ID_LENGTH]; - // PATHS expected for the output - guint kPaths; +struct service_t { + gchar algId[MAX_ALG_ID_LENGTH]; // Indentifier used to determine the used Algorithm Id, e.g., KSP + guint kPaths_inspected; // PATHS expected to be inspected + guint kPaths_returned; // Maximum number of PATHS to be returned struct serviceId_t serviceId; guint service_type; // unknown, l2nm, l3nm, tapi @@ -432,7 +431,7 @@ struct pathLink_t { gchar zEndPointId[UUID_CHAR_LENGTH]; struct topology_id_t topologyId; - struct linkTopology_t linkTopologies[2]; // a p2p link (at most) can connect to devices (endpoints) attached to 2 different topologies + struct linkTopology_t linkTopologies[2]; // A p2p link (at most) can connect to devices (endpoints) attached to 2 different topologies gint numLinkTopologies; };