@@ -63,8 +63,122 @@ void Environment::register_input_action(BaseAction* action) {
6363}
6464
6565void Environment::optimize () {
66- // no optimizations
67- optimized_graph_ = graph_;
66+ #ifdef GRAPH_OPTIMIZATIONS
67+ constexpr bool enable_optimizations = GRAPH_OPTIMIZATIONS;
68+ #else
69+ constexpr bool enable_optimizations = false ;
70+ #endif
71+
72+ if constexpr (enable_optimizations) {
73+ static std::map<std::pair<ConnectionType, ConnectionType>, ConnectionType> construction_table = {
74+ // Normal + x
75+ {std::make_pair<ConnectionType, ConnectionType>(Normal, Normal), Normal},
76+ {std::make_pair<ConnectionType, ConnectionType>(Normal, Delayed), Delayed},
77+ {std::make_pair<ConnectionType, ConnectionType>(Normal, Enclaved), Enclaved},
78+ {std::make_pair<ConnectionType, ConnectionType>(Normal, Physical), Physical},
79+ {std::make_pair<ConnectionType, ConnectionType>(Normal, DelayedEnclaved), DelayedEnclaved},
80+ {std::make_pair<ConnectionType, ConnectionType>(Normal, PhysicalEnclaved), PhysicalEnclaved},
81+ {std::make_pair<ConnectionType, ConnectionType>(Normal, Plugin), Plugin},
82+ // Delayed + x
83+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, Normal), Delayed},
84+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, Delayed), Delayed},
85+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, Enclaved), DelayedEnclaved},
86+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, Physical), Invalid}, // !!!
87+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, DelayedEnclaved), DelayedEnclaved},
88+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, PhysicalEnclaved), Invalid}, // !!!
89+ {std::make_pair<ConnectionType, ConnectionType>(Delayed, Plugin), Invalid},
90+ // Enclaved + x
91+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, Normal), Enclaved},
92+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, Delayed), DelayedEnclaved},
93+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, Enclaved), Enclaved},
94+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, Physical), PhysicalEnclaved},
95+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, DelayedEnclaved), DelayedEnclaved},
96+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, PhysicalEnclaved), PhysicalEnclaved},
97+ {std::make_pair<ConnectionType, ConnectionType>(Enclaved, Plugin), Invalid},
98+ // Physical + x
99+ {std::make_pair<ConnectionType, ConnectionType>(Physical, Normal), Physical},
100+ {std::make_pair<ConnectionType, ConnectionType>(Physical, Delayed), Invalid}, // !!!
101+ {std::make_pair<ConnectionType, ConnectionType>(Physical, Enclaved), PhysicalEnclaved},
102+ {std::make_pair<ConnectionType, ConnectionType>(Physical, Physical), Physical},
103+ {std::make_pair<ConnectionType, ConnectionType>(Physical, DelayedEnclaved), Invalid}, // !!!
104+ {std::make_pair<ConnectionType, ConnectionType>(Physical, PhysicalEnclaved), PhysicalEnclaved},
105+ {std::make_pair<ConnectionType, ConnectionType>(Physical, Plugin), Invalid},
106+ // DelayedEnclaved + x
107+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Normal), DelayedEnclaved},
108+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Delayed), DelayedEnclaved},
109+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Enclaved), DelayedEnclaved},
110+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Physical), Invalid}, // !!!
111+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, DelayedEnclaved), DelayedEnclaved},
112+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, PhysicalEnclaved), Invalid}, // !!!
113+ {std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Plugin), Invalid},
114+ // PhysicalEnclaved + x
115+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Normal), PhysicalEnclaved},
116+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Delayed), Invalid}, // !!!
117+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Enclaved), PhysicalEnclaved},
118+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Physical), PhysicalEnclaved},
119+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, DelayedEnclaved), Invalid}, // !!!
120+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, PhysicalEnclaved), PhysicalEnclaved},
121+ {std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Plugin), Invalid},
122+ // Plugin + x = Invalid
123+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, Normal), Invalid}, // !!!
124+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, Delayed), Invalid}, // !!!
125+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, Enclaved), Invalid}, // !!!
126+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, Physical), Invalid}, // !!!
127+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, DelayedEnclaved), Invalid}, // !!!
128+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, PhysicalEnclaved), Invalid}, // !!!
129+ {std::make_pair<ConnectionType, ConnectionType>(Plugin, Plugin), Invalid}, // !!!
130+ };
131+
132+ // discards all current changes
133+ optimized_graph_.clear ();
134+
135+ // getting all the sources from the graph
136+ auto keys = graph_.keys ();
137+
138+ // generating all the possible destinations for all sources
139+ for (auto * source : keys) {
140+ auto spanning_tree = graph_.spanning_tree (source);
141+
142+ for (const auto & [destination, path] : spanning_tree) {
143+ ConnectionProperties merged_properties{};
144+ auto * current_source = source;
145+
146+ for (auto element : path) {
147+ auto property = element.first ;
148+
149+ auto return_type =
150+ construction_table[std::pair<ConnectionType, ConnectionType>(merged_properties.type_ , property.type_ )];
151+
152+ // invalid will split the connections
153+ if (return_type == Invalid) {
154+ // first add connection until this point
155+ optimized_graph_.add_edge (current_source, element.second , merged_properties);
156+
157+ // updating the source of the connection and resetting the properties
158+ current_source = element.second ;
159+ merged_properties = property;
160+
161+ } else {
162+ // merging the connections
163+ merged_properties.type_ = return_type;
164+
165+ // adding up delays
166+ merged_properties.delay_ += property.delay_ ;
167+
168+ // updating target enclave if not nullptr
169+ merged_properties.enclave_ =
170+ (property.enclave_ != nullptr ) ? property.enclave_ : merged_properties.enclave_ ;
171+ }
172+ }
173+
174+ // add merged connection
175+ optimized_graph_.add_edge (current_source, destination, merged_properties);
176+ }
177+ }
178+ } else {
179+ // no optimizations
180+ optimized_graph_ = graph_;
181+ }
68182}
69183
70184void recursive_assemble (Reactor* container) { // NOLINT
0 commit comments