Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Actually, every AS can have bypass routes
authorMartin Quinson <martin.quinson@loria.fr>
Sat, 20 Feb 2016 02:31:52 +0000 (03:31 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Sat, 20 Feb 2016 11:36:36 +0000 (12:36 +0100)
I recently moved it down in the hierarchy to AsRoutedGraph, but there
is no reason for that. Moving it back to As, and making it non-virtual.

(+ use std::containers instead of XBT ones)

src/surf/surf_routing.cpp
src/surf/surf_routing.hpp
src/surf/surf_routing_RoutedGraph.cpp
src/surf/surf_routing_RoutedGraph.hpp
src/surf/surfxml_parse.cpp

index 6b7959a..4c8b00f 100644 (file)
@@ -21,6 +21,8 @@
 #include "src/surf/surf_routing_full.hpp"
 #include "src/surf/surf_routing_vivaldi.hpp"
 
+#include <vector>
+
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
 
 namespace simgrid {
@@ -38,6 +40,10 @@ namespace surf {
     xbt_dict_free(&sons_);
     xbt_dynar_free(&vertices_);
     xbt_dynar_free(&upDownLinks);
+    if (nullptr != bypassRoutes_)
+      for (auto &kv : *bypassRoutes_)
+        delete kv.second;
+    delete bypassRoutes_;
     xbt_free(name_);
     delete netcard_;
   }
@@ -46,9 +52,6 @@ namespace surf {
     sealed_ = true;
   }
 
-  sg_platf_route_cbarg_t As::getBypassRoute(NetCard * /*src*/, NetCard * /*dst*/, double * /*lat*/) {
-    return NULL;
-  }
   xbt_dynar_t As::getOneLinkRoutes() {
     return NULL;
   }
@@ -62,8 +65,151 @@ namespace surf {
   void As::addRoute(sg_platf_route_cbarg_t /*route*/){
     xbt_die("AS %s does not accept new routes (wrong class).",name_);
   }
-  void As::addBypassRoute(sg_platf_route_cbarg_t /*e_route*/){
-    xbt_die("AS %s does not accept new bypass routes (wrong class).",name_);
+
+  std::vector<Link*> *As::getBypassRoute(NetCard *src, NetCard *dst)
+  {
+    // If never set a bypass route return NULL without any further computations
+    XBT_DEBUG("generic_get_bypassroute from %s to %s", src->name(), dst->name());
+    if (bypassRoutes_ == nullptr)
+      return nullptr;
+
+    std::vector<Link*> *bypassedRoute = nullptr;
+
+    if(dst->containingAS() == this && src->containingAS() == this ){
+      char *route_name = bprintf("%s#%s", src->name(), dst->name());
+      if (bypassRoutes_->find(route_name) != bypassRoutes_->end()) {
+        bypassedRoute = bypassRoutes_->at(route_name);
+        XBT_DEBUG("Found a bypass route with %ld links",bypassedRoute->size());
+      }
+      free(route_name);
+      return bypassedRoute;
+    }
+
+    int index_src, index_dst;
+    As **current_src = NULL;
+    As **current_dst = NULL;
+
+    As *src_as = src->containingAS();
+    As *dst_as = dst->containingAS();
+
+    /* (2) find the path to the root routing component */
+    xbt_dynar_t path_src = xbt_dynar_new(sizeof(As*), NULL);
+    As *current = src_as;
+    while (current != NULL) {
+      xbt_dynar_push(path_src, &current);
+      current = current->father_;
+    }
+    xbt_dynar_t path_dst = xbt_dynar_new(sizeof(As*), NULL);
+    current = dst_as;
+    while (current != NULL) {
+      xbt_dynar_push(path_dst, &current);
+      current = current->father_;
+    }
+
+    /* (3) find the common father */
+    index_src = path_src->used - 1;
+    index_dst = path_dst->used - 1;
+    current_src = (As **) xbt_dynar_get_ptr(path_src, index_src);
+    current_dst = (As **) xbt_dynar_get_ptr(path_dst, index_dst);
+    while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
+      xbt_dynar_pop_ptr(path_src);
+      xbt_dynar_pop_ptr(path_dst);
+      index_src--;
+      index_dst--;
+      current_src = (As **) xbt_dynar_get_ptr(path_src, index_src);
+      current_dst = (As **) xbt_dynar_get_ptr(path_dst, index_dst);
+    }
+
+    int max_index_src = path_src->used - 1;
+    int max_index_dst = path_dst->used - 1;
+
+    int max_index = std::max(max_index_src, max_index_dst);
+
+    for (int max = 0; max <= max_index; max++) {
+      for (int i = 0; i < max; i++) {
+        if (i <= max_index_src && max <= max_index_dst) {
+          char *route_name = bprintf("%s#%s",
+              (*(As **) (xbt_dynar_get_ptr(path_src, i)))->name_,
+              (*(As **) (xbt_dynar_get_ptr(path_dst, max)))->name_);
+          if (bypassRoutes_->find(route_name) != bypassRoutes_->end())
+            bypassedRoute = bypassRoutes_->at(route_name);
+          xbt_free(route_name);
+        }
+        if (bypassedRoute)
+          break;
+        if (max <= max_index_src && i <= max_index_dst) {
+          char *route_name = bprintf("%s#%s",
+              (*(As **) (xbt_dynar_get_ptr(path_src, max)))->name_,
+              (*(As **) (xbt_dynar_get_ptr(path_dst, i)))->name_);
+          if (bypassRoutes_->find(route_name) != bypassRoutes_->end())
+            bypassedRoute = bypassRoutes_->at(route_name);
+          xbt_free(route_name);
+        }
+        if (bypassedRoute)
+          break;
+      }
+
+      if (bypassedRoute)
+        break;
+
+      if (max <= max_index_src && max <= max_index_dst) {
+        char *route_name = bprintf("%s#%s",
+            (*(As **) (xbt_dynar_get_ptr(path_src, max)))->name_,
+            (*(As **) (xbt_dynar_get_ptr(path_dst, max)))->name_);
+
+        if (bypassRoutes_->find(route_name) != bypassRoutes_->end())
+          bypassedRoute = bypassRoutes_->at(route_name);
+        xbt_free(route_name);
+      }
+      if (bypassedRoute)
+        break;
+    }
+
+    xbt_dynar_free(&path_src);
+    xbt_dynar_free(&path_dst);
+
+    return bypassedRoute;
+  }
+
+  void As::addBypassRoute(sg_platf_route_cbarg_t e_route){
+    const char *src = e_route->src;
+    const char *dst = e_route->dst;
+
+    if(bypassRoutes_ == nullptr)
+      bypassRoutes_ = new std::map<std::string, std::vector<Link*>*>();
+
+    char *route_name = bprintf("%s#%s", src, dst);
+
+    /* Argument validity checks */
+    if (e_route->gw_dst) {
+      XBT_DEBUG("Load bypassASroute from %s@%s to %s@%s",
+          src, e_route->gw_src->name(), dst, e_route->gw_dst->name());
+      xbt_assert(!xbt_dynar_is_empty(e_route->link_list), "Bypass route between %s@%s and %s@%s cannot be empty.",
+          src, e_route->gw_src->name(), dst, e_route->gw_dst->name());
+      xbt_assert(bypassRoutes_->find(route_name) == bypassRoutes_->end(),
+          "The bypass route between %s@%s and %s@%s already exists.",
+          src, e_route->gw_src->name(), dst, e_route->gw_dst->name());
+    } else {
+      XBT_DEBUG("Load bypassRoute from %s to %s", src, dst);
+      xbt_assert(!xbt_dynar_is_empty(e_route->link_list),                 "Bypass route between %s and %s cannot be empty.",    src, dst);
+      xbt_assert(bypassRoutes_->find(route_name) == bypassRoutes_->end(), "The bypass route between %s and %s already exists.", src, dst);
+    }
+
+    /* Build the value that will be stored in the dict */
+    std::vector<Link*> *newRoute = new std::vector<Link*>();
+    char *linkName;
+    unsigned int cpt;
+    xbt_dynar_foreach(e_route->link_list, cpt, linkName) {
+      Link *link = Link::byName(linkName);
+      if (link)
+        newRoute->push_back(link);
+      else
+        THROWF(mismatch_error, 0, "Link '%s' not found", linkName);
+    }
+
+    /* Store it */
+    bypassRoutes_->insert({route_name, newRoute});
+    xbt_free(route_name);
   }
 
 }} // namespace simgrid::surf
@@ -332,10 +478,13 @@ static void _get_route_and_latency(simgrid::surf::NetCard *src, simgrid::surf::N
       common_father->name_, src_father->name_, dst_father->name_);
 
   /* Check whether a direct bypass is defined. If so, use it and bail out */
-  sg_platf_route_cbarg_t bypassed_route = common_father->getBypassRoute(src, dst, latency);
-  if (bypassed_route) {
-    xbt_dynar_merge(links, &bypassed_route->link_list);
-    routing_route_free(bypassed_route);
+  std::vector<Link*> *bypassed_route = common_father->getBypassRoute(src, dst);
+  if (nullptr != bypassed_route) {
+    for (Link *link : *bypassed_route) {
+      xbt_dynar_push(*links,&link);
+      if (latency)
+        *latency += link->getLatency();
+    }
     return;
   }
 
index 062c173..5671de1 100644 (file)
@@ -13,6 +13,9 @@
 #include "surf_interface.hpp"
 #include <float.h>
 
+#include <vector>
+#include <map>
+
 XBT_PUBLIC(void) routing_model_create( void *loopback);
 
 namespace simgrid {
@@ -64,6 +67,7 @@ public:
 
 private:
   bool sealed_ = false; // We cannot add more content when sealed
+  std::map<std::string, std::vector<Link*>*> *bypassRoutes_ = nullptr;
 
 public:
   /**
@@ -96,12 +100,12 @@ public:
 
   virtual void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)=0;
 
-  virtual sg_platf_route_cbarg_t getBypassRoute(NetCard *src, NetCard *dst,double *lat);
+  std::vector<Link*> *getBypassRoute(NetCard *src, NetCard *dst);
 
   /* Add content to the AS, at parsing time. It should be sealed afterward. */
   virtual int addComponent(NetCard *elm); /* A host, a router or an AS, whatever */
   virtual void addRoute(sg_platf_route_cbarg_t route);
-  virtual void addBypassRoute(sg_platf_route_cbarg_t e_route);
+  void addBypassRoute(sg_platf_route_cbarg_t e_route);
 };
 
 struct XBT_PRIVATE NetCardImpl : public NetCard {
index 0bfcb66..b4bb652 100644 (file)
@@ -41,43 +41,8 @@ AsRoutedGraph::AsRoutedGraph(const char*name)
 
 AsRoutedGraph::~AsRoutedGraph()
 {
-  xbt_dict_free(&bypassRoutes_);
 }
 
-void AsRoutedGraph::addBypassRoute(sg_platf_route_cbarg_t e_route)
-{
-  char *src = (char*)(e_route->src);
-  char *dst = (char*)(e_route->dst);
-
-  if(bypassRoutes_ == nullptr)
-    bypassRoutes_ = xbt_dict_new_homogeneous((void (*)(void *)) routing_route_free);
-
-  if(e_route->gw_dst)
-    XBT_DEBUG("Load bypassASroute from \"%s\" to \"%s\"", src, dst);
-  else
-    XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
-  xbt_dict_t dict_bypassRoutes = bypassRoutes_;
-  char *route_name;
-
-  route_name = bprintf("%s#%s", src, dst);
-  xbt_assert(!xbt_dynar_is_empty(e_route->link_list),
-      "Invalid count of links, must be greater than zero (%s,%s)",
-      src, dst);
-  xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
-      "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
-      src, e_route->gw_src->name(), dst, e_route->gw_dst->name());
-
-  sg_platf_route_cbarg_t new_e_route = NULL;
-  if(e_route->gw_dst)
-    new_e_route =  newExtendedRoute(SURF_ROUTING_RECURSIVE, e_route, 1);
-  else
-    new_e_route =  newExtendedRoute(SURF_ROUTING_BASE, e_route, 1);
-
-  xbt_dynar_free(&(e_route->link_list));
-
-  xbt_dict_set(dict_bypassRoutes, route_name, new_e_route, NULL);
-  xbt_free(route_name);
-}
 
 }
 }
