11#pragma once
22
33#include " ../error/error.hpp"
4+ #include " ../utility/object_pool.hpp"
45#include " ../utility/traits.hpp"
56#include " ../utility/passive_vector.hpp"
67#include " declarations.hpp"
@@ -11,13 +12,17 @@ namespace tf {
1112class Graph {
1213
1314 friend class Node ;
15+ friend class Taskflow ;
16+ friend class Executor ;
1417
1518 public:
1619
1720 Graph () = default ;
1821 Graph (const Graph&) = delete ;
1922 Graph (Graph&&);
2023
24+ ~Graph ();
25+
2126 Graph& operator = (const Graph&) = delete ;
2227 Graph& operator = (Graph&&);
2328
@@ -28,17 +33,15 @@ class Graph {
2833 size_t size () const ;
2934
3035 template <typename ...Args>
31- Node& emplace_back (Args&& ...);
32-
33- Node& emplace_back ();
36+ Node* emplace_back (Args&& ...);
3437
35- std::vector<std::unique_ptr<Node>>& nodes ();
36-
37- const std::vector<std::unique_ptr<Node>>& nodes () const ;
38+ Node* emplace_back ();
3839
3940 private:
41+
42+ static ObjectPool<Node>& _node_pool ();
4043
41- std::vector<std::unique_ptr< Node> > _nodes;
44+ std::vector<Node* > _nodes;
4245};
4346
4447// ----------------------------------------------------------------------------
@@ -86,10 +89,10 @@ class Node {
8689
8790 const std::string& name () const ;
8891
89- // std::string dump() const ;
92+ ObjectPool<Node>:: satellite_t satellite ;
9093
9194 private:
92-
95+
9396 std::string _name;
9497 std::variant<std::monostate, StaticWork, DynamicWork, ConditionWork> _work;
9598
@@ -125,13 +128,17 @@ Node::Node(Args&&... args): _work{std::forward<Args>(args)...} {
125128inline Node::~Node () {
126129 // this is to avoid stack overflow
127130 if (_subgraph.has_value ()) {
128- std::vector<std::unique_ptr<Node>> nodes;
131+
132+ std::vector<Node*> nodes;
133+
129134 std::move (
130135 _subgraph->_nodes .begin (), _subgraph->_nodes .end (), std::back_inserter (nodes)
131136 );
132137 _subgraph->_nodes .clear ();
133138 _subgraph.reset ();
139+
134140 size_t i = 0 ;
141+
135142 while (i < nodes.size ()) {
136143 if (auto & sbg = nodes[i]->_subgraph ; sbg) {
137144 std::move (
@@ -142,6 +149,11 @@ inline Node::~Node() {
142149 }
143150 ++i;
144151 }
152+
153+ auto & np = Graph::_node_pool ();
154+ for (i=0 ; i<nodes.size (); ++i) {
155+ np.destruct (nodes[i]);
156+ }
145157 }
146158}
147159
@@ -275,97 +287,23 @@ inline bool Node::_has_state(int flag) const {
275287}
276288
277289// ----------------------------------------------------------------------------
278-
279- /* // Class: NodePool
280- class NodePool {
281-
282- public:
283-
284- template <typename C>
285- std::unique_ptr<Node> acquire(C&&);
286-
287- std::unique_ptr<Node> acquire();
288-
289- void release(std::unique_ptr<Node>);
290-
291- private:
290+ // Graph definition
291+ // ----------------------------------------------------------------------------
292292
293- //std::mutex _mutex;
294-
295- std::vector<std::unique_ptr<Node>> _nodes;
296-
297- void _recycle(Node&);
298- };
299-
300- // Function: acquire
301- template <typename C>
302- inline std::unique_ptr<Node> NodePool::acquire(C&& c) {
303- if(_nodes.empty()) {
304- return std::make_unique<Node>(std::forward<C>(c));
305- }
306- else {
307- auto node = std::move(_nodes.back());
308- node->_work = std::forward<C>(c);
309- _nodes.pop_back();
310- return node;
311- }
293+ // Function: _node_pool
294+ inline ObjectPool<Node>& Graph::_node_pool () {
295+ static ObjectPool<Node> pool;
296+ return pool;
312297}
313298
314- // Function: acquire
315- inline std::unique_ptr<Node> NodePool::acquire() {
316- if(_nodes.empty()) {
317- return std::make_unique<Node>();
318- }
319- else {
320- auto node = std::move(_nodes.back());
321- _nodes.pop_back();
322- return node;
323- }
324- }
325-
326- // Procedure: release
327- inline void NodePool::release(std::unique_ptr<Node> node) {
328-
329- return;
330-
331- //assert(node);
332- if(_nodes.size() >= 65536) {
333- return;
334- }
335-
336- auto children = node->_extract_children();
337-
338- for(auto& child : children) {
339- _recycle(*child);
299+ // Destructor
300+ inline Graph::~Graph () {
301+ auto & np = _node_pool ();
302+ for (auto node : _nodes) {
303+ np.destruct (node);
340304 }
341- _recycle(*node);
342-
343- std::move(children.begin(), children.end(), std::back_inserter(_nodes));
344- _nodes.push_back(std::move(node));
345- }
346-
347- // Procedure: _recycle
348- inline void NodePool::_recycle(Node& node) {
349- node._name.clear();
350- node._work = {};
351- node._successors.clear();
352- node._dependents.clear();
353- node._topology = nullptr;
354- node._module = nullptr;
355- node._state = 0;
356- node._join_counter.store(0, std::memory_order_relaxed);
357- //assert(!node._subgraph);
358305}
359306
360- // ----------------------------------------------------------------------------
361-
362- namespace this_thread {
363- inline thread_local NodePool nodepool;
364- }
365- */
366-
367- // ----------------------------------------------------------------------------
368-
369307// Move constructor
370308inline Graph::Graph (Graph&& other) :
371309 _nodes {std::move (other._nodes )} {
@@ -378,8 +316,11 @@ inline Graph& Graph::operator = (Graph&& other) {
378316}
379317
380318// Procedure: clear
381- // clear and recycle the nodes
382319inline void Graph::clear () {
320+ auto & np = _node_pool ();
321+ for (auto node : _nodes) {
322+ np.destruct (node);
323+ }
383324 _nodes.clear ();
384325}
385326
@@ -395,33 +336,21 @@ inline bool Graph::empty() const {
395336 return _nodes.empty ();
396337}
397338
398- // Function: nodes
399- // return a mutable reference to the node data structure
400- // inline std::vector<std::unique_ptr<Node>>& Graph::nodes() {
401- inline std::vector<std::unique_ptr<Node>>& Graph::nodes () {
402- return _nodes;
403- }
404-
405- // Function: nodes
406- // returns a constant reference to the node data structure
407- // inline const std::vector<std::unique_ptr<Node>>& Graph::nodes() const {
408- inline const std::vector<std::unique_ptr<Node>>& Graph::nodes () const {
409- return _nodes;
410- }
411-
412339// Function: emplace_back
413340// create a node from a give argument; constructor is called if necessary
414- template <typename ...Args>
415- Node& Graph::emplace_back (Args&&... args) {
416- _nodes.push_back (std::make_unique<Node>(std::forward<Args>(args)...));
417- return *(_nodes.back ());
341+ template <typename ...ArgsT>
342+ Node* Graph::emplace_back (ArgsT&&... args) {
343+ auto node = _node_pool ().construct (std::forward<ArgsT>(args)...);
344+ _nodes.push_back (node);
345+ return node;
418346}
419347
420348// Function: emplace_back
421349// create a node from a give argument; constructor is called if necessary
422- inline Node& Graph::emplace_back () {
423- _nodes.push_back (std::make_unique<Node>());
424- return *(_nodes.back ());
350+ inline Node* Graph::emplace_back () {
351+ auto node = _node_pool ().construct ();
352+ _nodes.push_back (node);
353+ return node;
425354}
426355
427356
0 commit comments