functional-dag
Loading...
Searching...
No Matches
dag_impl.hpp
1#pragma once
12#include <functional_dag/error_codes.h>
13
14#include <expected>
15#include <iostream>
16#include <unordered_set>
17
18#include "functional_dag/dag_interface.hpp"
19#include "functional_dag/impl/dag_fanout_impl.hpp"
20
21namespace fn_dag {
22using namespace std;
23
29template <typename IDType>
30class _dag_base {
31 public:
33 virtual ~_dag_base() = default;
34
38 virtual bool dag_contains(const IDType &_id) = 0;
39
41 virtual void print() = 0;
42
46 virtual const IDType &get_id() = 0;
47
49 virtual void push_once() = 0;
50};
51
62template <typename OriginType, typename IDType>
63class dag : public _dag_base<IDType> {
64 private:
65 const IDType m_id; // The ID of the DAG itself
66 dag_source<OriginType> *m_source; // The source generator that creates data
68 m_children; // The children of the source to propagate data across
69 unordered_set<IDType> m_children_ids; // An optimization: a quick O(1) set
70 // lookup of the children IDs
71 const _dag_context
72 &g_context; // The shared state across all of the children of this node.
73 thread m_thread; // Thread to run on if this DAG runs multi-threaded.
74
75 public:
86 dag(const IDType &_id, dag_source<OriginType> *_lsource,
87 const _dag_context &_context, bool _startThread)
88 : m_id(_id),
89 m_source(_lsource),
90 m_children(_context),
91 m_children_ids(),
92 g_context(_context) {
93 if (_startThread) m_thread = thread(&dag::start_source, this);
94 }
95
97 ~dag() {
98 if (m_thread.joinable()) m_thread.join();
99 delete m_source;
100 }
101
108 const IDType &get_id() { return m_id; }
109
117 void manual_pump(const unique_ptr<OriginType> _raw_dat) {
118 m_children.fan_out(_raw_dat);
119 }
120
129 bool dag_contains(const IDType &_id) { return m_children_ids.count(_id) > 0; }
130
143 template <typename In, typename Out>
144 [[nodiscard]] expected<IDType, error_codes> add_filter(
145 IDType _newID, dag_node<In, Out> *_new_filter, IDType _on_node) {
146 _internal_dag_node<In, Out, IDType> *new_node;
147 new_node =
148 new _internal_dag_node<In, Out, IDType>(_newID, _new_filter, g_context);
149 m_children_ids.insert(_newID);
150 auto res = m_children.add_node_to_subdag(new_node, _on_node, m_id);
151 if (!res) {
152 delete new_node;
153 }
154 return res;
155 }
156
158 void print() {
159 *g_context.log << "->" << m_id << endl;
160 m_children.print(string(g_context.indent_str));
161 }
162
168 void push_once() {
169 unique_ptr<OriginType> dat = m_source->update();
170 if (dat.get() != nullptr) m_children.fan_out(std::move(dat));
171 }
172
173 private:
178 void start_source() {
179 while (!g_context.filter_off) push_once();
180 }
181};
182}; // namespace fn_dag
Internal node to take data from parent and run children.
Definition dag_node_impl.hpp:25
Interface for all external "mapping" lambdas.
Definition dag_interface.hpp:42
Interface for all external generator lambdas.
Definition dag_interface.hpp:22
void push_once()
Runs the generator and begins propagating the data to it's children.
Definition dag_impl.hpp:168
~dag()
Default deconstructor.
Definition dag_impl.hpp:97
const IDType & get_id()
Simple getter for the ID of the DAG itself.
Definition dag_impl.hpp:108
dag(const IDType &_id, dag_source< OriginType > *_lsource, const _dag_context &_context, bool _startThread)
Constructor of the DAG.
Definition dag_impl.hpp:86
void print()
Simple print function to print the ID of this DAG and it's children.
Definition dag_impl.hpp:158
void manual_pump(const unique_ptr< OriginType > _raw_dat)
Manually pumps some data across the children of the DAG.
Definition dag_impl.hpp:117
expected< IDType, error_codes > add_filter(IDType _newID, dag_node< In, Out > *_new_filter, IDType _on_node)
Adds a new function to the DAG.
Definition dag_impl.hpp:144
bool dag_contains(const IDType &_id)
Checks whether this DAG contains a specific ID.
Definition dag_impl.hpp:129
Definition guid_generated.h:16