10. Dag
使用下述功能需要包含头文件coke/dag.h。
类型别名¶
该别名位于coke命名空间,用于表示一组Dag节点。
template<typename T>
using DagNodeGroup = std::initializer_list<DagNodeRef<T>>;
template<typename T>
using DagNodeVector = std::vector<DagNodeRef<T>>;
coke::DagGraph¶
DagGraph是由协程构成的有向无环图DAG,用于定义节点和管理节点之间的依赖关系,仅当某个节点的前置依赖满足时才会开始执行。
除了有向无环图的概念外,DagGraph引入了强边和弱边的概念。其中强边用于表达强前置依赖,要求必须满足;弱边用于表达弱前置依赖,若某节点有多个弱前置依赖,其中任何一个满足时认为所有弱前置依赖均已经满足。
template<typename T>
class DagGraph;
成员函数¶
-
构造函数/析构函数
该类不可直接构造,需要借助
DagBuilder创建,不可复制,不可移动。DagGraph(const DagGraph &) = delete; ~DagGraph(); -
运行
DAG使用给定的数据
data运行DAG。同一个DagGraph实例可以在多个协程中并发调用DagGraph::run,若用于创建节点的协程未使用全局状态,则同一个DagGraph多次运行也会相互独立,data用于在每次运行时向协程传递数据以及在协程间传递数据,使用者应保证对数据操作的安全性。coke::Task<> run(T &data); -
运行
DAG,void类型特化coke::Task<> run(); -
有效性检查
检查当前
DAG是否有效。一个有效的DagGraph要保证根节点没有任何前置依赖,图中没有环,且所有节点均从根节点可达。bool valid() const; -
打印图的结构
将当前
DAG以DOT语言格式输出到指定的输出流。void dump(std::ostream &os) const;
coke::DagBuilder¶
DagBuilder类用于构建DagGraph,提供了创建和连接节点的功能。
template<typename T>
class DagBuilder;
成员函数¶
-
构造函数
创建一个新的
DAG构建器。DagBuilder(); -
获取根节点的引用
coke::DagNodeRef<T> root(); -
创建新节点
使用协程函数创建一个新的节点,并返回其引用。其中节点名称
name仅用于输出图结构,默认为其节点编号。template<typename FUNC> requires std::constructible_from<coke::dag_node_func_t<T>, FUNC&&> coke::DagNodeRef<T> node(FUNC &&func, const std::string &name = ""); -
连接节点
将
l设置为r的前置依赖,返回r。coke::DagNodeRef<T> connect(coke::DagNodeRef<T> l, coke::DagNodeRef<T> r) const; coke::DagNodeRef<T> weak_connect(coke::DagNodeRef<T> l, coke::DagNodeRef<T> r) const; -
构建
DAG构建
DAG并返回一个共享指针,指向构建的DagGraph。std::shared_ptr<coke::DagGraph<T>> build();
coke::DagNodeRef¶
DagNodeRef提供对DagGraph节点的引用,用于在节点之间创建边。
template<typename T>
class DagBuilder;
成员函数¶
-
复制构造和赋值
支持复制构造和复制赋值。不可直接构造,必须从
DagBuilder创建。DagNodeRef(const DagNodeRef &) = default; DagNodeRef &operator= (const DagNodeRef &) = default; -
连接节点
将当前节点设为另一个节点的前置依赖。若参数为协程,则使用协程函数创建新节点。返回另一个节点。
template<typename FUNC> requires std::constructible_from<coke::dag_node_func_t<T>, FUNC&&> coke::DagNodeRef then(FUNC &&func) const; template<typename FUNC> requires std::constructible_from<coke::dag_node_func_t<T>, FUNC&&> coke::DagNodeRef weak_then(FUNC &&func) const; coke::DagNodeRef then(coke::DagNodeRef r) const; coke::DagNodeRef weak_then(coke::DagNodeRef r) const; -
批量连接
将当前节点设置为这一组节点的前置依赖,返回这个节点组的引用。
const coke::NodeGroup &then(const coke::NodeGroup &group); const coke::NodeGroup &weak_then(const coke::NodeGroup &group); const coke::NodeVector &then(const coke::NodeVector &vec); const coke::NodeVector &weak_then(const coke::NodeVector &vec);
操作符重载¶
提供强连接 (>) 和弱连接 (>=) 的操作符重载,简化节点间的连接语法。
template<typename T, typename U>
requires requires(const DagNodeRef<T> &l, const U &r) { l.then(r); }
const U &operator>(const DagNodeRef<T> &l, const U &r);
template<typename T>
decltype(auto) operator>(const DagNodeGroup<T> &l, const DagNodeRef<T> &r);
template<typename T>
decltype(auto) operator>(const DagNodeVector<T> &l, const DagNodeRef<T> &r);
template<typename T, typename U>
requires requires(const DagNodeRef<T> &l, const U &r) { l.weak_then(r); }
const U &operator>=(const DagNodeRef<T> &l, const U &r);
template<typename T>
decltype(auto) operator>=(const DagNodeGroup<T> &l, const DagNodeRef<T> &r);
template<typename T>
decltype(auto) operator>=(const DagNodeVector<T> &l, const DagNodeRef<T> &r);
示例¶
参考example/ex020-dag.cpp。