91 lines
3.3 KiB
C
91 lines
3.3 KiB
C
|
|
/**
|
|||
|
|
* @file CycleChecker.h
|
|||
|
|
* @brief 工作流循环的检查
|
|||
|
|
*
|
|||
|
|
* @author 霍吉东
|
|||
|
|
* @date 2011-10-24
|
|||
|
|
*/
|
|||
|
|
#ifndef PAI_FRAME_WORKFLOWENGINE_CYCLECHECKER_H
|
|||
|
|
#define PAI_FRAME_WORKFLOWENGINE_CYCLECHECKER_H
|
|||
|
|
|
|||
|
|
#include "WorkFlowFile.h"
|
|||
|
|
#include "WorkflowChecker.h"
|
|||
|
|
#include <string>
|
|||
|
|
#include <map>
|
|||
|
|
#include <vector>
|
|||
|
|
#include <set>
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 分隔路径标记
|
|||
|
|
*/
|
|||
|
|
#define CONST_SPLIT_PATH_FLAG "-"
|
|||
|
|
|
|||
|
|
namespace pai {
|
|||
|
|
namespace workflow {
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*@brief 工作流环校验器
|
|||
|
|
* 算法实现:工作流是一个有向图,校验工作流环,实际上是有向图的环检查。
|
|||
|
|
* 先对有向图进行递归深度遍历,在每次遍历过程中记录遍历路径,并记录所走过的弧;
|
|||
|
|
* 判断环的条件是:当前节点存在于父路径中,存在环;否则不存在;
|
|||
|
|
* 如果遍历过程中,如果当前弧是走过的弧,将不遍历当前节点的所有子节点。
|
|||
|
|
*/
|
|||
|
|
class PAI_WORKFLOWENGINE_EXPORT CCycleChecker: public CWorkflowChecker
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
CCycleChecker();
|
|||
|
|
virtual ~CCycleChecker();
|
|||
|
|
/**
|
|||
|
|
*@brief 得到所有的从输入模块到输出模块的路径,非校验器的核心算法
|
|||
|
|
*@param [in]workflow输入的工作流对象
|
|||
|
|
*@param [out]ioPaths所有的iopath路径的集合
|
|||
|
|
*@param [out]strErrorMsg 返回的错误信息
|
|||
|
|
*/
|
|||
|
|
bool GetAllIoPaths(CWorkFlowFile* workflow, std::vector<std::string>&ioPaths, std::string&strErrorMsg);
|
|||
|
|
protected:
|
|||
|
|
/**
|
|||
|
|
* @brief 工作流循环检验器具体方法实现
|
|||
|
|
* @param [in] workflow 待校验的工作流对象
|
|||
|
|
* @param [out] strErrorMsg 返回的错误信息,检验失败函数返回false
|
|||
|
|
*/
|
|||
|
|
virtual bool StepCheck(CWorkFlowFile* workflow, std::string& strErrorMsg);
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
/**
|
|||
|
|
*@brief 从当前节点开始遍历子节点
|
|||
|
|
*@param [in]parentPath
|
|||
|
|
*@param [in]parentId
|
|||
|
|
*@param [in]parentNodeClassNamePath
|
|||
|
|
*@param [out]strErrorMsg 错误信息
|
|||
|
|
*/
|
|||
|
|
void findChildNodeCycle(const std::string& parentPath,int parentId,const std::string& parentNodeClassNamePath,std::string& strErrorMsg);
|
|||
|
|
void InitChildNodesMap(CWorkFlowFile* workflow);
|
|||
|
|
void InitRootlist(CWorkFlowFile* workflow);
|
|||
|
|
bool HasCycle(const std::string& parentNodePath, const std::string& currendNodeId);
|
|||
|
|
std::string GetArc(const std::string& parentNodeId, const std::string& currentNodeId) const;
|
|||
|
|
std::string GetPath(const std::string& parentPath, const std::string& currentId) const;
|
|||
|
|
/**
|
|||
|
|
*@brief 得到从inputmodule到outpumodule的以classname连接的路径
|
|||
|
|
*@param [int]parentNodeClassNamePath 当前节点的父节点路径(以classname连接)
|
|||
|
|
*@param [in]currentId 当前节点的id 当前路径中含有的输入模块(根节点),在set容器中的位置
|
|||
|
|
*@param [in]rootposition
|
|||
|
|
*/
|
|||
|
|
std::string GetCurrentPath(const std::string& parentNodeClassNamePath, const std::string& currentId);
|
|||
|
|
/**
|
|||
|
|
*@brief 将stepId和classname关联放入stepIdToClassNameMaps之中
|
|||
|
|
*/
|
|||
|
|
void CombineStepIdAndClassName(CWorkFlowFile* workflow);
|
|||
|
|
private:
|
|||
|
|
std::set<int> rootlist;
|
|||
|
|
std::map<int, std::vector<int> > childnodesmaps;
|
|||
|
|
std::set<std::string> traversedarcset;
|
|||
|
|
//用与记录inputmodule->outputmodule的总路径
|
|||
|
|
std::vector<std::string> iopaths;
|
|||
|
|
//将模块的stepid与moduleId关联
|
|||
|
|
std::map<std::string, std::string> stepIdToClassNameMaps;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endif
|