From 277a638bf1d27ba6c3da37ff82d2fd06e718e7ca Mon Sep 17 00:00:00 2001 From: Aleksandar Donchev Date: Mon, 23 Jan 2017 15:18:21 +0100 Subject: * Max count of the returned routes and max allowed domain cycles Signed-off-by: Christian Linke --- AudioManagerCore/include/CAmGraph.h | 129 +++-- AudioManagerCore/include/CAmRouter.h | 172 ++++--- AudioManagerCore/src/CAmRouter.cpp | 518 +++++++++++++-------- .../test/AmRouterMapTest/CAmRouterMapTest.cpp | 271 ++++++++--- .../test/AmRouterMapTest/CAmRouterMapTest.h | 10 +- 5 files changed, 723 insertions(+), 377 deletions(-) diff --git a/AudioManagerCore/include/CAmGraph.h b/AudioManagerCore/include/CAmGraph.h index ff4a09c..a27d512 100644 --- a/AudioManagerCore/include/CAmGraph.h +++ b/AudioManagerCore/include/CAmGraph.h @@ -89,6 +89,7 @@ namespace am * Setters and getters. */ NodeData & getData() { return mData; } + const NodeData & getData() const { return mData; } uint16_t getIndex() const { return mIndex; } void setIndex(uint16_t index) { mIndex = index; } }; @@ -120,13 +121,13 @@ namespace am typedef typename std::vector*> CAmListNodePtrs; typedef typename std::list> CAmListVertices; typedef typename std::list>::iterator CAmListVerticesItr; - typedef typename std::list>::const_iterator CAmListVerticesItrConst; - typedef typename std::list CAmNodesAdjList; - typedef typename std::list::iterator CAmNodesAdjListItr; - typedef typename std::list::const_iterator CAmNodesAdjListItrConst; - typedef typename std::list> CAmListNodes; - typedef typename std::list>::iterator CAmListNodesItr; - typedef typename std::list>::const_iterator CAmListNodesItrConst; + typedef typename std::list>::const_iterator CAmListVerticesItrConst; + typedef typename std::list CAmNodesAdjList; + typedef typename std::list::iterator CAmNodesAdjListItr; + typedef typename std::list::const_iterator CAmNodesAdjListItrConst; + typedef typename std::list> CAmListNodes; + typedef typename std::list>::iterator CAmListNodesItr; + typedef typename std::list>::const_iterator CAmListNodesItrConst; typedef typename std::vector*> CAmNodeReferenceList; typedef typename std::vector CAmVertexReferenceList; @@ -136,6 +137,24 @@ namespace am CAmVertexReferenceList mPointersAdjList; //!< CAmVertexReferenceList vector with pointers to vertices for direct access bool mIsCyclic; //!< bool the graph has cycles or not + struct IterateThroughAllNodesDelegate + { + CAmNode * source; + CAmNode * destination; + CAmNodeReferenceList visited; + std::function * )> shouldVisitNode; + std::function *)> willVisitNode; + std::function *)> didVisitNode; + std::function didFindPath; + }; + + struct VisitNodeDelegate + { + CAmNode * source; + CAmNode * destination; + std::function &)> visitedNode; + }; + /** * Updates the node indexes after adding or removing nodes. * @@ -162,7 +181,7 @@ namespace am typedef uint16_t vertex_t; typedef uint16_t weight_t; - void findShortestsPathsFromNode(const CAmNode & node, std::vector &minDistance, std::vector *> &previous) + void findShortestPathsFromNode(const CAmNode & node, std::vector &minDistance, std::vector *> &previous) { typename CAmListVertices::const_iterator nIter; CAmListVertices * neighbors; @@ -256,32 +275,40 @@ namespace am } /** - * Generates list with all possible paths to given destination node after findShortestsPathsFromNode has been called. - * Finding paths is observed through the callback. The caller is informed after a new path has been found. + * Iterate through the nodes and generate all paths to given node. * * @param dst end node. * @param visited vector with current path. - * @param cb callback which is mostly used for constructing. + * @param delegate enumeration delegate. */ - void goThroughAllPaths(const CAmNode & dst, std::vector*> & visited, std::function cb) + void findAllPaths(IterateThroughAllNodesDelegate & delegate) { - CAmListVertices * nodes = mPointersAdjList[visited.back()->getIndex()]; + CAmListVertices * nodes = mPointersAdjList[delegate.visited.back()->getIndex()]; CAmListVerticesItrConst vItr(nodes->begin()); + + CAmVertex * pNextVertex; + CAmNode * pNextNode; for (; vItr != nodes->end(); ++vItr) { - const CAmVertex & vertex = (*vItr); - if(vertex.getNode()->getStatus()!=GES_NOT_VISITED) + pNextVertex = (CAmVertex *)&(*vItr); + pNextNode = pNextVertex->getNode(); + if( + pNextNode->getStatus()!=GES_NOT_VISITED || + !delegate.shouldVisitNode(pNextNode) + ) continue; - if (vertex.getNode()==&dst) + if (pNextNode==delegate.destination) { - vertex.getNode()->setStatus(GES_IN_PROGRESS); - visited.push_back(vertex.getNode()); + delegate.willVisitNode(pNextNode); + pNextNode->setStatus(GES_IN_PROGRESS); + delegate.visited.push_back(pNextNode); //notify observer - cb(visited); + delegate.didFindPath(delegate.visited); //remove last node from the list - auto last = visited.end()-1; - visited.erase(last); - vertex.getNode()->setStatus(GES_NOT_VISITED); + auto last = delegate.visited.end()-1; + delegate.visited.erase(last); + pNextNode->setStatus(GES_NOT_VISITED); + delegate.didVisitNode(pNextNode); break; } } @@ -289,20 +316,28 @@ namespace am //bfs like loop for (; vItr != nodes->end(); ++vItr) { - const CAmVertex & vertex = (*vItr); - if(vertex.getNode()->getStatus()!=GES_NOT_VISITED||vertex.getNode()==&dst) + pNextVertex = (CAmVertex *)&(*vItr); + pNextNode = pNextVertex->getNode(); + + if(pNextNode->getStatus()!=GES_NOT_VISITED || + pNextNode==delegate.destination || + !delegate.shouldVisitNode(pNextNode) + ) continue; - vertex.getNode()->setStatus(GES_IN_PROGRESS); - visited.push_back(vertex.getNode()); - goThroughAllPaths(dst, visited, cb); + delegate.willVisitNode(pNextNode); + pNextNode->setStatus(GES_IN_PROGRESS); + delegate.visited.push_back(pNextNode); + findAllPaths(delegate); //remove last node from the list - auto last = visited.end()-1; - visited.erase(last); - vertex.getNode()->setStatus(GES_NOT_VISITED); + auto last = delegate.visited.end()-1; + delegate.visited.erase(last); + pNextNode->setStatus(GES_NOT_VISITED); + delegate.didVisitNode(pNextNode); } } public: + explicit CAmGraph(const std::vector &v):mStoreNodes(), mStoreAdjList(), mPointersNodes(), mPointersAdjList() { typedef typename std::vector::const_iterator inItr; @@ -524,7 +559,7 @@ namespace am std::vector min_distance; std::vector*> previous; - findShortestsPathsFromNode(source, min_distance, previous); + findShortestPathsFromNode(source, min_distance, previous); for(auto it=listTargets.begin(); it!=listTargets.end(); it++) { @@ -554,7 +589,7 @@ namespace am return; std::vector min_distance; std::vector*> previous; - findShortestsPathsFromNode(source, min_distance, previous); + findShortestPathsFromNode(source, min_distance, previous); constructShortestPathTo(destination, previous, resultPath); } @@ -576,7 +611,7 @@ namespace am std::vector min_distance; std::vector*> previous; - findShortestsPathsFromNode(source, min_distance, previous); + findShortestPathsFromNode(source, min_distance, previous); for(auto it=listTargets.begin(); it!=listTargets.end(); it++) { @@ -603,7 +638,7 @@ namespace am std::vector min_distance; std::vector*> previous; - findShortestsPathsFromNode(source, min_distance, previous); + findShortestPathsFromNode(source, min_distance, previous); constructShortestPathTo(destination, previous, cb); } @@ -613,15 +648,29 @@ namespace am * * @param src start node. * @param dst destination node. - * @param cb callabck. + * @param cbShouldVisitNode ask the delegate if we should proceed with the current node. + * @param cbWillVisitNode tell the delegate the current node will be visited. + * @param cbDidVisitNode tell the delegate the current node was visited. + * @param cbDidFindPath return the path to the delegate. */ - void getAllPaths(const CAmNode & src, const CAmNode & dst, std::function cb) + void getAllPaths(CAmNode & src, + CAmNode & dst, + std::function * )> cbShouldVisitNode, + std::function *)> cbWillVisitNode, + std::function *)> cbDidVisitNode, + std::function cbDidFindPath) { - CAmNodeReferenceList visited; - visited.push_back((CAmNode*)&src); + IterateThroughAllNodesDelegate delegate; + delegate.source = &src; + delegate.destination = &dst; + delegate.shouldVisitNode = cbShouldVisitNode; + delegate.willVisitNode = cbWillVisitNode; + delegate.didVisitNode = cbDidVisitNode; + delegate.didFindPath = cbDidFindPath; + delegate.visited.push_back((CAmNode*)&src); ((CAmNode*)&src)->setStatus(GES_VISITED); - goThroughAllPaths(dst, visited, cb); - reset(); + findAllPaths(delegate); + ((CAmNode*)&src)->setStatus(GES_NOT_VISITED); } }; diff --git a/AudioManagerCore/include/CAmRouter.h b/AudioManagerCore/include/CAmRouter.h index 705fb4a..f4955d6 100644 --- a/AudioManagerCore/include/CAmRouter.h +++ b/AudioManagerCore/include/CAmRouter.h @@ -38,7 +38,7 @@ namespace am { /** - * Optimal path search between a source and a sink is implemented with a graph which contains nodes - sinks, sources, gateways, converters. + * Optimal path search is implemented with graph which contains nodes - sinks, sources, gateways, converters. * The nodes are identified by sinkID, sourceID, gatewayID, converterID. * A possible connection between two nodes represents the facts that the nodes can be connected with one or more connectionFormats (Node[id=1] ---> Node[id=2]). * It is assumption that the two nodes can be connected. The controller itself decides later whether the connection is possible or not. @@ -48,22 +48,25 @@ namespace am /** * Trace on/off. */ -#if !defined(ROUTING_BUILD_CONNECTIONS) - #undef TRACE_GRAPH -#endif +#undef TRACE_GRAPH /** - * Default behavior is to do the search in one step without connections, which are identified during the search. - * Alternatively the search can be done in two steps. + * Max paths count returned to the controller */ -#if !defined(ROUTING_BUILD_CONNECTIONS) - #undef ROUTING_BUILD_CONNECTIONS -#endif - -#if defined(TRACE_GRAPH) -#if !defined(ROUTING_BUILD_CONNECTIONS) -#warning "You should define ROUTING_BUILD_CONNECTIONS in order to be able to see the connections in the trace." +#ifndef MAX_ROUTING_PATHS +#define MAX_ROUTING_PATHS 5 #endif +/** + * How many times the routing algorithm should look back into domains. + * + * 0 - no cycles are allowed + * 1 - default is one cycle + * ... + * UINT_MAX - set this define to UINT_MAX in order to allow cycles. + * + */ +#ifndef MAX_ALLOWED_DOMAIN_CYCLES +#define MAX_ALLOWED_DOMAIN_CYCLES 1 #endif class CAmRouter; @@ -150,23 +153,17 @@ class CAmControlSender; */ class CAmRouter { - IAmDatabaseHandler* mpDatabaseHandler; //!< pointer to database handler - CAmControlSender* mpControlSender; //!< pointer the controlsender - is used to retrieve information for the optimal route - bool mOnlyFreeConversionNodes; //!< bool flag whether only disconnected elements should be considered or not - CAmRoutingGraph mRoutingGraph; //!< graph object - std::map> mNodeListSources; //!< map with pointers to nodes with sources, used for quick access - std::map> mNodeListSinks; //!< map with pointers to nodes with sinks, used for quick access - std::map> mNodeListGateways; //!< map with pointers to nodes with gateways, used for quick access + IAmDatabaseHandler* mpDatabaseHandler; //!< pointer to database handler + CAmControlSender* mpControlSender; //!< pointer the controlsender - is used to retrieve information for the optimal route + bool mOnlyFreeConversionNodes; //!< bool flag whether only disconnected elements should be considered or not + unsigned mMaxAllowedCycles; //!< max allowed cycles, default is 1 + unsigned mMaxPathCount; //!< max paths count returned to the controller, default is 5 + CAmRoutingGraph mRoutingGraph; //!< graph object + std::map> mNodeListSources; //!< map with pointers to nodes with sources, used for quick access + std::map> mNodeListSinks; //!< map with pointers to nodes with sinks, used for quick access + std::map> mNodeListGateways; //!< map with pointers to nodes with gateways, used for quick access std::map> mNodeListConverters;//!< map with pointers to nodes with converters, used for quick access - am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector & nodes, std::vector & result); - am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects, - std::vector & route, - std::vector::iterator routingElementIterator, - std::vector::iterator routeIterator, - std::vector & result); - - /** * Check whether given converter or gateway has been connected. * @@ -176,86 +173,119 @@ class CAmRouter { return mpDatabaseHandler->isComponentConnected(comp); } - void generateAllPaths(const CAmRoutingNode & src, - const CAmRoutingNode & dst, - const bool includeCycles, - std::function & path)> cb); - void goThroughAllPaths(const CAmRoutingNode & dst, - std::vector & visited, - std::vector & visitedDomains, - std::function & path)> cb); - -#ifdef ROUTING_BUILD_CONNECTIONS + /** - * Connects all converters to its sink and sources if possible. + * Connect all converters to its sink and sources if possible. * */ void constructConverterConnections(); /** - * Connects all gateways to its sink and sources if possible. + * Connect all gateways to its sink and sources if possible. * */ void constructGatewayConnections(); /** - * Connects all sources to the sinks if possible. + * Connect all sources to the sinks if possible. * */ void constructSourceSinkConnections(); -#else + /** - * Construct a list with all vertices + * Construct list with all vertices */ void getVerticesForNode(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Construct a list with all vertices from given source. + * Construct list with all vertices from given source. */ void getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Construct a list with all vertices from given sink. + * Construct list with all vertices from given sink. */ void getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Construct a list with all vertices from given converter. + * Construct list with all vertices from given converter. */ void getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Construct a list with all vertices from given gateway. + * Construct list with all vertices from given gateway. */ void getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list); -#endif + + /** + * Connection format permutations. + */ + am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector & nodes, std::vector & result); + am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects, + std::vector & route, + std::vector::iterator routingElementIterator, + std::vector::iterator routeIterator, + std::vector & result); + am_Error_e cfPermutationsForPath(am_Route_s shortestRoute, std::vector resultNodesPath, std::vector& resultPath); + + /** + * Helper method. + */ + static int insertPostion(const std::vector& path, const std::vector >& nodes) ; + public: CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender); ~CAmRouter(); + unsigned getMaxAllowedCycles() { return mMaxAllowedCycles; } + void setMaxAllowedCycles(unsigned count) { mMaxAllowedCycles = count; } + + unsigned getMaxPathCount() { return mMaxPathCount; } + void setMaxPathCount(unsigned count) { mMaxPathCount = count; } + /** - * Finds all possible paths between given source and sink. + * Find first mMaxPathCount paths between given source and sink. * * @param onlyfree only disconnected elements should be included or not. - * @param sourceID starting point. - * @param sinkID ending point. + * @param sourceID start point. + * @param sinkID end point. * @param returnList list with all possible paths * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure. */ am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector& returnList); - am_Error_e getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes); + am_Error_e getRoute(const bool onlyfree, const am_Source_s & source, const am_Sink_s & sink, std::vector & listRoutes); - am_Error_e getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink, - std::vector & resultPath, std::vector> & resultNodesPath, -#if !defined(ROUTING_BUILD_CONNECTIONS) - __attribute__((unused)) -#endif - const bool includeCycles = false); -#ifdef ROUTING_BUILD_CONNECTIONS - void getShortestPath(const CAmRoutingNode & source, const CAmRoutingNode & destination, std::vector & resultPath); - void getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, am_Route_s & resultPath, std::vector & resultNodesPath); -#endif + /** + * Find first mMaxPathCount paths between given source and sink after the nodes have been loaded. + * + * @param sourceID start point. + * @param sinkID end point. + * @param returnList list with all possible paths + * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure. + */ + am_Error_e getRouteFromLoadedNodes(const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector & returnList); + am_Error_e getRouteFromLoadedNodes(const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes); + + /** + * Find first mMaxPathCount paths between given source and sink. This method should be called only after 'load' has been called. + * + * @param source start point. + * @param sink end point. + * @param returnList list with all possible paths. + * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure. + */ + am_Error_e getFirstNShortestPaths(CAmRoutingNode & source, CAmRoutingNode & sink, std::vector & resultPath); + + /** + * Find the shortest path between given source and sink. This method should be called only after 'load' has been called. + * + * @param source start point. + * @param sink end point. + * @param returnList list with the connection format permutations of the shortest path. + * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure. + */ + am_Error_e getShortestPath(CAmRoutingNode & source, CAmRoutingNode & sink, std::vector & resultPath); static bool getAllowedFormatsFromConvMatrix( const std::vector & convertionMatrix, const std::vector & listSourceFormats, @@ -274,8 +304,8 @@ public: std::vector::iterator iteratorSink, std::vector & outConnectionFormats); - static bool shouldGoInDomain(const std::vector & visitedDomains, const am_domainID_t nodeDomainID); - + static bool shouldGoInDomain(const std::vector & visitedDomains, const am_domainID_t nodeDomainID, const unsigned maxCyclesNumber); + bool shouldGoInDomain(const std::vector & visitedDomains, const am_domainID_t nodeDomainID); /** * Returns a sink node with given sinkID. * @@ -313,6 +343,20 @@ public: void load(const bool onlyFree); void clear(); + + /** + * DEPRECATED! + */ +public: + am_Error_e getAllPaths(CAmRoutingNode & aSource, + CAmRoutingNode & aSink, + std::vector & resultPath, + std::vector> & resultNodesPath, + const bool includeCycles = false) + __attribute__((deprecated("You should use am_Error_e getFirstNShortestPaths(CAmRoutingNode &, CAmRoutingNode &, std::vector &) instead!"))); + + void getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, am_Route_s & resultPath, std::vector & resultNodesPath) + __attribute__((deprecated("You should use am_Error_e getShortestPath(CAmRoutingNode &, CAmRoutingNode &, std::vector &) instead!"))); }; } /* namespace am */ #endif /* ROUTER_H_ */ diff --git a/AudioManagerCore/src/CAmRouter.cpp b/AudioManagerCore/src/CAmRouter.cpp index f59af24..7ee71ba 100644 --- a/AudioManagerCore/src/CAmRouter.cpp +++ b/AudioManagerCore/src/CAmRouter.cpp @@ -57,6 +57,8 @@ CAmRouter::CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSe mpDatabaseHandler(iDatabaseHandler), // mpControlSender(iSender), mOnlyFreeConversionNodes(false), + mMaxAllowedCycles(MAX_ALLOWED_DOMAIN_CYCLES), + mMaxPathCount(MAX_ROUTING_PATHS), mRoutingGraph(), mNodeListSources(), mNodeListSinks(), @@ -81,52 +83,51 @@ CAmRouter::~CAmRouter() */ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector & returnList) { - returnList.clear(); - am_Source_s source; - am_Sink_s sink; - am_Error_e error = mpDatabaseHandler->getSourceInfoDB(sourceID, source); - if(error!=E_OK) - return error; - error = mpDatabaseHandler->getSinkInfoDB(sinkID, sink); - if(error!=E_OK) - return error; - error = getRoute(onlyfree, source, sink, returnList); - return error; + load(onlyfree); + return getRouteFromLoadedNodes(sourceID, sinkID, returnList); } am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes) { - am_Error_e error; - load(onlyfree); + return getRoute(onlyfree, aSource.sourceID, aSink.sinkID, listRoutes); +} - CAmRoutingNode* pRootSource = sourceNodeWithID(aSource.sourceID); - CAmRoutingNode* pRootSink = sinkNodeWithID(aSink.sinkID); +am_Error_e CAmRouter::getRouteFromLoadedNodes(const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector & returnList) +{ + returnList.clear(); - assert(pRootSource); - assert(pRootSink); + CAmRoutingNode* pRootSource = sourceNodeWithID(sourceID); + CAmRoutingNode* pRootSink = sinkNodeWithID(sinkID); -#ifdef TRACE_GRAPH - mRoutingGraph.trace([&](const CAmRoutingNode & node, const std::vector*> & list) { - std::cout << "Node " << node.getIndex() << ":"; - ((CAmRoutingNode &)node).getData().trace(); - std::cout << "-->["; - int count = 0; - std::for_each(list.begin(), list.end(), [&](const CAmVertex* refVertex){ - am::CAmNode* data = refVertex->getNode(); - if(count>0) - std::cout << ", "; - std::cout << "Node " << data->getIndex() << ":"; - data->getData().trace(); - count++; - }); - std::cout << "]" << std::endl; - }); -#endif + if(!pRootSource || !pRootSink) + return E_NON_EXISTENT; - std::vector> pathNodes; - error = getAllPaths(*pRootSource, *pRootSink, listRoutes, pathNodes); - return error; + //try to find paths without cycles + const unsigned cycles = mMaxAllowedCycles; + mMaxAllowedCycles = 0; + + am_Error_e error = getFirstNShortestPaths(*pRootSource, *pRootSink, returnList); + + mMaxAllowedCycles = cycles; + + //if no paths have been found, we start a second search with cycles. + if( !returnList.size() && cycles>0 ) + { + error = getFirstNShortestPaths(*pRootSource, *pRootSink, returnList); + } + + /* For shortest path use the following call: + * + * error = getShortestPath(*pRootSource, *pRootSink, listRoutes); + */ + return error; +} + + +am_Error_e CAmRouter::getRouteFromLoadedNodes(const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes) +{ + return getRouteFromLoadedNodes(aSource.sourceID, aSink.sinkID, listRoutes); } void CAmRouter::load(const bool onlyFree) @@ -138,32 +139,53 @@ void CAmRouter::load(const bool onlyFree) nodeDataSrc.type = CAmNodeDataType::SOURCE; mpDatabaseHandler->enumerateSources([&](const am_Source_s & obj){ nodeDataSrc.data.source = (am_Source_s*)&obj; - mNodeListSources[nodeDataSrc.data.source->domainID].push_back(&mRoutingGraph.addNode(nodeDataSrc)); - }); + auto node = &mRoutingGraph.addNode(nodeDataSrc); + mNodeListSources[nodeDataSrc.data.source->domainID].push_back(node); + }); am_RoutingNodeData_s nodeDataSink; nodeDataSink.type = CAmNodeDataType::SINK; mpDatabaseHandler->enumerateSinks([&](const am_Sink_s & obj){ nodeDataSink.data.sink = (am_Sink_s*)&obj; - mNodeListSinks[nodeDataSink.data.sink->domainID].push_back(&mRoutingGraph.addNode(nodeDataSink)); - }); + auto node = &mRoutingGraph.addNode(nodeDataSink); + mNodeListSinks[nodeDataSink.data.sink->domainID].push_back(node); + }); am_RoutingNodeData_s nodeDataGateway; nodeDataGateway.type = CAmNodeDataType::GATEWAY; mpDatabaseHandler->enumerateGateways([&](const am_Gateway_s & obj){ nodeDataGateway.data.gateway = (am_Gateway_s*)&obj; - mNodeListGateways[nodeDataGateway.data.gateway->controlDomainID].push_back(&mRoutingGraph.addNode(nodeDataGateway)); + auto node = &mRoutingGraph.addNode(nodeDataGateway); + mNodeListGateways[nodeDataGateway.data.gateway->controlDomainID].push_back(node); }); am_RoutingNodeData_s nodeDataConverter; nodeDataConverter.type = CAmNodeDataType::CONVERTER; mpDatabaseHandler->enumerateConverters([&](const am_Converter_s & obj){ nodeDataConverter.data.converter = (am_Converter_s*)&obj; - mNodeListConverters[nodeDataConverter.data.converter->domainID].push_back(&mRoutingGraph.addNode(nodeDataConverter)); + auto node = &mRoutingGraph.addNode(nodeDataConverter); + mNodeListConverters[nodeDataConverter.data.converter->domainID].push_back(node); }); -#ifdef ROUTING_BUILD_CONNECTIONS constructConverterConnections(); constructGatewayConnections(); constructSourceSinkConnections(); + +#ifdef TRACE_GRAPH + mRoutingGraph.trace([&](const CAmRoutingNode & node, const std::vector*> & list) { + std::cout << "Node " << node.getIndex() << ":"; + ((CAmRoutingNode &)node).getData().trace(); + std::cout << "-->["; + int count = 0; + std::for_each(list.begin(), list.end(), [&](const CAmVertex* refVertex){ + am::CAmNode* data = refVertex->getNode(); + if(count>0) + std::cout << ", "; + std::cout << "Node " << data->getIndex() << ":"; + data->getData().trace(); + count++; + }); + std::cout << "]" << std::endl; + }); #endif + } void CAmRouter::clear() @@ -249,8 +271,6 @@ CAmRoutingNode* CAmRouter::gatewayNodeWithSinkID(const am_sinkID_t sinkID) return NULL; } -#ifdef ROUTING_BUILD_CONNECTIONS - void CAmRouter::constructSourceSinkConnections() { std::vector intersection; @@ -353,7 +373,6 @@ void CAmRouter::constructConverterConnections() } } } -#else void CAmRouter::getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list) { @@ -470,8 +489,6 @@ void CAmRouter::getVerticesForNode( } } -#endif - am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector & nodes, std::vector & result) { std::vector::iterator routingElementIterator = routeObjects.route.begin(); @@ -570,31 +587,66 @@ am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, } } -#ifdef ROUTING_BUILD_CONNECTIONS - -void CAmRouter::getShortestPath(const CAmRoutingNode & source, - const CAmRoutingNode & destination, - std::vector & resultPath) +am_Error_e CAmRouter::cfPermutationsForPath(am_Route_s shortestRoute, std::vector resultNodesPath, std::vector& resultPath) { - mRoutingGraph.getShortestPath(source, destination, resultPath); + std::vector result; + am_Error_e err = determineConnectionFormatsForPath(shortestRoute, resultNodesPath, result); + if (err != E_UNKNOWN) + { + resultPath.insert(resultPath.end(), result.begin(), result.end()); +#ifdef TRACE_GRAPH + std::cout + << "Successfully determined connection formats for path from source:" + << shortestRoute.sourceID << " to sink:" << shortestRoute.sinkID + << "\n"; + for (auto routeConnectionFormats : result) + { + std::cout << "["; + for (auto it = routeConnectionFormats.route.begin();it != routeConnectionFormats.route.end(); it++) + { + am_RoutingElement_s& routingElement = *it; + if (it - routeConnectionFormats.route.begin() > 0) + std::cout << " -> "; + + std::cout << routingElement.sourceID << ":" + << routingElement.sinkID << " CF:" + << routingElement.connectionFormat << " D:" + << routingElement.domainID; + } + std::cout << "]\n"; + } +#endif + } +#ifdef TRACE_GRAPH + else + { + std::cout + << "Error by determining connection formats for path from source:" + << shortestRoute.sourceID << " to sink:" << shortestRoute.sinkID + << "\n"; + } +#endif + return err; } -void CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, - am_Route_s & resultPath, std::vector & resultNodesPath) +am_Error_e CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, std::vector & resultPath) { - am_RoutingElement_s * element; + am_Error_e err = E_OK; + am_Route_s shortestRoute; + std::vector resultNodesPath; am_RoutingNodeData_s & sinkNodeData = aSink.getData(); am_RoutingNodeData_s & sourceNodeData = aSource.getData(); - resultPath.sinkID = sinkNodeData.data.sink->sinkID; - resultPath.sourceID = sourceNodeData.data.source->sourceID; + shortestRoute.sinkID = sinkNodeData.data.sink->sinkID; + shortestRoute.sourceID = sourceNodeData.data.source->sourceID; - std::function cb = [&](const am_GraphPathPosition_e, CAmRoutingNode & object) - { + mRoutingGraph.getShortestPath(aSource, aSink, [&shortestRoute, &resultNodesPath](const am_GraphPathPosition_e position, CAmRoutingNode & object){ + am_RoutingElement_s * element; + //reverse order resultNodesPath.insert(resultNodesPath.begin(), (CAmRoutingNode*)&object); am_RoutingNodeData_s & routingData = object.getData(); if(routingData.type==CAmNodeDataType::SINK) { - auto iter = resultPath.route.emplace(resultPath.route.begin()); + auto iter = shortestRoute.route.emplace(shortestRoute.route.begin()); element = &(*iter); element->domainID = routingData.data.sink->domainID; element->sinkID = routingData.data.sink->sinkID; @@ -606,87 +658,195 @@ void CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink element->sourceID = routingData.data.source->sourceID; element->connectionFormat = CF_UNKNOWN; } - }; - mRoutingGraph.getShortestPath(aSource, aSink, cb); -} + }); -#endif + if(shortestRoute.route.size()) + { + err = cfPermutationsForPath(shortestRoute, resultNodesPath, resultPath); + } + return err; +} -am_Error_e CAmRouter::getAllPaths(CAmRoutingNode & aSource, - CAmRoutingNode & aSink, - std::vector & resultPath, - std::vector> & resultNodesPath, - const bool includeCycles) -{ -#ifndef ROUTING_BUILD_CONNECTIONS - bool cycles = false; -#else - bool cycles = includeCycles; -#endif - if(((CAmRoutingNode*)&aSource)->getData().type!=CAmNodeDataType::SOURCE || - ((CAmRoutingNode*)&aSink)->getData().type!=CAmNodeDataType::SINK) - return E_NOT_POSSIBLE; +void CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, am_Route_s & path, std::vector & resultNodesPath) +{ + am_Route_s shortestRoute; + am_RoutingNodeData_s & sinkNodeData = aSink.getData(); + am_RoutingNodeData_s & sourceNodeData = aSource.getData(); + shortestRoute.sinkID = sinkNodeData.data.sink->sinkID; + shortestRoute.sourceID = sourceNodeData.data.source->sourceID; - uint8_t errorsCount = 0, successCount = 0; - generateAllPaths(aSource, aSink, cycles, [&](const std::vector & path) { - resultNodesPath.push_back(path); - am_Route_s nextRoute; - nextRoute.sinkID = aSink.getData().data.sink->sinkID; - nextRoute.sourceID = aSource.getData().data.source->sourceID; + mRoutingGraph.getShortestPath(aSource, aSink, [&shortestRoute, &resultNodesPath](const am_GraphPathPosition_e position, CAmRoutingNode & object){ am_RoutingElement_s * element; - for(auto it = path.begin(); it!=path.end(); it++) + //reverse order + resultNodesPath.insert(resultNodesPath.begin(), (CAmRoutingNode*)&object); + am_RoutingNodeData_s & routingData = object.getData(); + if(routingData.type==CAmNodeDataType::SINK) { - am_RoutingNodeData_s & routingData = (*it)->getData(); - if(routingData.type==CAmNodeDataType::SOURCE) - { - auto iter = nextRoute.route.emplace(nextRoute.route.end()); - element = &(*iter); - element->domainID = routingData.data.source->domainID; - element->sourceID = routingData.data.source->sourceID; - element->connectionFormat = CF_UNKNOWN; - } - else if(routingData.type==CAmNodeDataType::SINK) - { - element->domainID = routingData.data.sink->domainID; - element->sinkID = routingData.data.sink->sinkID; - element->connectionFormat = CF_UNKNOWN; - } + auto iter = shortestRoute.route.emplace(shortestRoute.route.begin()); + element = &(*iter); + element->domainID = routingData.data.sink->domainID; + element->sinkID = routingData.data.sink->sinkID; + element->connectionFormat = CF_UNKNOWN; } - std::vector result; - am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector &)path, result); - if(err==E_UNKNOWN) + else if(routingData.type==CAmNodeDataType::SOURCE) { - errorsCount++; -#ifdef TRACE_GRAPH - std::cout<<"Error by determining connection formats for path from source:"<domainID = routingData.data.source->domainID; + element->sourceID = routingData.data.source->sourceID; + element->connectionFormat = CF_UNKNOWN; + } + }); + + if(shortestRoute.route.size()) + { + std::vector resultPath; + cfPermutationsForPath(shortestRoute, resultNodesPath, resultPath); + if(resultPath.size()) + path = resultPath.front(); + } +} + +int CAmRouter::insertPostion(const std::vector& path, const std::vector >& nodes) +{ + int index = 0; + if (!nodes.empty()) { + auto itNodes = nodes.begin(); + for (; itNodes != nodes.end(); itNodes++) { + if (itNodes->size() > path.size()) + break; } + if (itNodes == nodes.end()) + index = nodes.size(); + else + index = itNodes - nodes.begin(); + } + return index; +} + +am_Error_e CAmRouter::getAllPaths(CAmRoutingNode & aSource, + CAmRoutingNode & aSink, + std::vector & resultPath, + std::vector> & resultNodesPath, + const bool includeCycles) +{ + + if( aSource.getData().type!=CAmNodeDataType::SOURCE || aSink.getData().type!=CAmNodeDataType::SINK ) + return E_NOT_POSSIBLE; + + unsigned cycles; + if(includeCycles) + cycles = UINT_MAX; + else + cycles = 0; + + uint8_t errorsCount = 0, successCount = 0; + const am_sinkID_t sinkID = aSink.getData().data.sink->sinkID; + const am_sourceID_t sourceID = aSource.getData().data.source->sourceID; + std::vector paths; + std::vector visitedDomains; + visitedDomains.push_back(((CAmRoutingNode*)&aSource)->getData().domainID()); + mRoutingGraph.getAllPaths(aSource, + aSink, + [&visitedDomains, &cycles](const CAmRoutingNode * node)->bool{ return CAmRouter::shouldGoInDomain(visitedDomains, node->getData().domainID(), cycles); }, + [&visitedDomains](const CAmRoutingNode * node){ visitedDomains.push_back(node->getData().domainID()); }, + [&visitedDomains](const CAmRoutingNode * node){ visitedDomains.erase(visitedDomains.end()-1); }, + [&resultPath, &resultNodesPath, &paths, &errorsCount, &successCount, &sinkID, &sourceID](const std::vector & path) { + int index = CAmRouter::insertPostion(path, resultNodesPath); + resultNodesPath.emplace(resultNodesPath.begin()+index); + paths.emplace(paths.begin()+index); + resultNodesPath[index] = path; + am_Route_s & nextRoute = paths[index]; + nextRoute.sinkID = sinkID; + nextRoute.sourceID = sourceID; + am_RoutingElement_s * element; + for(auto it = path.begin(); it!=path.end(); it++) + { + am_RoutingNodeData_s & routingData = (*it)->getData(); + if(routingData.type==CAmNodeDataType::SOURCE) + { + auto iter = nextRoute.route.emplace(nextRoute.route.end()); + element = &(*iter); + element->domainID = routingData.data.source->domainID; + element->sourceID = routingData.data.source->sourceID; + element->connectionFormat = CF_UNKNOWN; + } + else if(routingData.type==CAmNodeDataType::SINK) + { + element->domainID = routingData.data.sink->domainID; + element->sinkID = routingData.data.sink->sinkID; + element->connectionFormat = CF_UNKNOWN; + } + } + }); + + for(auto it = paths.begin(); successCount" - < & resultPath) +{ + if( aSource.getData().type!=CAmNodeDataType::SOURCE || aSink.getData().type!=CAmNodeDataType::SINK ) + return E_NOT_POSSIBLE; + const unsigned cycles = mMaxAllowedCycles; + uint8_t errorsCount = 0, successCount = 0; + const am_sinkID_t sinkID = aSink.getData().data.sink->sinkID; + const am_sourceID_t sourceID = aSource.getData().data.source->sourceID; + std::vector paths; + std::vector> nodes; + std::vector visitedDomains; + visitedDomains.push_back(((CAmRoutingNode*)&aSource)->getData().domainID()); + mRoutingGraph.getAllPaths(aSource, + aSink, + [&visitedDomains, &cycles](const CAmRoutingNode * node)->bool{ return CAmRouter::shouldGoInDomain(visitedDomains, node->getData().domainID(), cycles); }, + [&visitedDomains](const CAmRoutingNode * node){ visitedDomains.push_back(node->getData().domainID()); }, + [&visitedDomains](const CAmRoutingNode * node){ visitedDomains.erase(visitedDomains.end()-1); }, + [&resultPath, &nodes, &paths, &errorsCount, &successCount, &sinkID, &sourceID](const std::vector & path) { + int index = CAmRouter::insertPostion(path, nodes); + nodes.emplace(nodes.begin()+index); + paths.emplace(paths.begin()+index); + nodes[index] = path; + am_Route_s & nextRoute = paths[index]; + nextRoute.sinkID = sinkID; + nextRoute.sourceID = sourceID; + am_RoutingElement_s * element; + for(auto it = path.begin(); it!=path.end(); it++) + { + am_RoutingNodeData_s & routingData = (*it)->getData(); + if(routingData.type==CAmNodeDataType::SOURCE) + { + auto iter = nextRoute.route.emplace(nextRoute.route.end()); + element = &(*iter); + element->domainID = routingData.data.source->domainID; + element->sourceID = routingData.data.source->sourceID; + element->connectionFormat = CF_UNKNOWN; + } + else if(routingData.type==CAmNodeDataType::SINK) + { + element->domainID = routingData.data.sink->domainID; + element->sinkID = routingData.data.sink->sinkID; + element->connectionFormat = CF_UNKNOWN; + } + } }); + + for(auto it = paths.begin(); successCount & visitedDomains, const am_domainID_t nodeDomainID) +bool CAmRouter::shouldGoInDomain(const std::vector & visitedDomains, const am_domainID_t nodeDomainID, const unsigned maxCyclesNumber) { + unsigned recourseCounter(0); if(visitedDomains.size()) { if(visitedDomains.back()==nodeDomainID) return true; - - for(auto it=visitedDomains.begin();it!=visitedDomains.end()-1; it++) + unsigned count = 0; + am_domainID_t lastDomain = 0; + for(auto it=visitedDomains.begin(); it!=visitedDomains.end()-1; it++) { - if(nodeDomainID==*it) - return false; + if(lastDomain!=*it) + { + if(nodeDomainID==*it) + { + recourseCounter++; + if (recourseCounter>maxCyclesNumber) + return false; + } + lastDomain=*it; + } } } return true; } -void CAmRouter::generateAllPaths(const CAmRoutingNode & src, - const CAmRoutingNode & dst, - const bool includeCycles, - std::function & path)> cb) -{ - if(!includeCycles) - { - std::vector visited; - std::vector visitedDomains; - visited.push_back((CAmRoutingNode*)&src); - visitedDomains.push_back(((CAmRoutingNode*)&src)->getData().domainID()); - ((CAmRoutingNode*)&src)->setStatus(GES_VISITED); - goThroughAllPaths(dst, visited, visitedDomains, cb); - } - else - mRoutingGraph.getAllPaths(src, dst, cb); -} - -void CAmRouter::goThroughAllPaths(const CAmRoutingNode & dst, - std::vector & visited, - std::vector & visitedDomains, - std::function & path)> cb) +bool CAmRouter::shouldGoInDomain(const std::vector & visitedDomains, const am_domainID_t nodeDomainID) { -#ifndef ROUTING_BUILD_CONNECTIONS - CAmRoutingListVertices vertices; - getVerticesForNode(*visited.back(), vertices); - const CAmRoutingListVertices * nodes = &vertices; -#else - const CAmRoutingListVertices * nodes = mRoutingGraph.getVertexList()[visited.back()->getIndex()]; -#endif - CAmRoutingListVertices::const_iterator vItr(nodes->begin()); - for (; vItr != nodes->end(); ++vItr) - { - const CAmRoutingVertex & vertex = (*vItr); - if(vertex.getNode()->getStatus()!=GES_NOT_VISITED || !shouldGoInDomain(visitedDomains, vertex.getNode()->getData().domainID())) - continue; - if (vertex.getNode()==&dst) - { - vertex.getNode()->setStatus(GES_IN_PROGRESS); - visited.push_back(vertex.getNode()); - visitedDomains.push_back(vertex.getNode()->getData().domainID()); - //notify observer - cb(visited); - //remove last node from the list - auto last = visited.end()-1; - visited.erase(last); - visitedDomains.erase(visitedDomains.end()-1); - vertex.getNode()->setStatus(GES_NOT_VISITED); - break; - } - } - vItr = nodes->begin(); - //bfs like loop - for (; vItr != nodes->end(); ++vItr) - { - const CAmRoutingVertex & vertex = (*vItr); - if(vertex.getNode()->getStatus()!=GES_NOT_VISITED - ||vertex.getNode()==&dst || - !shouldGoInDomain(visitedDomains, vertex.getNode()->getData().domainID())) - continue; - vertex.getNode()->setStatus(GES_IN_PROGRESS); - visited.push_back(vertex.getNode()); - visitedDomains.push_back(vertex.getNode()->getData().domainID()); - goThroughAllPaths(dst, visited, visitedDomains, cb); - //remove last node from the list - auto last = visited.end()-1; - visited.erase(last); - visitedDomains.erase(visitedDomains.end()-1); - vertex.getNode()->setStatus(GES_NOT_VISITED); - } + return CAmRouter::shouldGoInDomain(visitedDomains, nodeDomainID, mMaxAllowedCycles); } bool CAmRouter::getAllowedFormatsFromConvMatrix( const std::vector & convertionMatrix, @@ -872,4 +975,5 @@ am_Error_e CAmRouter::getSourceSinkPossibleConnectionFormats(std::vector & listRoutes) +void CAmRouterMapTest::getRoute(const bool onlyfree, const bool shouldReload, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes, const unsigned countCycles, const unsigned pathsCount) { + pRouter.setMaxAllowedCycles(countCycles); + pRouter.setMaxPathCount(pathsCount); std::ios_base::fmtflags oldflags = std::cout.flags(); std::streamsize oldprecision = std::cout.precision(); auto t_start = std::chrono::high_resolution_clock::now(); - ASSERT_EQ(E_OK, pRouter.getRoute(onlyfree, aSource, aSink, listRoutes)); + if(shouldReload) + pRouter.load(onlyfree); + ASSERT_EQ(E_OK, pRouter.getRouteFromLoadedNodes(aSource, aSink, listRoutes)); auto t_end = std::chrono::high_resolution_clock::now(); std::cout << std::fixed << std::setprecision(2); std::cout << listRoutes.size() <<" routes from " << aSource.sourceID << " to " << aSink.sinkID; @@ -181,12 +185,16 @@ void CAmRouterMapTest::getRoute(const bool onlyfree, const am_Source_s & aSource std::cout.precision (oldprecision); } -void CAmRouterMapTest::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector& returnList) +void CAmRouterMapTest::getRoute(const bool onlyfree, const bool shouldReload, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector& returnList, const unsigned countCycles, const unsigned pathsCount) { + pRouter.setMaxAllowedCycles(countCycles); + pRouter.setMaxPathCount(pathsCount); std::ios_base::fmtflags oldflags = std::cout.flags(); std::streamsize oldprecision = std::cout.precision(); auto t_start = std::chrono::high_resolution_clock::now(); - ASSERT_EQ(E_OK, pRouter.getRoute(onlyfree, sourceID, sinkID, returnList)); + if(shouldReload) + pRouter.load(onlyfree); + ASSERT_EQ(E_OK, pRouter.getRouteFromLoadedNodes(sourceID, sinkID, returnList)); auto t_end = std::chrono::high_resolution_clock::now(); std::cout << std::fixed << std::setprecision(2); std::cout << returnList.size() <<" routes from " << sourceID << " to " << sinkID; @@ -195,16 +203,14 @@ void CAmRouterMapTest::getRoute(const bool onlyfree, const am_sourceID_t sourceI std::cout.precision (oldprecision); } -void CAmRouterMapTest::getAllPaths(CAmRoutingNode & aSource, - CAmRoutingNode & aSink, - std::vector & resultPath, - std::vector> & resultNodesPath, - const bool includeCycles) +void CAmRouterMapTest::getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink, std::vector & resultPath, const unsigned countCycles, const unsigned pathsCount) { + pRouter.setMaxAllowedCycles(countCycles); + pRouter.setMaxPathCount(pathsCount); std::ios_base::fmtflags oldflags = std::cout.flags(); std::streamsize oldprecision = std::cout.precision(); auto t_start = std::chrono::high_resolution_clock::now(); - ASSERT_EQ(E_OK, pRouter.getAllPaths(aSource, aSink, resultPath, resultNodesPath, includeCycles)); + ASSERT_EQ(E_OK, pRouter.getFirstNShortestPaths(aSource, aSink, resultPath)); auto t_end = std::chrono::high_resolution_clock::now(); std::cout << std::fixed << std::setprecision(2); std::cout << resultPath.size() @@ -218,19 +224,19 @@ void CAmRouterMapTest::getAllPaths(CAmRoutingNode & aSource, TEST_F(CAmRouterMapTest,checkInsertedDomain) { std::vector domains; - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22, 0)); domains.push_back(22); - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22, 0)); domains.push_back(22); - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22)); - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 50)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22, 0)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 50, 0)); domains.push_back(30); - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30)); - ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30, 0)); + ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22, 0)); domains.push_back(30); - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30)); - ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22)); - ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 60)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30, 0)); + ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22, 0)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 60, 0)); } //test that checks just sinks and source in a domain but connectionformats do not match @@ -304,7 +310,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2withDomainNoMatchFormats) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(true, sourceDb, sinkDb, listRoutes); + getRoute(true, true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast(0), listRoutes.size()); } @@ -379,7 +385,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2withDomain) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(true, sourceDb, sinkDb, listRoutes); + getRoute(true, true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -498,7 +504,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsOnlyFree) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(true,sourceID,sinkID,listRoutes); + getRoute(true, true,sourceID,sinkID,listRoutes); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -633,11 +639,11 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsOnlyFreeNotFree) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(true, sourceDb, sinkDb, listRoutes); + getRoute(true, true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast(0), listRoutes.size()); listRoutes.clear(); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -784,7 +790,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsCircularGWOnlyFree) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(true, sourceDb, sinkDb, listRoutes); + getRoute(true, true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -957,7 +963,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats_2) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -1124,12 +1130,11 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats_1) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } - //test that checks 3 domains, one sink one source, longer lists of connectionformats. TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats) { @@ -1287,12 +1292,11 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } - //test that checks 4 domains, one sink and one source but there are 2 routes because there are 2 gateways TEST_F(CAmRouterMapTest,simpleRoute4Domains2Routes) { @@ -1534,7 +1538,7 @@ TEST_F(CAmRouterMapTest,simpleRoute4Domains2Routes) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(2), listRoutes.size()); bool containsRoute1 = std::find_if(listRoutes.begin(), listRoutes.end(), [&](const am_Route_s & ref) { @@ -1702,9 +1706,10 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsNoConnection) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(0), listRoutes.size()); } + //test that checks just 2 domains, one sink one source with only one connection format each TEST_F(CAmRouterMapTest,simpleRoute2Domains) { @@ -1820,7 +1825,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2Domains) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -1917,7 +1922,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsNoMatchConnectionFormats) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(0), listRoutes.size()); } @@ -2076,7 +2081,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3Domains) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2275,7 +2280,7 @@ TEST_F(CAmRouterMapTest,simpleRoute4Domains) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - getRoute(false, sourceDb, sinkDb, listRoutes); + getRoute(false, true, sourceDb, sinkDb, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2400,7 +2405,7 @@ TEST_F(CAmRouterMapTest,route1Domain1Source1Sink) compareRoute.sinkID = sinkID; compareRoute.sourceID = sourceID; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2485,7 +2490,7 @@ TEST_F(CAmRouterMapTest,route1Domain1Source1Converter1Sink) compareRoute.sinkID = sinkID1; compareRoute.sourceID = sourceID; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2600,7 +2605,7 @@ TEST_F(CAmRouterMapTest,route1Domain1Source3Converters1Sink) compareRoute1.sinkID = sinkID; compareRoute1.sourceID = sourceID; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(2), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])||pCF.compareRoute(compareRoute1,listRoutes[1])); @@ -2665,7 +2670,7 @@ TEST_F(CAmRouterMapTest,route2Domains1Source1Sink) pDatabaseHandler.getSourceInfoDB(sourceID, source); std::vector listRoutes; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2741,7 +2746,7 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1Sink) std::vector listRoutes; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2822,7 +2827,7 @@ TEST_F(CAmRouterMapTest,routeSource1Sink2PathThroughConv1Gate1) std::vector listRoutes; - getRoute(false, source, sink1, listRoutes); + getRoute(false, true, source, sink1, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2834,7 +2839,7 @@ TEST_F(CAmRouterMapTest,routeSource1Sink2PathThroughConv1Gate1) ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])); listRoutes.clear(); - getRoute(false, source, sink2, listRoutes); + getRoute(false, true, source, sink2, listRoutes, 0); ASSERT_EQ(static_cast(0), listRoutes.size()); } @@ -2900,13 +2905,13 @@ TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughDomain2) pDatabaseHandler.getSinkInfoDB(sink1ID, sink1); pDatabaseHandler.getSourceInfoDB(sourceID, source); - getRoute(false, source, sink1, listRoutes); + getRoute(false, true, source, sink1, listRoutes, 0); ASSERT_EQ(static_cast(0), listRoutes.size()); am::am_Sink_s sink2; pDatabaseHandler.getSinkInfoDB(sink2ID, sink2); - getRoute(false, source, sink2, listRoutes); + getRoute(false, true, source, sink2, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2993,12 +2998,12 @@ TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughGate1Conv2Gate2) std::vector listRoutes; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(0), listRoutes.size()); am::am_Sink_s sink1; pDatabaseHandler.getSinkInfoDB(sink2ID, sink1); - getRoute(false, source, sink1, listRoutes); + getRoute(false, true, source, sink1, listRoutes, 0); ASSERT_EQ(static_cast(1), listRoutes.size()); am_Route_s compareRoute1; @@ -3107,12 +3112,12 @@ TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughConv1Gate1Conv2Gate2) std::vector listRoutes; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes, 0); ASSERT_EQ(static_cast(0), listRoutes.size()); am::am_Sink_s sink2; pDatabaseHandler.getSinkInfoDB(coSinkID21, sink2); - pRouter.getRoute(false, source, sink2, listRoutes); + getRoute(false, true, source, sink2, listRoutes, 0); ASSERT_EQ(static_cast(2), listRoutes.size()); am_Route_s compareRoute1; @@ -3217,7 +3222,6 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles) ASSERT_TRUE(sinkNode); std::vector listRoutes; - std::vector> resultNodesPath; am_Route_s compareRoute1; compareRoute1.sinkID = sink1ID; @@ -3231,8 +3235,7 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles) ASSERT_TRUE(didMatch); \ } -#ifdef ROUTING_BUILD_CONNECTIONS - getAllPaths(*sourceNode, *sinkNode, listRoutes, resultNodesPath, true); + getAllPaths(*sourceNode, *sinkNode, listRoutes, UINT_MAX, 10); ASSERT_EQ(static_cast(9), listRoutes.size()); compareRoute1.route.clear(); @@ -3303,19 +3306,169 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles) compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() -#else + + listRoutes.clear(); + + getAllPaths(*sourceNode, *sinkNode, listRoutes, 1, 10); + ASSERT_EQ(static_cast(5), listRoutes.size()); + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); + DO_ASSERT() + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); + DO_ASSERT() + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); + DO_ASSERT() + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); + DO_ASSERT() + compareRoute1.route.clear(); compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); -#endif + DO_ASSERT() listRoutes.clear(); - resultNodesPath.clear(); - getAllPaths(*sourceNode, *sinkNode, listRoutes, resultNodesPath, false); + + getAllPaths(*sourceNode, *sinkNode, listRoutes); ASSERT_EQ(static_cast(1), listRoutes.size()); DO_ASSERT() } +TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles2) +{ + EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK))); + + am_SourceClass_s sourceclass; + + sourceclass.name="sClass"; + sourceclass.sourceClassID=5; + + ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceClassDB(sourceclass.sourceClassID,sourceclass)); + + am_SinkClass_s sinkclass; + sinkclass.sinkClassID=5; + sinkclass.name="sname"; + + + ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkClassDB(sinkclass,sinkclass.sinkClassID)); + + am_domainID_t domain1ID, domain2ID, domain3ID; + enterDomainDB("domain1", domain1ID); + enterDomainDB("domain2", domain2ID); + enterDomainDB("domain3", domain3ID); + + //just make so many cycles as possible + std::vector cfStereo; + cfStereo.push_back(CF_GENIVI_STEREO); + std::vector cfOther; + cfOther.push_back(CF_GENIVI_AUTO); + std::vector cfMono; + cfMono.push_back(CF_GENIVI_MONO); + + am_sourceID_t source1ID; + enterSourceDB("source1", domain1ID, cfMono, source1ID); + am_sinkID_t gw1SinkID; + enterSinkDB("gw1Sink", domain1ID, cfStereo, gw1SinkID); + am_sinkID_t gw2SinkID; + enterSinkDB("gw2Sink", domain1ID, cfMono, gw2SinkID); + am_sourceID_t gw3SourceID; + enterSourceDB("gw3Source", domain1ID, cfStereo, gw3SourceID); + am_sourceID_t gw4SourceID; + enterSourceDB("gw4Source", domain1ID, cfStereo, gw4SourceID); + am_sinkID_t gw5SinkID; + enterSinkDB("gw5Sink", domain1ID, cfStereo, gw5SinkID); + + am_sourceID_t gw1SourceID; + enterSourceDB("gw1Source", domain2ID, cfStereo, gw1SourceID); + am_sourceID_t gw2SourceID; + enterSourceDB("gw2Source", domain2ID, cfStereo, gw2SourceID); + am_sinkID_t gw3SinkID; + enterSinkDB("gw3Sink", domain2ID, cfStereo, gw3SinkID); + am_sinkID_t gw4SinkID; + enterSinkDB("gw4Sink", domain2ID, cfStereo, gw4SinkID); + + am_sourceID_t gw5SourceID; + enterSourceDB("gw5Source", domain3ID, cfOther, gw5SourceID); + am_sinkID_t sink1ID; + enterSinkDB("sink1", domain3ID, cfOther, sink1ID); + + std::vector matrixT; + matrixT.push_back(true); + std::vector matrixF; + matrixF.push_back(false); + + am_gatewayID_t gateway1ID; + enterGatewayDB("gateway1", domain2ID, domain1ID, cfStereo, cfStereo, matrixT, gw1SourceID, gw1SinkID, gateway1ID); + am_gatewayID_t gateway2ID; + enterGatewayDB("gateway2", domain2ID, domain1ID, cfStereo, cfMono, matrixT, gw2SourceID, gw2SinkID, gateway2ID); + am_gatewayID_t gateway3ID; + enterGatewayDB("gateway3", domain1ID, domain2ID, cfStereo, cfStereo, matrixT, gw3SourceID, gw3SinkID, gateway3ID); + am_gatewayID_t gateway4ID; + enterGatewayDB("gateway4", domain1ID, domain2ID, cfStereo, cfStereo, matrixT, gw4SourceID, gw4SinkID, gateway4ID); + am_gatewayID_t gateway5ID; + enterGatewayDB("gateway5", domain3ID, domain1ID, cfOther, cfStereo, matrixT, gw5SourceID, gw5SinkID, gateway5ID); + + pRouter.load(false); + + CAmRoutingNode* sourceNode = pRouter.sourceNodeWithID(source1ID); + CAmRoutingNode* sinkNode = pRouter.sinkNodeWithID(sink1ID); + + ASSERT_TRUE(sourceNode); + ASSERT_TRUE(sinkNode); + + std::vector listRoutes; + + am_Route_s compareRoute1; + compareRoute1.sinkID = sink1ID; + compareRoute1.sourceID = source1ID; + +#define DO_ASSERT() \ + {\ + bool didMatch = false; \ + for(auto it = listRoutes.begin(); it!=listRoutes.end(); it++) \ + didMatch|=pCF.compareRoute(compareRoute1,*it); \ + ASSERT_TRUE(didMatch); \ + } + + getRoute(false, false, source1ID, sink1ID, listRoutes, 0, 10); + ASSERT_EQ(static_cast(0), listRoutes.size()); + + getRoute(false, false, source1ID, sink1ID, listRoutes, 1, 10); + ASSERT_EQ(static_cast(2), listRoutes.size()); + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_MONO}); + compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_AUTO}); + DO_ASSERT() + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_MONO}); + compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_AUTO}); + DO_ASSERT() +} + TEST_F(CAmRouterMapTest,route3Domains1Source3Gateways3Convertres1Sink) { EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK))); @@ -3403,7 +3556,7 @@ TEST_F(CAmRouterMapTest,route3Domains1Source3Gateways3Convertres1Sink) std::vector listRoutes; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes); ASSERT_EQ(static_cast(4), listRoutes.size()); am_Route_s compareRoute1; @@ -3519,7 +3672,7 @@ TEST_F(CAmRouterMapTest, routeTunerHeadphonePathThroughGWPlus2OtherSinks) pDatabaseHandler.getSourceInfoDB(tunerID, source); std::vector listRoutes; - getRoute(false, source, sink, listRoutes); + getRoute(false, true, source, sink, listRoutes); ASSERT_EQ(listRoutes.size(), static_cast(1)); am_Route_s compareRoute1; @@ -3536,7 +3689,7 @@ TEST_F(CAmRouterMapTest, routeTunerHeadphonePathThroughGWPlus2OtherSinks) am::am_Sink_s sink2; pDatabaseHandler.getSinkInfoDB(rseHeadphoneID, sink2); pDatabaseHandler.getSourceInfoDB(gwSourceID1, gwSource); - getRoute(false, gwSource, sink2, listRoutes); + getRoute(false, true, gwSource, sink2, listRoutes); ASSERT_GT(listRoutes.size(), static_cast(0)); am_Route_s compareRoute2; diff --git a/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h b/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h index 65ff97b..2fc7a46 100644 --- a/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h +++ b/AudioManagerCore/test/AmRouterMapTest/CAmRouterMapTest.h @@ -94,13 +94,9 @@ public: const am_sourceID_t & sourceID, const am_sinkID_t & sinkID, am_converterID_t & converterID); - void getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector& returnList); - void getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes); - void getAllPaths(CAmRoutingNode & aSource, - CAmRoutingNode & aSink, - std::vector & resultPath, - std::vector> & resultNodesPath, - const bool includeCycles); + void getRoute(const bool onlyfree, const bool shouldReload, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector& returnList, const unsigned countCycles=0, const unsigned pathsCount=MAX_ROUTING_PATHS); + void getRoute(const bool onlyfree, const bool shouldReload, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector & listRoutes, const unsigned countCycles=0, const unsigned pathsCount=MAX_ROUTING_PATHS); + void getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink, std::vector & resultPath, const unsigned countCycles=0, const unsigned pathsCount=MAX_ROUTING_PATHS); }; } -- cgit v1.2.1