summaryrefslogtreecommitdiff
path: root/AudioManagerCore/src/CAmRouter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'AudioManagerCore/src/CAmRouter.cpp')
-rw-r--r--AudioManagerCore/src/CAmRouter.cpp518
1 files changed, 311 insertions, 207 deletions
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<am_Route_s> & 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<am_Route_s> & 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<am_Route_s> & 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<CAmVertex<am_RoutingNodeData_s,uint16_t>*> & list) {
- std::cout << "Node " << node.getIndex() << ":";
- ((CAmRoutingNode &)node).getData().trace();
- std::cout << "-->[";
- int count = 0;
- std::for_each(list.begin(), list.end(), [&](const CAmVertex<am_RoutingNodeData_s,uint16_t>* refVertex){
- am::CAmNode<am::am_RoutingNodeData_s>* 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<std::vector<CAmRoutingNode*>> 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<am_Route_s> & 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<CAmVertex<am_RoutingNodeData_s,uint16_t>*> & list) {
+ std::cout << "Node " << node.getIndex() << ":";
+ ((CAmRoutingNode &)node).getData().trace();
+ std::cout << "-->[";
+ int count = 0;
+ std::for_each(list.begin(), list.end(), [&](const CAmVertex<am_RoutingNodeData_s,uint16_t>* refVertex){
+ am::CAmNode<am::am_RoutingNodeData_s>* 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<am_CustomConnectionFormat_t> 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<CAmRoutingNode*> & nodes, std::vector<am_Route_s> & result)
{
std::vector<am_RoutingElement_s>::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<CAmRoutingNode*> & resultPath)
+am_Error_e CAmRouter::cfPermutationsForPath(am_Route_s shortestRoute, std::vector<CAmRoutingNode*> resultNodesPath, std::vector<am_Route_s>& resultPath)
{
- mRoutingGraph.getShortestPath(source, destination, resultPath);
+ std::vector<am_Route_s> 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<CAmRoutingNode*> & resultNodesPath)
+am_Error_e CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, std::vector<am_Route_s> & resultPath)
{
- am_RoutingElement_s * element;
+ am_Error_e err = E_OK;
+ am_Route_s shortestRoute;
+ std::vector<CAmRoutingNode*> 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<void(const am_GraphPathPosition_e, CAmRoutingNode &)> 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<am_Route_s> & resultPath,
- std::vector<std::vector<CAmRoutingNode*>> & 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<CAmRoutingNode*> & 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<CAmRoutingNode*> & 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<am_Route_s> result;
- am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector<CAmRoutingNode*> &)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:"<<nextRoute.sourceID<<" to sink:"<<nextRoute.sinkID<<"\n";
-#endif
+ element->domainID = routingData.data.source->domainID;
+ element->sourceID = routingData.data.source->sourceID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ });
+
+ if(shortestRoute.route.size())
+ {
+ std::vector<am_Route_s> resultPath;
+ cfPermutationsForPath(shortestRoute, resultNodesPath, resultPath);
+ if(resultPath.size())
+ path = resultPath.front();
+ }
+}
+
+int CAmRouter::insertPostion(const std::vector<CAmRoutingNode*>& path, const std::vector<std::vector<CAmRoutingNode*> >& 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<am_Route_s> & resultPath,
+ std::vector<std::vector<CAmRoutingNode*>> & 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<am_Route_s> paths;
+ std::vector<am_domainID_t> 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<CAmRoutingNode*> & 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<mMaxPathCount && it!=paths.end(); it++)
+ {
+ if(cfPermutationsForPath(*it, resultNodesPath[it-paths.begin()], resultPath)==E_UNKNOWN)
+ errorsCount++;
else
- {
- resultPath.insert(resultPath.end(), result.begin(), result.end());
-#ifdef TRACE_GRAPH
- std::cout<<"Successfully determined connection formats for path from source:"<<nextRoute.sourceID<<" to sink:"<<nextRoute.sinkID<<"\n";
- for(auto routeConnectionFormats: result)
- {
- for(auto it = routeConnectionFormats.route.begin(); it!=routeConnectionFormats.route.end(); it++)
- {
- am_RoutingElement_s & routingElement = *it;
- std::cout<<"["
- <<routingElement.sourceID
- <<"->"
- <<routingElement.sinkID
- <<" CF:"
- <<routingElement.connectionFormat
- <<" D:"
- <<routingElement.domainID
- <<"]";
- }
- std::cout<<"\n";
- }
-#endif
successCount++;
- }
+ }
+
+ if(successCount)
+ return E_OK;
+ if(errorsCount)
+ return E_NOT_POSSIBLE;
+ return E_OK;
+}
+
+am_Error_e CAmRouter::getFirstNShortestPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink, std::vector<am_Route_s> & 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<am_Route_s> paths;
+ std::vector<std::vector<CAmRoutingNode*>> nodes;
+ std::vector<am_domainID_t> 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<CAmRoutingNode*> & 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<mMaxPathCount && it!=paths.end(); it++)
+ {
+ if(cfPermutationsForPath(*it, nodes[it-paths.begin()], resultPath)==E_UNKNOWN)
+ errorsCount++;
+ else
+ successCount++;
+ }
+
if(successCount)
return E_OK;
if(errorsCount)
@@ -694,92 +854,35 @@ am_Error_e CAmRouter::getAllPaths(CAmRoutingNode & aSource,
return E_OK;
}
-bool CAmRouter::shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID)
+bool CAmRouter::shouldGoInDomain(const std::vector<am_domainID_t> & 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<void(const std::vector<CAmRoutingNode*> & path)> cb)
-{
- if(!includeCycles)
- {
- std::vector<CAmRoutingNode*> visited;
- std::vector<am_domainID_t> 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<CAmRoutingNode*> & visited,
- std::vector<am_domainID_t> & visitedDomains,
- std::function<void(const std::vector<CAmRoutingNode*> & path)> cb)
+bool CAmRouter::shouldGoInDomain(const std::vector<am_domainID_t> & 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<bool> & convertionMatrix,
@@ -872,4 +975,5 @@ am_Error_e CAmRouter::getSourceSinkPossibleConnectionFormats(std::vector<CAmRout
return (E_OK);
}
+
}