Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / src / compiler / transactions.hpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2018-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_COMPILER_TRANSACTIONS_HPP
9 #define OPENCV_GAPI_COMPILER_TRANSACTIONS_HPP
10
11 #include <algorithm> // find_if
12 #include <functional>
13 #include <list>
14
15 #include <ade/graph.hpp>
16
17 #include "opencv2/gapi/own/assert.hpp"
18
19 enum class Direction: int {Invalid, In, Out};
20
21 ////////////////////////////////////////////////////////////////////////////
22 ////
23 // TODO: Probably it can be moved to ADE
24
25 namespace Change
26 {
27     struct Base
28     {
29         virtual void commit  (ade::Graph & ) {};
30         virtual void rollback(ade::Graph & ) {};
31         virtual ~Base() = default;
32     };
33
34     class NodeCreated final: public Base
35     {
36         ade::NodeHandle m_node;
37     public:
38         explicit NodeCreated(const ade::NodeHandle &nh) : m_node(nh) {}
39         virtual void rollback(ade::Graph &g) override { g.erase(m_node); }
40     };
41
42     // NB: Drops all metadata stored in the EdgeHandle,
43     // which is not restored even in the rollback
44
45     // FIXME: either add a way for users to preserve meta manually
46     // or extend ADE to manipulate with meta such way
47     class DropLink final: public Base
48     {
49         ade::NodeHandle m_node;
50         Direction       m_dir;
51
52         ade::NodeHandle m_sibling;
53
54     public:
55         DropLink(ade::Graph &g,
56                  const ade::NodeHandle &node,
57                  const ade::EdgeHandle &edge)
58             : m_node(node), m_dir(node == edge->srcNode()
59                                   ? Direction::Out
60                                   : Direction::In)
61         {
62             m_sibling = (m_dir == Direction::In
63                          ? edge->srcNode()
64                          : edge->dstNode());
65             g.erase(edge);
66         }
67
68         virtual void rollback(ade::Graph &g) override
69         {
70             switch(m_dir)
71             {
72             case Direction::In:  g.link(m_sibling, m_node); break;
73             case Direction::Out: g.link(m_node, m_sibling); break;
74             default: GAPI_Assert(false);
75             }
76         }
77     };
78
79     class NewLink final: public Base
80     {
81         ade::EdgeHandle m_edge;
82
83     public:
84         NewLink(ade::Graph &g,
85                   const ade::NodeHandle &prod,
86                   const ade::NodeHandle &cons)
87             : m_edge(g.link(prod, cons))
88         {
89         }
90
91         virtual void rollback(ade::Graph &g) override
92         {
93             g.erase(m_edge);
94         }
95     };
96
97     class DropNode final: public Base
98     {
99         ade::NodeHandle m_node;
100
101     public:
102         explicit DropNode(const ade::NodeHandle &nh)
103             : m_node(nh)
104         {
105             // According to the semantic, node should be disconnected
106             // manually before it is dropped
107             GAPI_Assert(m_node->inEdges().size()  == 0);
108             GAPI_Assert(m_node->outEdges().size() == 0);
109         }
110
111         virtual void commit(ade::Graph &g) override
112         {
113             g.erase(m_node);
114         }
115     };
116
117     class List
118     {
119         std::list< std::unique_ptr<Base> > m_changes;
120
121     public:
122         template<typename T, typename ...Args>
123         void enqueue(Args&&... args)
124         {
125             std::unique_ptr<Base> p(new T(args...));
126             m_changes.push_back(std::move(p));
127         }
128
129         void commit(ade::Graph &g)
130         {
131             // Commit changes in the forward order
132             for (auto& ch : m_changes) ch->commit(g);
133         }
134
135         void rollback(ade::Graph &g)
136         {
137             // Rollback changes in the reverse order
138             for (auto it = m_changes.rbegin(); it != m_changes.rend(); ++it)
139             {
140                 (*it)->rollback(g);
141             }
142         }
143     };
144 } // namespace Change
145 ////////////////////////////////////////////////////////////////////////////
146
147 #endif // OPENCV_GAPI_COMPILER_TRANSACTIONS_HPP