/** * @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 #include #include #include /** * 分隔路径标记 */ #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&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 rootlist; std::map > childnodesmaps; std::set traversedarcset; //用与记录inputmodule->outputmodule的总路径 std::vector iopaths; //将模块的stepid与moduleId关联 std::map stepIdToClassNameMaps; }; } } #endif