@@ -196,130 +161,6 @@ void AsRoutedGraph::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edg
   }
 }
 
-sg_platf_route_cbarg_t AsRoutedGraph::getBypassRoute(NetCard *src, NetCard *dst, double *lat)
-{
-  // If never set a bypass route return NULL without any further computations
-  XBT_DEBUG("generic_get_bypassroute from %s to %s", src->name(), dst->name());
-  if (bypassRoutes_ == nullptr)
-    return NULL;
-
-  sg_platf_route_cbarg_t e_route_bypass = NULL;
-
-  if(dst->containingAS() == this && src->containingAS() == this ){
-    char *route_name = bprintf("%s#%s", src->name(), dst->name());
-    e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(bypassRoutes_, route_name);
-    if(e_route_bypass)
-      XBT_DEBUG("Find bypass route with %ld links",xbt_dynar_length(e_route_bypass->link_list));
-    free(route_name);
-  }
-  else{
-    As *src_as, *dst_as;
-    int index_src, index_dst;
-    xbt_dynar_t path_src = NULL;
-    xbt_dynar_t path_dst = NULL;
-    As *current = NULL;
-    As **current_src = NULL;
-    As **current_dst = NULL;
-
-    if (src == NULL || dst == NULL)
-      xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
-              src ? src->name() : "(null)",
-              dst ? dst->name() : "(null)", name_);
-
-    src_as = src->containingAS();
-    dst_as = dst->containingAS();
-
-    /* (2) find the path to the root routing component */
-    path_src = xbt_dynar_new(sizeof(As*), NULL);
-    current = src_as;
-    while (current != NULL) {
-      xbt_dynar_push(path_src, &current);
-      current = current->father_;
-    }
-    path_dst = xbt_dynar_new(sizeof(As*), NULL);
-    current = dst_as;
-    while (current != NULL) {
-      xbt_dynar_push(path_dst, &current);
-      current = current->father_;
-    }
-
-    /* (3) find the common father */
-    index_src = path_src->used - 1;
-    index_dst = path_dst->used - 1;
-    current_src = (As **) xbt_dynar_get_ptr(path_src, index_src);
-    current_dst = (As **) xbt_dynar_get_ptr(path_dst, index_dst);
-    while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
-      xbt_dynar_pop_ptr(path_src);
-      xbt_dynar_pop_ptr(path_dst);
-      index_src--;
-      index_dst--;
-      current_src = (As **) xbt_dynar_get_ptr(path_src, index_src);
-      current_dst = (As **) xbt_dynar_get_ptr(path_dst, index_dst);
-    }
-
-    int max_index_src = path_src->used - 1;
-    int max_index_dst = path_dst->used - 1;
-
-    int max_index = std::max(max_index_src, max_index_dst);
-
-    for (int max = 0; max <= max_index; max++) {
-      for (int i = 0; i < max; i++) {
-        if (i <= max_index_src && max <= max_index_dst) {
-          char *route_name = bprintf("%s#%s",
-              (*(As **) (xbt_dynar_get_ptr(path_src, i)))->name_,
-              (*(As **) (xbt_dynar_get_ptr(path_dst, max)))->name_);
-          e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(bypassRoutes_, route_name);
-          xbt_free(route_name);
-        }
-        if (e_route_bypass)
-          break;
-        if (max <= max_index_src && i <= max_index_dst) {
-          char *route_name = bprintf("%s#%s",
-              (*(As **) (xbt_dynar_get_ptr(path_src, max)))->name_,
-              (*(As **) (xbt_dynar_get_ptr(path_dst, i)))->name_);
-          e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(bypassRoutes_, route_name);
-          xbt_free(route_name);
-        }
-        if (e_route_bypass)
-          break;
-      }
-
-      if (e_route_bypass)
-        break;
-
-      if (max <= max_index_src && max <= max_index_dst) {
-        char *route_name = bprintf("%s#%s",
-            (*(As **) (xbt_dynar_get_ptr(path_src, max)))->name_,
-            (*(As **) (xbt_dynar_get_ptr(path_dst, max)))->name_);
-        e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(bypassRoutes_, route_name);
-        xbt_free(route_name);
-      }
-      if (e_route_bypass)
-        break;
-    }
-
-    xbt_dynar_free(&path_src);
-    xbt_dynar_free(&path_dst);
-  }
-
-  sg_platf_route_cbarg_t new_e_route = NULL;
-  if (e_route_bypass) {
-    Link* link;
-    unsigned int cpt = 0;
-    new_e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
-    new_e_route->gw_src = e_route_bypass->gw_src;
-    new_e_route->gw_dst = e_route_bypass->gw_dst;
-    new_e_route->link_list =
-        xbt_dynar_new(sizeof(Link*), NULL);
-    xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
-      xbt_dynar_push(new_e_route->link_list, &link);
-      if (lat)
-        *lat += link->getLatency();
-    }
-  }
-
-  return new_e_route;
-}
 
 /* ************************************************************************** */
 /* ************************* GENERIC AUX FUNCTIONS ************************** */
