functional-dag
Loading...
Searching...
No Matches
dag_fanout_impl.hpp
1#pragma once
12
13#include <functional_dag/error_codes.h>
14
15#include <expected>
16#include <functional_dag/core/dag_utils.hpp>
17#include <functional_dag/impl/dag_node_impl.hpp>
18#include <thread>
19#include <vector>
20
21#include "include/functional_dag/error_codes.h"
22
23namespace fn_dag {
24using namespace std;
25
31template <typename Type, typename IDType>
32class dag_fanout_node {
33 private:
34 const fn_dag::_dag_context &g_context; // Shared state
35 vector<_abstract_internal_dag_node<Type, IDType> *>
36 m_children; // Children to fan-out to
37
42 void _add_node(_abstract_internal_dag_node<Type, IDType> *_new_node) {
43 m_children.push_back(_new_node);
44 }
45
46 public:
56 dag_fanout_node(const _dag_context &_context)
57 : g_context(_context), m_children() {}
58
61 for (auto internal_dag : m_children) delete internal_dag;
62 m_children.clear();
63 }
64
76 void fan_out(unique_ptr<Type> _data) {
77 if (_data.get() == nullptr) return;
78 if (!g_context.run_single_threaded) {
79 vector<thread> child_threads;
80
81 for (auto it : m_children)
82 child_threads.push_back(thread(
83 &fn_dag::_abstract_internal_dag_node<Type, IDType>::run_filter, it,
84 _data.get()));
85
86 for (uint32_t i = 0; i < child_threads.size(); i++)
87 child_threads[i].join();
88 } else
89 for (auto it : m_children) it->run_filter(_data.get());
90 }
91
99 void print(const string &_indent) {
100 const string next_indent = _indent + string(g_context.indent_str);
101
102 for (const auto child : m_children) {
103 *g_context.log << _indent << "->";
104 child->print(next_indent);
105 }
106 }
107
122 template <typename In, typename Out>
123 [[nodiscard]] expected<IDType, error_codes> add_node_to_subdag(
124 _internal_dag_node<In, Out, IDType> *_node_to_add, const IDType _onto,
125 const IDType _parent_id) {
126 if (_onto == _parent_id) {
127 _add_node((_abstract_internal_dag_node<In, IDType> *)_node_to_add);
128 return _parent_id;
129 } else {
130 for (auto child = m_children.cbegin(); child != m_children.cend();
131 child++) {
132 auto *internal_child =
133 static_cast<_internal_dag_node<In, Type, IDType> *>(*child);
135 internal_child->m_child;
136 if (auto p = fanout_node->add_node_to_subdag(_node_to_add, _onto,
137 (*child)->get_id());
138 p.has_value())
139 return p.value();
140 }
141 }
142
143 return unexpected(error_codes::PARENT_NOT_FOUND);
144 ;
145 }
146};
147} // namespace fn_dag
Internal node to take data from parent and run children.
Definition dag_node_impl.hpp:25
dag_fanout_node(const _dag_context &_context)
This node uses data computed from the previous node to fan-out to it's children.
Definition dag_fanout_impl.hpp:56
void print(const string &_indent)
Printing function.
Definition dag_fanout_impl.hpp:99
~dag_fanout_node()
Standard deconstructor.
Definition dag_fanout_impl.hpp:60
expected< IDType, error_codes > add_node_to_subdag(_internal_dag_node< In, Out, IDType > *_node_to_add, const IDType _onto, const IDType _parent_id)
Recursively adds a node to children.
Definition dag_fanout_impl.hpp:123
void fan_out(unique_ptr< Type > _data)
Function to move data through the graph.
Definition dag_fanout_impl.hpp:76
Definition guid_generated.h:16
@ PARENT_NOT_FOUND
The parent of the node you are attaching to the dag was not found.
Definition error_codes.h:20