diff options
author | Aleksandar Donchev <Aleksander.Donchev@partner.bmw.de> | 2015-07-06 15:37:49 +0200 |
---|---|---|
committer | Christian Linke <christian.linke@bmw.de> | 2015-07-06 17:14:22 +0100 |
commit | f33da7d02a0f72fab903288f3c840e09f8fa5b3c (patch) | |
tree | 91ef42c2bd16b7fff3bae9003075d03f87d5169b /AudioManagerDaemon/src | |
parent | 580a59d950152a3a6d9b7d6a2b29bd3a2e64fc0c (diff) | |
download | audiomanager-f33da7d02a0f72fab903288f3c840e09f8fa5b3c.tar.gz |
*Routing bug fixing and enhancment.
Signed-off-by:Christian Linke<christian.linke@bmw.de>
Diffstat (limited to 'AudioManagerDaemon/src')
-rw-r--r-- | AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp | 2 | ||||
-rw-r--r-- | AudioManagerDaemon/src/CAmRouter.cpp | 1080 |
2 files changed, 480 insertions, 602 deletions
diff --git a/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp b/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp index 3f031ff..46163db 100644 --- a/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp +++ b/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp @@ -794,7 +794,7 @@ am_Error_e CAmDatabaseHandlerMap::enterConverterDB(const am_Converter_s & conver if (converterData.converterID != 0 || mFirstStaticConverter) { //check if the ID already exists - if (existGateway(converterData.converterID)) + if (existConverter(converterData.converterID)) { converterID = converterData.converterID; return (E_ALREADY_EXISTS); diff --git a/AudioManagerDaemon/src/CAmRouter.cpp b/AudioManagerDaemon/src/CAmRouter.cpp index 30bb4c3..f98bf11 100644 --- a/AudioManagerDaemon/src/CAmRouter.cpp +++ b/AudioManagerDaemon/src/CAmRouter.cpp @@ -36,21 +36,6 @@ namespace am { -void getSourceSinkPossibleConnectionFormats(std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator iteratorSource, - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator iteratorSink, - std::vector<am_CustomConnectionFormat_t> & outConnectionFormats) -{ - CAmNode<am_RoutingNodeData_s> * nodeSink = *iteratorSink; - assert(nodeSink->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SINK); - - CAmNode<am_RoutingNodeData_s> * nodeSource = *iteratorSource; - assert(nodeSource->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE); - - am_Source_s *source = nodeSource->getData().data.source; - am_Sink_s *sink = nodeSink->getData().data.sink; - CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, outConnectionFormats); -} - template <class X> void getMergeConnectionFormats(const X * element, const am_CustomConnectionFormat_t connectionFormat, const std::vector<am_CustomConnectionFormat_t> & listConnectionFormats, @@ -76,9 +61,7 @@ CAmRouter::CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSe mNodeListSources(), mNodeListSinks(), mNodeListGateways(), - mNodeListConverters(), - mpRootSource(0), - mpRootSink(0) + mNodeListConverters() { assert(mpDatabaseHandler); assert(mpControlSender); @@ -101,130 +84,60 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_sourceID_t sourceID returnList.clear(); am_Source_s source; am_Sink_s sink; - mpDatabaseHandler->getSourceInfoDB(sourceID, source); - mpDatabaseHandler->getSinkInfoDB(sinkID, sink); - return getRoute(onlyfree, source, sink, returnList); + 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; } -bool CAmRouter::getAllowedFormatsFromConvMatrix( const std::vector<bool> & convertionMatrix, - const std::vector<am_CustomConnectionFormat_t> & listSourceFormats, - const std::vector<am_CustomConnectionFormat_t> & listSinkFormats, - std::vector<am_CustomConnectionFormat_t> & sourceFormats, - std::vector<am_CustomConnectionFormat_t> & sinkFormats) -{ - const size_t sizeSourceFormats = listSourceFormats.size(); - const size_t sizeSinkFormats = listSinkFormats.size(); - const size_t sizeConvertionMatrix = convertionMatrix.size(); - - if(sizeSourceFormats==0||sizeSinkFormats==0||sizeConvertionMatrix==0||sizeConvertionMatrix!=sizeSinkFormats*sizeSourceFormats) - { - return false; - } - std::vector<bool>::const_iterator iterator = convertionMatrix.begin(); - for (; iterator != convertionMatrix.end(); ++iterator) - { - if( true == *iterator ) - { - const size_t index = iterator-convertionMatrix.begin(); - size_t idx = index%sizeSourceFormats; - sourceFormats.push_back(listSourceFormats.at(idx)); - idx = index/sizeSourceFormats; - sinkFormats.push_back(listSinkFormats.at(idx)); - } - } - return sourceFormats.size()>0; -} - -void CAmRouter::listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats, - std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, - std::vector<am_CustomConnectionFormat_t> & outListFormats) -{ - std::sort(inListSourceFormats.begin(), inListSourceFormats.end()); - std::sort(inListSinkFormats.begin(), inListSinkFormats.end()); - std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(outListFormats, outListFormats.begin()); - set_intersection(inListSourceFormats.begin(), inListSourceFormats.end(), inListSinkFormats.begin(), inListSinkFormats.end(), inserter); -} - - -bool CAmRouter::getRestrictedOutputFormats(const std::vector<bool> & convertionMatrix, - const std::vector<am_CustomConnectionFormat_t> & listSourceFormats, - const std::vector<am_CustomConnectionFormat_t> & listSinkFormats, - const am_CustomConnectionFormat_t connectionFormat, - std::vector<am_CustomConnectionFormat_t> & listFormats) +am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes) { - listFormats.clear(); - std::vector<am_CustomConnectionFormat_t>::const_iterator rowSinkIterator = listSinkFormats.begin(); - std::vector<bool>::const_iterator matrixIterator = convertionMatrix.begin(); - - //find the row number of the sink - rowSinkIterator = find(listSinkFormats.begin(), listSinkFormats.end(), connectionFormat); - int rowNumberSink = rowSinkIterator - listSinkFormats.begin(); - - //go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ... - std::advance(matrixIterator, rowNumberSink); + am_Error_e error; + load(onlyfree); - //iterate line-wise through the matrix and add more formats - do - { - if (*matrixIterator) - { - listFormats.push_back(listSourceFormats.at((matrixIterator - convertionMatrix.begin()) / listSinkFormats.size())); - } - std::advance(matrixIterator, listSinkFormats.size()); - } while (convertionMatrix.end() - matrixIterator > 0); + CAmRoutingNode* pRootSource = sourceNodeWithID(aSource.sourceID); + CAmRoutingNode* pRootSink = sinkNodeWithID(aSink.sinkID); - return listFormats.size(); -} + assert(pRootSource); + assert(pRootSink); -#ifdef EXTENDED_ROUTING_GRAPH -void appendNodes(CAmGraph<am_RoutingNodeData_s, uint16_t> & routingGraph, - const std::vector<am_CustomConnectionFormat_t> & listConnectionFormats, - am_RoutingNodeData_s & nodeData, - std::vector<CAmNode<am_RoutingNodeData_s>*> & nodeList) -{ - std::for_each(listConnectionFormats.begin(), listConnectionFormats.end(), [&](const am_CustomConnectionFormat_t cf){ - nodeData.inConnectionFormat = cf; - nodeList.push_back(&routingGraph.addNode(nodeData)); - }); -} - -void appendNodes(CAmGraph<am_RoutingNodeData_s, uint16_t> & routingGraph, - const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats, - const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats, - const std::vector<bool> & convertionMatrix, - am_RoutingNodeData_s & nodeData, - std::vector<CAmNode<am_RoutingNodeData_s>*> & nodeList) -{ +#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 << "-->"; + std::for_each(list.begin(), list.end(), [&](const CAmVertex<am_RoutingNodeData_s,uint16_t>* refVertex){ + am::CAmNode<am::am_RoutingNodeData_s>* data = refVertex->getNode(); + std::cout << "Node " << data->getIndex() << " :"; + data->getData().trace(); + }); + std::cout << std::endl; + }); +#endif - std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; - if(CAmRouter::getAllowedFormatsFromConvMatrix(convertionMatrix, sourceConnectionFormats, sinkConnectionFormats, sourceFormats, sinkFormats)) - { - for(size_t i = 0; i < sourceFormats.size(); i++) - { - nodeData.inConnectionFormat = sinkFormats[i]; - nodeData.outConnectionFormat = sourceFormats[i]; - nodeList.push_back(&routingGraph.addNode(nodeData)); - } - } + std::vector<std::vector<CAmRoutingNode*>> pathNodes; + error = getAllPaths(*pRootSource, *pRootSink, listRoutes, pathNodes); + return error; } -#endif -am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes) +void CAmRouter::load(const bool onlyFree) { clear(); - mOnlyFreeConversionNodes = onlyfree; - // We need to copy the sinks, sources, converters, gateways for SQLite data store. + mOnlyFreeConversionNodes = onlyFree; + #if defined (WITH_DATABASE_STORAGE) std::deque<am_Source_s> listSources; std::deque<am_Sink_s> listSinks; std::deque<am_Gateway_s> listGateways; std::deque<am_Converter_s> listConverters; #endif - am_Error_e error = E_OK; - am_RoutingNodeData_s nodeDataSrc; - nodeDataSrc.type = NodeDataType::SOURCE; + nodeDataSrc.type = CAmNodeDataType::SOURCE; mpDatabaseHandler->enumerateSources([&](const am_Source_s & obj){ #if defined (WITH_DATABASE_STORAGE) listSources.push_back(obj); @@ -232,14 +145,10 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataSrc.data.source = (am_Source_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listConnectionFormats, nodeDataSrc, mNodeListSources); -#else - mNodeListSources.push_back(&mRoutingGraph.addNode(nodeDataSrc)); -#endif + mNodeListSources[nodeDataSrc.data.source->domainID].push_back(&mRoutingGraph.addNode(nodeDataSrc)); }); am_RoutingNodeData_s nodeDataSink; - nodeDataSink.type = NodeDataType::SINK; + nodeDataSink.type = CAmNodeDataType::SINK; mpDatabaseHandler->enumerateSinks([&](const am_Sink_s & obj){ #if defined (WITH_DATABASE_STORAGE) listSinks.push_back(obj); @@ -247,14 +156,10 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataSink.data.sink = (am_Sink_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listConnectionFormats, nodeDataSink, mNodeListSinks); -#else - mNodeListSinks.push_back(&mRoutingGraph.addNode(nodeDataSink)); -#endif + mNodeListSinks[nodeDataSink.data.sink->domainID].push_back(&mRoutingGraph.addNode(nodeDataSink)); }); am_RoutingNodeData_s nodeDataGateway; - nodeDataGateway.type = NodeDataType::GATEWAY; + nodeDataGateway.type = CAmNodeDataType::GATEWAY; mpDatabaseHandler->enumerateGateways([&](const am_Gateway_s & obj){ #if defined (WITH_DATABASE_STORAGE) listGateways.push_back(obj); @@ -262,14 +167,10 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataGateway.data.gateway = (am_Gateway_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listSourceFormats, obj.listSinkFormats, obj.convertionMatrix, nodeDataGateway, mNodeListGateways); -#else - mNodeListGateways.push_back(&mRoutingGraph.addNode(nodeDataGateway)); -#endif + mNodeListGateways[nodeDataGateway.data.gateway->controlDomainID].push_back(&mRoutingGraph.addNode(nodeDataGateway)); }); am_RoutingNodeData_s nodeDataConverter; - nodeDataConverter.type = NodeDataType::CONVERTER; + nodeDataConverter.type = CAmNodeDataType::CONVERTER; mpDatabaseHandler->enumerateConverters([&](const am_Converter_s & obj){ #if defined (WITH_DATABASE_STORAGE) listConverters.push_back(obj); @@ -277,543 +178,356 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataConverter.data.converter = (am_Converter_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listSourceFormats, obj.listSinkFormats, obj.convertionMatrix, nodeDataConverter, mNodeListConverters); -#else - mNodeListConverters.push_back(&mRoutingGraph.addNode(nodeDataConverter)); -#endif + mNodeListConverters[nodeDataConverter.data.converter->domainID].push_back(&mRoutingGraph.addNode(nodeDataConverter)); }); - buildGraph(aSource, aSink); - -#ifdef EXTENDED_ROUTING_GRAPH - std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> pathNodes; - getShortestPath(listRoutes, pathNodes); -#else - std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> pathNodes; - error = getAllPaths(listRoutes, pathNodes); +#ifdef ROUTING_BUILD_CONNECTIONS + constructConverterConnections(); + constructGatewayConnections(); + constructSourceSinkConnections(); #endif - return error; } -void CAmRouter::buildGraph( const am_Source_s & aSource, const am_Sink_s & aSink) +void CAmRouter::clear() { - //build up a topological sorted graph -#ifdef EXTENDED_ROUTING_GRAPH - mpRootSource = (am_Source_s*)&aSource; - mpRootSink = (am_Sink_s*)&aSink; - for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++) - { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1); - for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++) - { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2); - if(pRootNodeSource && pRootNodeSink) - { - if(aSource.domainID==aSink.domainID) - routeInSameDomain(*pRootNodeSource, *pRootNodeSink); - else - routeInAnotherDomain(*pRootNodeSource, *pRootNodeSink); - } - } - } -#else - mpRootSource = sourceNodeWithID(aSource.sourceID); - mpRootSink = sinkNodeWithID(aSink.sinkID); - - assert(mpRootSource); - assert(mpRootSink); + mRoutingGraph.clear(); + mNodeListSources.clear(); + mNodeListSinks.clear(); + mNodeListGateways.clear(); + mNodeListConverters.clear(); +} - if(aSource.domainID==aSink.domainID) - { - routeInSameDomain(*mpRootSource, *mpRootSink); - } - else +CAmRoutingNode* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID) +{ + CAmRoutingNode* result = NULL; + for(auto it = mNodeListSinks.begin(); it!=mNodeListSinks.end(); it++) { - routeInAnotherDomain(*mpRootSource, *mpRootSink); + result = sinkNodeWithID(sinkID, it->first); + if(result) + return result; } -#endif -#ifdef TRACE_GRAPH - mRoutingGraph.trace([&](const CAmNode<am_RoutingNodeData_s> & node, const std::vector<CAmVertex<am_RoutingNodeData_s,uint16_t>*> & list) { - std::cout << "Node " << node.getIndex() << " :"; - ((CAmNode<am_RoutingNodeData_s> &)node).getData().trace(); - std::cout << "-->"; - std::for_each(list.begin(), list.end(), [&](const CAmVertex<am_RoutingNodeData_s,uint16_t>* refVertex){ - am::CAmNode<am::am_RoutingNodeData_s>* data = refVertex->getNode(); - std::cout << "Node " << data->getIndex() << " :"; - data->getData().trace(); - }); - std::cout << std::endl; - }); -#endif + return result; } -#ifdef EXTENDED_ROUTING_GRAPH -CAmNode<am_RoutingNodeData_s>* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat) +CAmRoutingNode* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID) { - auto iter = std::find_if(mNodeListSinks.begin(), mNodeListSinks.end(), [sinkID, connectionFormat](CAmNode<am_RoutingNodeData_s>* node){ - return node->getData().data.sink->sinkID==sinkID && node->getData().inConnectionFormat==connectionFormat; + CAmRoutingNode* result = NULL; + std::vector<CAmRoutingNode*> & value = mNodeListSinks[domainID]; + auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){ + return node->getData().data.sink->sinkID==sinkID; }); - if(iter!=mNodeListSinks.end()) - return *iter; - return NULL; + if(iter!=value.end()) + result = *iter; + return result; } -CAmNode<am_RoutingNodeData_s>* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID, const am_CustomConnectionFormat_t connectionFormat) +CAmRoutingNode* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID) { - auto iter = std::find_if(mNodeListSources.begin(), mNodeListSources.end(), [sourceID, connectionFormat](CAmNode<am_RoutingNodeData_s>* node){ - return node->getData().data.source->sourceID==sourceID && node->getData().inConnectionFormat==connectionFormat; - }); - if(iter!=mNodeListSources.end()) - return *iter; - return NULL; + CAmRoutingNode* result = NULL; + for(auto it = mNodeListSources.begin(); it!=mNodeListSources.end(); it++) + { + result = sourceNodeWithID(sourceID, it->first); + if(result) + return result; + } + return result; } -#else -CAmNode<am_RoutingNodeData_s>* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID) + +CAmRoutingNode* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID) { - auto iter = std::find_if(mNodeListSinks.begin(), mNodeListSinks.end(), [sinkID](CAmNode<am_RoutingNodeData_s>* node){ - return node->getData().data.sink->sinkID==sinkID; + CAmRoutingNode* result = NULL; + std::vector<CAmRoutingNode*> & value = mNodeListSources[domainID]; + auto iter = std::find_if(value.begin(), value.end(), [sourceID](CAmRoutingNode* node){ + return node->getData().data.source->sourceID==sourceID; }); - if(iter!=mNodeListSinks.end()) - return *iter; - return NULL; + if(iter!=value.end()) + result = *iter; + return result; } -CAmNode<am_RoutingNodeData_s>* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID) +CAmRoutingNode* CAmRouter::converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID) { - auto iter = std::find_if(mNodeListSources.begin(), mNodeListSources.end(), [sourceID](CAmNode<am_RoutingNodeData_s>* node){ - return node->getData().data.source->sourceID==sourceID; + CAmRoutingNode* result = NULL; + std::vector<CAmRoutingNode*> & value = mNodeListConverters[domainID]; + auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){ + return node->getData().data.converter->sinkID==sinkID; }); - if(iter!=mNodeListSources.end()) - return *iter; - return NULL; + if(iter!=value.end()) + result = *iter; + return result; } -#endif -void CAmRouter::connectNodes(const CAmNode<am_RoutingNodeData_s> & node1, - const CAmNode<am_RoutingNodeData_s> & node2, - const am_CustomConnectionFormat_t vertexData, - const int16_t weight) +CAmRoutingNode* CAmRouter::gatewayNodeWithSinkID(const am_sinkID_t sinkID) { - if( !mRoutingGraph.isAnyVertex(node1, node2) ) - mRoutingGraph.connectNodes(node1, node2, vertexData, weight); + for(auto it = mNodeListGateways.begin(); it!=mNodeListGateways.end(); it++) + { + std::vector<CAmRoutingNode*> & value = it->second; + auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){ + return node->getData().data.gateway->sinkID==sinkID; + }); + if(iter!=value.end()) + return *iter; + } + return NULL; } -bool CAmRouter::routeInSameDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink) +#ifdef ROUTING_BUILD_CONNECTIONS + +void CAmRouter::constructSourceSinkConnections() { - am_RoutingNodeData_s & sourceData = aSource.getData(); - am_RoutingNodeData_s & sinkData = aSink.getData(); - am_Source_s * source = sourceData.data.source; - //If exists connection return - if( mRoutingGraph.isAnyVertex(aSource, aSink)) - return true; - if( aSource.getStatus()!=GES_NOT_VISITED ) - return false; - bool result = false; - aSource.setStatus(GES_IN_PROGRESS); -#ifdef EXTENDED_ROUTING_GRAPH - if(sourceData.inConnectionFormat!=sinkData.inConnectionFormat) // it is not possible to connect them directly - { -#else - am_Sink_s * sink = sinkData.data.sink; - std::vector<am_CustomConnectionFormat_t> listFormats; - CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listFormats); - if(listFormats.size()==0) // it is not possible to connect them directly + std::vector<am_CustomConnectionFormat_t> intersection; + for(auto itSrc = mNodeListSources.begin(); itSrc!=mNodeListSources.end(); itSrc++) { -#endif - bool availableConverter = false; - for(auto iter = mNodeListConverters.begin(); iter!=mNodeListConverters.end(); iter++) + for(auto it = itSrc->second.begin(); it!=itSrc->second.end(); it++) { - CAmNode<am_RoutingNodeData_s>* converterNode = *iter; - am_RoutingNodeData_s & converterNodeData = converterNode->getData(); - am_Converter_s * converter = converterNodeData.data.converter; - //Get only converters with end point in current source domain - if( converterNode->getStatus()==GES_NOT_VISITED && converter->domainID==source->domainID && (!mOnlyFreeConversionNodes || !isComponentConnected(*converter))) + CAmRoutingNode* srcNode = *it; + am_RoutingNodeData_s & srcNodeData = srcNode->getData(); + am_Source_s * source = srcNodeData.data.source; + for(auto itSink = mNodeListSinks[itSrc->first].begin(); itSink!=mNodeListSinks[itSrc->first].end(); itSink++) { - //Get the sink connected to the converter... - converterNode->setStatus(GES_IN_PROGRESS); -#ifdef EXTENDED_ROUTING_GRAPH - CAmNode<am_RoutingNodeData_s> *converterSinkNode = this->sinkNodeWithID(converter->sinkID, converterNodeData.inConnectionFormat); -#else - CAmNode<am_RoutingNodeData_s> *converterSinkNode = this->sinkNodeWithID(converter->sinkID); -#endif - if(converterSinkNode) + CAmRoutingNode* sinkNode = *itSink; + am_RoutingNodeData_s & sinkNodeData = sinkNode->getData(); + am_Sink_s * sink = sinkNodeData.data.sink; + + intersection.clear(); + //Check whether the hidden sink formats match the source formats... + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, intersection); + if(intersection.size()>0)//OK match source -> sink { - am_RoutingNodeData_s & converterSinkData = converterSinkNode->getData(); - //Check whether the hidden sink formats match the source formats... -#ifdef EXTENDED_ROUTING_GRAPH - if(sourceData.inConnectionFormat==converterSinkData.inConnectionFormat) - { - CAmNode<am_RoutingNodeData_s> *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converterNodeData.outConnectionFormat); - if(converterSourceNode) - { - am_RoutingNodeData_s & converterSourceData = converterSourceNode->getData(); - if(converterSourceData.inConnectionFormat==converterSinkData.outConnectionFormat) - { - availableConverter=true; - // Connection source->conv_sink->converter->conv_source - this->connectNodes(aSource, *converterSinkNode, converterNodeData.inConnectionFormat, 1); - this->connectNodes(*converterSinkNode, *converterNode, converterNodeData.inConnectionFormat, 1); - this->connectNodes(*converterNode, *converterSourceNode, converterNodeData.outConnectionFormat, 1); - result|=this->routeInSameDomain(*converterSourceNode, aSink); - } - } - } - else - { - //the converter is not suitable, lets try to find paths through another domains - bool alternResult = this->routeInAnotherDomain(aSource, *converterSinkNode); - if(alternResult) - { - CAmNode<am_RoutingNodeData_s> *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converterNodeData.outConnectionFormat); - if(converterSourceNode) - { - am_RoutingNodeData_s & converterSourceData = converterSourceNode->getData(); - if(converterSourceData.inConnectionFormat==converterSinkData.outConnectionFormat) - { - // Connection source->conv_sink->converter->conv_source - this->connectNodes(*converterSinkNode, *converterNode, converterNodeData.inConnectionFormat, 1); - this->connectNodes(*converterNode, *converterSourceNode, converterNodeData.outConnectionFormat, 1); - result|=this->routeInSameDomain(*converterSourceNode, aSink); - } - } - } - } -#else - am_Sink_s * nextSink = converterSinkData.data.sink; - std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection; - //Check whether the hidden sink formats match the source formats... - CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, nextSink->listConnectionFormats, intersection); - if(intersection.size()>0)//OK match source -> conv_sink - { - //Are there convertible formats or not - if(CAmRouter::getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) - { - availableConverter=true; - CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(converter->sourceID); - assert(nextSourceNode); - //Connections source->hidden_sink->converter->hidden_source - this->connectNodes(aSource, *converterSinkNode, CF_UNKNOWN, 1); - this->connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1); - this->connectNodes(*converterNode, *nextSourceNode, CF_UNKNOWN, 1); - //Go ahead with hidden_source and sink - result|=this->routeInSameDomain(*nextSourceNode, aSink); - } - } - else - { - //the converter is not suitable, lets try to find paths through another domains - bool alternResult = this->routeInAnotherDomain(aSource, *converterSinkNode); - if(alternResult) - { - if(CAmRouter::getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) - { - CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(converter->sourceID); - assert(nextSourceNode); - //Connections source->hidden_sink->converter->hidden_source - this->connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1); - this->connectNodes(*converterNode, *nextSourceNode, CF_UNKNOWN, 1); - //Go ahead with hidden_source and sink - result|=this->routeInSameDomain(*nextSourceNode, aSink); - } - } - } -#endif + mRoutingGraph.connectNodes(*srcNode, *sinkNode, CF_UNKNOWN, 1); } - converterNode->setStatus(GES_NOT_VISITED); } } - if(!availableConverter) - { - aSource.setStatus(GES_NOT_VISITED); - result|=this->routeInAnotherDomain(aSource, aSink); - } - } - else - { - //success only if the source can be connected with the sink -#ifdef EXTENDED_ROUTING_GRAPH - this->connectNodes(aSource, aSink, sourceData.inConnectionFormat, 1); -#else - this->connectNodes(aSource, aSink, CF_UNKNOWN, 1); -#endif - result=true; } - aSource.setStatus(GES_NOT_VISITED); - return result; } -bool CAmRouter::routeInAnotherDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink) +void CAmRouter::constructGatewayConnections() { - am_RoutingNodeData_s & sourceData = aSource.getData(); - am_RoutingNodeData_s & sinkData = aSink.getData(); - am_Source_s * source = sourceData.data.source; - am_Sink_s * sink = sinkData.data.sink; - - if( mRoutingGraph.isAnyVertex(aSource, aSink)) - return true; - if( aSource.getStatus()!=GES_NOT_VISITED ) - return false; - aSource.setStatus(GES_IN_PROGRESS); -#ifndef EXTENDED_ROUTING_GRAPH - std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection; -#endif - bool result = false; + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; for(auto iter = mNodeListGateways.begin(); iter!=mNodeListGateways.end(); iter++) { - CAmNode<am_RoutingNodeData_s>* gatewayNode = *iter; - am_RoutingNodeData_s & gatewayNodeData = gatewayNode->getData(); - am_Gateway_s * gateway = gatewayNodeData.data.gateway; - //Get only gateways with end point in current source domain - if( - gatewayNode->getStatus()==GES_NOT_VISITED && - gateway->domainSinkID==source->domainID && - (!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) ) + for(auto it = iter->second.begin(); it!=iter->second.end(); it++) { - //Get the sink connected to the gateway... - gatewayNode->setStatus(GES_IN_PROGRESS); -#ifdef EXTENDED_ROUTING_GRAPH - CAmNode<am_RoutingNodeData_s> *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID, gatewayNodeData.inConnectionFormat); -#else - CAmNode<am_RoutingNodeData_s> *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID); -#endif - - if(gatewaySinkNode) + CAmRoutingNode* gatewayNode = *it; + am_RoutingNodeData_s & gatewayNodeData = gatewayNode->getData(); + am_Gateway_s * gateway = gatewayNodeData.data.gateway; + //Get only gateways with end point in current source domain + if(!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) { - am_RoutingNodeData_s & gatewaySinkData = gatewaySinkNode->getData(); - //Check whether the hidden sink formats match the source formats... - -#ifdef EXTENDED_ROUTING_GRAPH - if(sourceData.inConnectionFormat==gatewaySinkData.inConnectionFormat) - { - //Check if the gateway is able to convert any formats... - CAmNode<am_RoutingNodeData_s> *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gatewayNodeData.outConnectionFormat); - if(gatewaySourceNode) - { - am_RoutingNodeData_s & gatewaySourceData = gatewaySourceNode->getData(); - if(gatewaySourceData.inConnectionFormat==gatewayNodeData.outConnectionFormat) - { - am_Source_s * gatewaySource = gatewaySourceData.data.source; - //Connections source->hidden_sink->gateway->hidden_source - this->connectNodes(aSource, *gatewaySinkNode, gatewayNodeData.inConnectionFormat, 1); - this->connectNodes(*gatewaySinkNode, *gatewayNode, gatewayNodeData.inConnectionFormat, 1); - this->connectNodes(*gatewayNode, *gatewaySourceNode, gatewayNodeData.outConnectionFormat, 1); - //Go ahead with hidden_source and sink - if(gatewaySource->domainID==sink->domainID) - result|=this->routeInSameDomain(*gatewaySourceNode, aSink); - else - result|=this->routeInAnotherDomain(*gatewaySourceNode, aSink); - } - } - } - else + //Get the sink connected to the gateway... + CAmRoutingNode *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID, gateway->domainSinkID); + if(gatewaySinkNode) { - //the gateway is not suitable, lets try to find paths within this domains - bool alternResult = this->routeInSameDomain(aSource, *gatewaySinkNode); - if(alternResult) + am_RoutingNodeData_s & gatewaySinkData = gatewaySinkNode->getData(); + //Check whether the hidden sink formats match the source formats... + sourceFormats.clear(); + sinkFormats.clear(); + if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) { - CAmNode<am_RoutingNodeData_s> *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gatewayNodeData.outConnectionFormat); + CAmRoutingNode *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gateway->domainSourceID); if(gatewaySourceNode) { - am_RoutingNodeData_s & gatewaySourceData = gatewaySourceNode->getData(); - if(gatewaySourceData.inConnectionFormat==gatewayNodeData.outConnectionFormat) - { - am_Source_s * gatewaySource = gatewaySourceData.data.source; - //Connections source->hidden_sink->gateway->hidden_source - this->connectNodes(aSource, *gatewaySinkNode, gatewayNodeData.inConnectionFormat, 1); - this->connectNodes(*gatewaySinkNode, *gatewayNode, gatewayNodeData.inConnectionFormat, 1); - this->connectNodes(*gatewayNode, *gatewaySourceNode, gatewayNodeData.outConnectionFormat, 1); - //Go ahead with hidden_source and sink - if(gatewaySource->domainID==sink->domainID) - result|=this->routeInSameDomain(*gatewaySourceNode, aSink); - else - result|=this->routeInAnotherDomain(*gatewaySourceNode, aSink); - } + //Connections hidden_sink->gateway->hidden_source + mRoutingGraph.connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1); + mRoutingGraph.connectNodes(*gatewayNode, *gatewaySourceNode, CF_UNKNOWN, 1); } } } -#else - am_Sink_s * nextSink = gatewaySinkData.data.sink; - std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection; - CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, nextSink->listConnectionFormats, intersection); - if(intersection.size()>0)//OK match source -> conv_sink - { - //Check if the gateway is able to convert any formats... - if(CAmRouter::getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) - { - CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(gateway->sourceID); - assert(nextSourceNode); - am_Source_s * nextSource = nextSourceNode->getData().data.source; - //Connections source->hidden_sink->gateway->hidden_source - this->connectNodes(aSource, *gatewaySinkNode, CF_UNKNOWN, 1); - this->connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1); - this->connectNodes(*gatewayNode, *nextSourceNode, CF_UNKNOWN, 1); - //Go ahead with hidden_source and sink - if(nextSource->domainID==sink->domainID) - result|=this->routeInSameDomain(*nextSourceNode, aSink); - else - result|=this->routeInAnotherDomain(*nextSourceNode, aSink); - } - } - else - { - //the gateway is not suitable, lets try to find paths within this domains - aSource.setStatus(GES_NOT_VISITED); + } + } + } +} + +void CAmRouter::constructConverterConnections() +{ + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; - bool alternResult = this->routeInSameDomain(aSource, *gatewaySinkNode); - if(alternResult) + for(auto iter = mNodeListConverters.begin(); iter!=mNodeListConverters.end(); iter++) + { + for(auto it = iter->second.begin(); it!=iter->second.end(); it++) + { + CAmRoutingNode* converterNode = *it; + am_RoutingNodeData_s & converterNodeData = converterNode->getData(); + am_Converter_s * converter = converterNodeData.data.converter; + //Get only converters with end point in current source domain + if(!mOnlyFreeConversionNodes || !isComponentConnected(*converter)) + { + //Get the sink connected to the converter... + CAmRoutingNode *converterSinkNode = this->sinkNodeWithID(converter->sinkID, converter->domainID); + if(converterSinkNode) + { + am_RoutingNodeData_s & converterSinkData = converterSinkNode->getData(); + //Check whether the hidden sink formats match the source formats... + sourceFormats.clear(); + sinkFormats.clear(); + if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) { - if(CAmRouter::getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) + CAmRoutingNode *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converter->domainID); + if(converterSourceNode) { - CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(gateway->sourceID); - assert(nextSourceNode); - am_Source_s * nextSource = nextSourceNode->getData().data.source; - //Connections source->hidden_sink->gateway->hidden_source - this->connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1); - this->connectNodes(*gatewayNode, *nextSourceNode, CF_UNKNOWN, 1); - //Go ahead with hidden_source and sink - if(nextSource->domainID==sink->domainID) - result|=this->routeInSameDomain(*nextSourceNode, aSink); - else - result|=this->routeInAnotherDomain(*nextSourceNode, aSink); + //Connections hidden_sink->converter->hidden_source + mRoutingGraph.connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1); + mRoutingGraph.connectNodes(*converterNode, *converterSourceNode, CF_UNKNOWN, 1); } } } -#endif } - gatewayNode->setStatus(GES_NOT_VISITED); } } - aSource.setStatus(GES_NOT_VISITED); - return result; } +#else -#ifdef EXTENDED_ROUTING_GRAPH -void CAmRouter::getShortestPath(const am_Source_s & aSource, - const am_Sink_s & aSink, - std::vector<am_Route_s> & resultPath, - std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath) +void CAmRouter::getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list) { - std::vector<CAmNode<am_RoutingNodeData_s>*> listTargets; - std::vector<CAmNode<am_RoutingNodeData_s>*> * pathNodes; - am_Route_s *path; - am_RoutingElement_s * element; - std::function<void(const am_GraphPathPosition_e, CAmNode<am_RoutingNodeData_s> &)> cb = [&](const am_GraphPathPosition_e pos, CAmNode<am_RoutingNodeData_s> & object) + am_RoutingNodeData_s & srcNodeData = ((CAmRoutingNode*)&node)->getData(); + std::vector<am_CustomConnectionFormat_t> intersection; + am_Source_s * source = srcNodeData.data.source; + std::vector<CAmRoutingNode*> & sinks = mNodeListSinks[source->domainID]; + for(auto itSink = sinks.begin(); itSink!=sinks.end(); itSink++) { - if(pos==GRAPH_PATH_START) + CAmRoutingNode* sinkNode = *itSink; + am_RoutingNodeData_s & sinkNodeData = sinkNode->getData(); + am_Sink_s * sink = sinkNodeData.data.sink; + + intersection.clear(); + //Check whether the hidden sink formats match the source formats... + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, intersection); + if(intersection.size()>0)//OK match source -> sink { - resultNodesPath.emplace_back(); - pathNodes=&resultNodesPath.back(); - resultPath.emplace_back(); - path= &resultPath.back(); - path->sinkID = aSink.sinkID; - path->sourceID = aSource.sourceID; + list.emplace_back(sinkNode, CF_UNKNOWN, 1); } - pathNodes->insert(pathNodes->begin(), (CAmNode<am_RoutingNodeData_s>*)&object); + } +} - am_RoutingNodeData_s & routingData = object.getData(); +void CAmRouter::getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list) +{ + am_RoutingNodeData_s & sinkNodeData = ((CAmRoutingNode*)&node)->getData(); + std::vector<am_CustomConnectionFormat_t> intersection; + am_Sink_s * sink = sinkNodeData.data.sink; - if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK) + CAmRoutingNode *converterNode = converterNodeWithSinkID(sink->sinkID, sink->domainID); + if(converterNode) + { + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_RoutingNodeData_s & converterData = converterNode->getData(); + am_Converter_s * converter = converterData.data.converter; + if(!mOnlyFreeConversionNodes || !isComponentConnected(*converter)) { - auto iter = path->route.emplace(path->route.begin()); - element = &(*iter); - - element->domainID = routingData.data.sink->domainID; - element->sinkID = routingData.data.sink->sinkID; - element->connectionFormat = routingData.inConnectionFormat; - + if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) + list.emplace_back(converterNode, CF_UNKNOWN, 1); } - else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE) + } + else + { + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + CAmRoutingNode *gatewayNode = gatewayNodeWithSinkID(sink->sinkID); + if(gatewayNode) { - element->domainID = routingData.data.source->domainID; - element->sourceID = routingData.data.source->sourceID; - element->connectionFormat = routingData.inConnectionFormat; + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_RoutingNodeData_s & gatewayData = gatewayNode->getData(); + am_Gateway_s * gateway = gatewayData.data.gateway; + if(!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) + { + if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) + list.emplace_back(gatewayNode, CF_UNKNOWN, 1); + } } - }; + } +} - for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++) - { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2); - if(pRootNodeSink) - listTargets.push_back(pRootNodeSink); - } - if(listTargets.size()) +void CAmRouter::getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list) +{ + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_RoutingNodeData_s & converterNodeData = ((CAmRoutingNode*)&node)->getData(); + am_Converter_s * converter = converterNodeData.data.converter; + //Get only converters with end point in current source domain + if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) { - for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++) + CAmRoutingNode *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converter->domainID); + if(converterSourceNode) { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1); - if(pRootNodeSource) - { - mRoutingGraph.getShortestPath(*pRootNodeSource, listTargets, cb); - } + list.emplace_back(converterSourceNode, CF_UNKNOWN, 1); } } } -void CAmRouter::getShortestPath(std::vector<am_Route_s> & routes, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & nodes) +void CAmRouter::getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list) { - getShortestPath(*mpRootSource, *mpRootSink, routes, nodes); + am_RoutingNodeData_s & gatewayNodeData = ((CAmRoutingNode*)&node)->getData(); + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_Gateway_s * gateway = gatewayNodeData.data.gateway; + if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) + { + CAmRoutingNode *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gateway->domainSourceID); + if(gatewaySourceNode) + { + //Connections hidden_sink->gateway->hidden_source + list.emplace_back(gatewaySourceNode, CF_UNKNOWN, 1); + } + } } -void CAmRouter::getShortestPath(const am_Source_s & aSource, const am_Sink_s & aSink, - std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultPath) +void CAmRouter::getVerticesForNode( + const CAmRoutingNode & node, + CAmRoutingListVertices & list + ) { - std::vector<CAmNode<am_RoutingNodeData_s>*> listTargets; - for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++) + am_RoutingNodeData_s & nodeData = ((CAmRoutingNode*)&node)->getData(); + if(nodeData.type==CAmNodeDataType::SOURCE) { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2); - if(pRootNodeSink) - listTargets.push_back(pRootNodeSink); + getVerticesForSource(node, list); } - if(listTargets.size()) + else if(nodeData.type==CAmNodeDataType::SINK) { - for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++) - { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1); - if(pRootNodeSource) - { - mRoutingGraph.getShortestPath(*pRootNodeSource, listTargets, resultPath); - } - } + getVerticesForSink(node, list); + } + else if(nodeData.type==CAmNodeDataType::CONVERTER) + { + getVerticesForConverter(node, list); + } + else if(nodeData.type==CAmNodeDataType::GATEWAY) + { + getVerticesForGateway(node, list); } } -#else -am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes) +#endif + +am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes) { std::vector<am_RoutingElement_s>::iterator routingElementIterator = routeObjects.route.begin(); - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator nodeIterator = nodes.begin(); + std::vector<CAmRoutingNode*>::iterator nodeIterator = nodes.begin(); if( routingElementIterator!= routeObjects.route.end() && nodeIterator!=nodes.end() ) return doConnectionFormatsForPath(routeObjects, nodes, routingElementIterator, nodeIterator); return E_OK; } am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, - std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes, + std::vector<CAmRoutingNode*> & nodes, std::vector<am_RoutingElement_s>::iterator routingElementIterator, - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator nodeIterator) + std::vector<CAmRoutingNode*>::iterator nodeIterator) { am_Error_e returnError = E_NOT_POSSIBLE; std::vector<am_CustomConnectionFormat_t> listConnectionFormats; std::vector<am_CustomConnectionFormat_t> listMergeConnectionFormats; - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator currentNodeIterator = nodeIterator; + std::vector<CAmRoutingNode*>::iterator currentNodeIterator = nodeIterator; std::vector<am_RoutingElement_s>::iterator currentRoutingElementIterator = routingElementIterator; if (currentRoutingElementIterator!=routeObjects.route.begin()) { std::vector<am_CustomConnectionFormat_t> listConnectionFormats; std::vector<am_RoutingElement_s>::iterator tempIterator = (currentRoutingElementIterator-1); - CAmNode<am_RoutingNodeData_s> * currentNode = *currentNodeIterator; + CAmRoutingNode * currentNode = *currentNodeIterator; getSourceSinkPossibleConnectionFormats(currentNodeIterator+1, currentNodeIterator+2, listConnectionFormats); - if(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::GATEWAY) + if(currentNode->getData().type==CAmNodeDataType::GATEWAY) { am_Gateway_s *gateway = currentNode->getData().data.gateway; getMergeConnectionFormats(gateway, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats); } - else if(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::CONVERTER) + else if(currentNode->getData().type==CAmNodeDataType::CONVERTER) { am_Converter_s *converter = currentNode->getData().data.converter; getMergeConnectionFormats(converter, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats); @@ -822,18 +536,18 @@ am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, } else { - CAmNode<am_RoutingNodeData_s> * currentNode = *currentNodeIterator; - assert(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE); + CAmRoutingNode * currentNode = *currentNodeIterator; + assert(currentNode->getData().type==CAmNodeDataType::SOURCE); currentNodeIterator++; assert(currentNodeIterator!=nodes.end()); - CAmNode<am_RoutingNodeData_s> * nodeSink = *currentNodeIterator; - assert(nodeSink->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SINK); + CAmRoutingNode * nodeSink = *currentNodeIterator; + assert(nodeSink->getData().type==CAmNodeDataType::SINK); am_Source_s *source = currentNode->getData().data.source; am_Sink_s *sink = nodeSink->getData().data.sink; - CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listMergeConnectionFormats); + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listMergeConnectionFormats); currentNodeIterator+=1; //now we are on the next converter/gateway } @@ -868,20 +582,17 @@ am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, return (returnError); } -void CAmRouter::getShortestPath(const CAmNode<am_RoutingNodeData_s> & source, - const CAmNode<am_RoutingNodeData_s> & destination, - std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath) -{ - mRoutingGraph.getShortestPath(source, destination, resultPath); -} +#ifdef ROUTING_BUILD_CONNECTIONS -void CAmRouter::getShortestPath(std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath) +void CAmRouter::getShortestPath(const CAmRoutingNode & source, + const CAmRoutingNode & destination, + std::vector<CAmRoutingNode*> & resultPath) { - getShortestPath(*mpRootSource, *mpRootSink, resultPath); + mRoutingGraph.getShortestPath(source, destination, resultPath); } -void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink, - am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath) +void CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, + am_Route_s & resultPath, std::vector<CAmRoutingNode*> & resultNodesPath) { am_RoutingElement_s * element; am_RoutingNodeData_s & sinkNodeData = aSink.getData(); @@ -889,11 +600,11 @@ void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode resultPath.sinkID = sinkNodeData.data.sink->sinkID; resultPath.sourceID = sourceNodeData.data.source->sourceID; - std::function<void(const am_GraphPathPosition_e, CAmNode<am_RoutingNodeData_s> &)> cb = [&](const am_GraphPathPosition_e, CAmNode<am_RoutingNodeData_s> & object) + std::function<void(const am_GraphPathPosition_e, CAmRoutingNode &)> cb = [&](const am_GraphPathPosition_e, CAmRoutingNode & object) { - resultNodesPath.insert(resultNodesPath.begin(), (CAmNode<am_RoutingNodeData_s>*)&object); + resultNodesPath.insert(resultNodesPath.begin(), (CAmRoutingNode*)&object); am_RoutingNodeData_s & routingData = object.getData(); - if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK) + if(routingData.type==CAmNodeDataType::SINK) { auto iter = resultPath.route.emplace(resultPath.route.begin()); element = &(*iter); @@ -901,7 +612,7 @@ void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode element->sinkID = routingData.data.sink->sinkID; element->connectionFormat = CF_UNKNOWN; } - else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE) + else if(routingData.type==CAmNodeDataType::SOURCE) { element->domainID = routingData.data.source->domainID; element->sourceID = routingData.data.source->sourceID; @@ -911,16 +622,25 @@ void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode mRoutingGraph.getShortestPath(aSource, aSink, cb); } -void CAmRouter::getShortestPath(am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath) -{ - getShortestPath(*mpRootSource, *mpRootSink, resultPath, resultNodesPath); -} +#endif -am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink, - std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath) +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; + uint8_t errorsCount = 0, successCount = 0; - mRoutingGraph.getAllPaths(aSource, aSink, [&](const std::vector<CAmNode<am_RoutingNodeData_s>*> & path) { + generateAllPaths(aSource, aSink, cycles, [&](const std::vector<CAmRoutingNode*> & path) { resultNodesPath.push_back(path); resultPath.emplace_back(); am_Route_s & nextRoute = resultPath.back(); @@ -930,7 +650,7 @@ am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNo for(auto it = path.begin(); it!=path.end(); it++) { am_RoutingNodeData_s & routingData = (*it)->getData(); - if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE) + if(routingData.type==CAmNodeDataType::SOURCE) { auto iter = nextRoute.route.emplace(nextRoute.route.end()); element = &(*iter); @@ -938,14 +658,15 @@ am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNo element->sourceID = routingData.data.source->sourceID; element->connectionFormat = CF_UNKNOWN; } - else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK) + else if(routingData.type==CAmNodeDataType::SINK) { element->domainID = routingData.data.sink->domainID; element->sinkID = routingData.data.sink->sinkID; element->connectionFormat = CF_UNKNOWN; } } - am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector<CAmNode<am_RoutingNodeData_s>*> &)path); + + am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector<CAmRoutingNode*> &)path); if(err!=E_OK) { errorsCount++; @@ -984,22 +705,179 @@ am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNo return E_OK; } -am_Error_e CAmRouter::getAllPaths(std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath) +bool CAmRouter::shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID) +{ + if(visitedDomains.size()) + { + if(visitedDomains.back()==nodeDomainID) + return true; + + for(auto it=visitedDomains.begin();it!=visitedDomains.end()-1; it++) + { + if(nodeDomainID==*it) + return false; + } + } + return true; +} + +void CAmRouter::generateAllPaths(const CAmRoutingNode & src, + const CAmRoutingNode & dst, + const bool includeCycles, + std::function<void(const std::vector<CAmRoutingNode*> & path)> cb) { - return getAllPaths(*mpRootSource, *mpRootSink, resultPath, resultNodesPath); + 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) +{ +#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); + } +} -void CAmRouter::clear() +bool CAmRouter::getAllowedFormatsFromConvMatrix( const std::vector<bool> & convertionMatrix, + const std::vector<am_CustomConnectionFormat_t> & listSourceFormats, + const std::vector<am_CustomConnectionFormat_t> & listSinkFormats, + std::vector<am_CustomConnectionFormat_t> & sourceFormats, + std::vector<am_CustomConnectionFormat_t> & sinkFormats) { - mRoutingGraph.clear(); - mNodeListSources.clear(); - mNodeListSinks.clear(); - mNodeListGateways.clear(); - mNodeListConverters.clear(); - mpRootSource=NULL; - mpRootSink=NULL; + const size_t sizeSourceFormats = listSourceFormats.size(); + const size_t sizeSinkFormats = listSinkFormats.size(); + const size_t sizeConvertionMatrix = convertionMatrix.size(); + + if(sizeSourceFormats==0||sizeSinkFormats==0||sizeConvertionMatrix==0||sizeConvertionMatrix!=sizeSinkFormats*sizeSourceFormats) + { + return false; + } + + std::vector<bool>::const_iterator iterator = convertionMatrix.begin(); + for (; iterator != convertionMatrix.end(); ++iterator) + { + if( true == *iterator ) + { + const size_t index = iterator-convertionMatrix.begin(); + size_t idx = index%sizeSourceFormats; + sourceFormats.push_back(listSourceFormats.at(idx)); + idx = index/sizeSourceFormats; + sinkFormats.push_back(listSinkFormats.at(idx)); + } + } + return sourceFormats.size()>0; +} + +void CAmRouter::listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats, + std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, + std::vector<am_CustomConnectionFormat_t> & outListFormats) +{ + std::sort(inListSourceFormats.begin(), inListSourceFormats.end()); + std::sort(inListSinkFormats.begin(), inListSinkFormats.end()); + std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(outListFormats, outListFormats.begin()); + set_intersection(inListSourceFormats.begin(), inListSourceFormats.end(), inListSinkFormats.begin(), inListSinkFormats.end(), inserter); +} + + +bool CAmRouter::getRestrictedOutputFormats(const std::vector<bool> & convertionMatrix, + const std::vector<am_CustomConnectionFormat_t> & listSourceFormats, + const std::vector<am_CustomConnectionFormat_t> & listSinkFormats, + const am_CustomConnectionFormat_t connectionFormat, + std::vector<am_CustomConnectionFormat_t> & listFormats) +{ + listFormats.clear(); + std::vector<am_CustomConnectionFormat_t>::const_iterator rowSinkIterator = listSinkFormats.begin(); + std::vector<bool>::const_iterator matrixIterator = convertionMatrix.begin(); + + //find the row number of the sink + rowSinkIterator = find(listSinkFormats.begin(), listSinkFormats.end(), connectionFormat); + int rowNumberSink = rowSinkIterator - listSinkFormats.begin(); + + //go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ... + std::advance(matrixIterator, rowNumberSink); + + //iterate line-wise through the matrix and add more formats + do + { + if (*matrixIterator) + { + listFormats.push_back(listSourceFormats.at((matrixIterator - convertionMatrix.begin()) / listSinkFormats.size())); + } + std::advance(matrixIterator, listSinkFormats.size()); + } while (convertionMatrix.end() - matrixIterator > 0); + + return listFormats.size(); +} + + +void CAmRouter::getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource, + std::vector<CAmRoutingNode*>::iterator iteratorSink, + std::vector<am_CustomConnectionFormat_t> & outConnectionFormats) +{ + CAmRoutingNode * nodeSink = *iteratorSink; + assert(nodeSink->getData().type==CAmNodeDataType::SINK); + + CAmRoutingNode * nodeSource = *iteratorSource; + assert(nodeSource->getData().type==CAmNodeDataType::SOURCE); + + am_Source_s *source = nodeSource->getData().data.source; + am_Sink_s *sink = nodeSink->getData().data.sink; + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, outConnectionFormats); } |