index 3de0bfc..9d5c7db 100644 (file)
@@ -22,17 +22,10 @@ public:
   ~AsRoutedGraph();
 
   virtual void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) override;
-  virtual sg_platf_route_cbarg_t getBypassRoute(NetCard *src, NetCard *dst, double *lat) override;
-
-  /* Add content to the AS, at parsing time */
-  virtual void addBypassRoute(sg_platf_route_cbarg_t e_route) override;
-
   virtual sg_platf_route_cbarg_t newExtendedRoute(e_surf_routing_hierarchy_t hierarchy, sg_platf_route_cbarg_t routearg, int change_order);
 protected:
   void getRouteCheckParams(NetCard *src, NetCard *dst);
   void addRouteCheckParams(sg_platf_route_cbarg_t route);
-private:
-  xbt_dict_t bypassRoutes_ = nullptr;;
 };
 
 }
index a0c9a43..382d772 100644 (file)
@@ -827,7 +827,7 @@ void ETag_surfxml_bypassRoute(void){
   route.symmetrical = FALSE;
 
   sg_platf_new_bypassRoute(&route);
-  parsed_link_list = NULL;
+  xbt_dynar_free(&parsed_link_list);
 }
 
 void ETag_surfxml_bypassASroute(void){
@@ -843,7 +843,7 @@ void ETag_surfxml_bypassASroute(void){
   ASroute.gw_dst = sg_netcard_by_name_or_null(A_surfxml_bypassASroute_gw___dst);
 
   sg_platf_new_bypassRoute(&ASroute);
-  parsed_link_list = NULL;
+  xbt_dynar_free(&parsed_link_list);
 }
 
 void ETag_surfxml_trace(void){