+ /* (2) find the path to the root routing component */
+ std::vector<AsImpl*> path_src;
+ AsImpl* current = src->containingAS();
+ while (current != nullptr) {
+ path_src.push_back(current);
+ current = static_cast<AsImpl*>(current->father());
+ }
+ std::vector<AsImpl*> path_dst;
+ current = dst->containingAS();
+ while (current != nullptr) {
+ path_dst.push_back(current);
+ current = static_cast<AsImpl*>(current->father());
+ }
+
+ /* (3) find the common father.
+ * Before that, index_src and index_dst may be different, they both point to nullptr in path_src/path_dst
+ * So we move them down simultaneously as long as they point to the same content.
+ *
+ * This works because all SimGrid platform have a unique root element (that is the last element of both paths).
+ */
+ AsImpl* father = nullptr; // the AS we dropped on the previous loop iteration
+ while (path_src.size() > 1 && path_dst.size() > 1 &&
+ path_src.at(path_src.size() - 1) == path_dst.at(path_dst.size() - 1)) {
+ father = path_src.at(path_src.size() - 1);
+ path_src.pop_back();
+ path_dst.pop_back();
+ }
+
+ /* (4) we found the difference at least. Finalize the returned values */
+ *src_ancestor = path_src.at(path_src.size() - 1); /* the first different father of src */
+ *dst_ancestor = path_dst.at(path_dst.size() - 1); /* the first different father of dst */
+ if (*src_ancestor == *dst_ancestor) { // src is the ancestor of dst, or the contrary
+ *common_ancestor = *src_ancestor;
+ } else {
+ *common_ancestor = father;
+ }
+ }
+
+ /* PRECONDITION: this is the common ancestor of src and dst */
+ bool AsImpl::getBypassRoute(routing::NetCard* src, routing::NetCard* dst,
+ /* OUT */ std::vector<surf::Link*>* links, double* latency)
+ {
+ // If never set a bypass route return nullptr without any further computations
+ if (bypassRoutes_.empty())
+ return false;
+
+ /* Base case, no recursion is needed */
+ if (dst->containingAS() == this && src->containingAS() == this) {
+ if (bypassRoutes_.find({src, dst}) != bypassRoutes_.end()) {
+ AsRoute* bypassedRoute = bypassRoutes_.at({src, dst});
+ for (surf::Link* link : bypassedRoute->links) {
+ links->push_back(link);
+ if (latency)
+ *latency += link->latency();