Skip to content

Commit 4f3da1c

Browse files
committedAug 25, 2023
reimplementation of optimizer
1 parent baaebb7 commit 4f3da1c

File tree

4 files changed

+177
-187
lines changed

4 files changed

+177
-187
lines changed
 

‎include/reactor-cpp/environment.hh

+2-3
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ private:
5959

6060
const Duration timeout_{};
6161

62-
Graph<BasePort*, ConnectionProperties> graph_{};
63-
Graph<BasePort*, ConnectionProperties> optimized_graph_{};
62+
Graph<BasePort> graph_{};
63+
Graph<BasePort> optimized_graph_{};
6464

6565
void build_dependency_graph(Reactor* reactor);
6666
void calculate_indexes();
@@ -91,7 +91,6 @@ public:
9191
}
9292

9393
void optimize();
94-
void expand_and_merge();
9594

9695
void register_reactor(Reactor* reactor);
9796
void register_input_action(BaseAction* action);

‎include/reactor-cpp/graph.hh

+159-52
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,34 @@
1212
#include <iostream>
1313
#include <map>
1414
#include <optional>
15+
#include <type_traits>
1516
#include <vector>
1617

1718
namespace reactor {
19+
class GraphElement {
20+
public:
21+
GraphElement() noexcept = default;
22+
GraphElement(const GraphElement& graph) noexcept = default;
23+
GraphElement(GraphElement&& graph) noexcept = default;
24+
25+
virtual ~GraphElement() noexcept = default;
26+
[[nodiscard]] virtual auto connected_to_downstream_actions() const noexcept -> bool = 0;
27+
[[nodiscard]] virtual auto connected_to_upstream_actions() const noexcept -> bool = 0;
28+
[[nodiscard]] virtual auto rating() const noexcept -> std::size_t = 0;
29+
30+
auto operator=([[maybe_unused]] const GraphElement& other) noexcept -> GraphElement& = default;
31+
auto operator=([[maybe_unused]] GraphElement&& other) noexcept -> GraphElement& = default;
32+
};
33+
1834
// this graph is special, because to every edge properties are annotated
19-
template <class E, class P> class Graph {
35+
template <class X> class Graph {
36+
// static_assert(std::is_base_of_v<GraphElement, X>);
37+
using E = X*;
38+
using P = ConnectionProperties;
39+
2040
private:
21-
std::map<E, std::vector<std::pair<P, E>>> graph_;
41+
using Path = std::vector<std::tuple<E, P, E>>;
42+
std::map<E, std::vector<std::pair<P, E>>> graph_{};
2243
std::set<E> nodes_{};
2344

2445
// custom compare operator this is required if u want special key values in std::map
@@ -39,8 +60,6 @@ public:
3960
: graph_(std::move(graph.graph_)) {}
4061
~Graph() noexcept = default;
4162

42-
using Path = std::vector<std::pair<P, E>>;
43-
4463
auto operator=(const Graph other) noexcept -> Graph& {
4564
graph_ = other.graph_;
4665
return *this;
@@ -55,8 +74,10 @@ public:
5574
void add_edge(E source, E destination, P properties) noexcept {
5675
nodes_.insert(source);
5776
nodes_.insert(destination);
77+
5878
if (graph_.find(source) == std::end(graph_)) {
59-
Path edges{std::make_pair(properties, destination)};
79+
std::vector<std::pair<P, E>> edges;
80+
edges.emplace_back(properties, destination);
6081
graph_[source] = edges;
6182
} else {
6283
graph_[source].emplace_back(properties, destination);
@@ -95,79 +116,45 @@ public:
95116
// the return type looks a little bit cursed what is happening here ?
96117
// we have a map from the destination as a key to a list of paths through the graph.
97118
// A path here is modelled by a list of edges (with properties and the next vertex).
98-
auto naive_spanning_tree(E source) noexcept -> std::vector<std::vector<std::pair<P, E>>> {
119+
auto naive_spanning_tree(E source) noexcept -> std::vector<std::vector<std::tuple<E, P, E>>> {
99120
return recursive_spanning_tree(source, std::vector<E>{});
100121
}
101122

102123
// this function goes recursively though the graph and tries to find every possible path
103124
auto recursive_spanning_tree(E source_node, std::vector<E> visited_nodes)
104-
-> std::vector<std::vector<std::pair<P, E>>> {
125+
-> std::vector<std::vector<std::tuple<E, P, E>>> {
105126
std::vector<Path> paths{};
106127

107128
if (graph_[source_node].empty()) {
108129
return std::vector<Path>{Path{}};
109130
}
110131

132+
// if this node has an action we need to append the path
133+
if (source_node->connected_to_downstream_actions()) {
134+
paths.push_back(Path{});
135+
}
136+
111137
for (auto child : graph_[source_node]) {
112138
E current_node = child.second;
113139

114-
// means this node has not been visited yey
115-
if (std::find(std::begin(visited_nodes), std::end(visited_nodes), current_node) == std::end(visited_nodes)) {
116-
117-
// creating a temporary vector where the currently selected vertex is appended
118-
auto temp_nodes = visited_nodes;
119-
temp_nodes.push_back(current_node);
120-
121-
for (auto path : recursive_spanning_tree(current_node, temp_nodes)) {
122-
path.insert(std::begin(path), child);
123-
paths.push_back(path);
124-
}
140+
// we dont need to check for cycles because lf semantics assure that there wont be any cycles
141+
for (auto path : recursive_spanning_tree(current_node, visited_nodes)) {
142+
path.push_back(std::make_tuple(source_node, child.first, current_node));
143+
paths.push_back(path);
125144
}
126145
}
127146

128147
return paths;
129148
}
130149

131-
auto shortest_path(E source, E destination) -> std::optional<Path> {
132-
// TODO: maybe build proper djikstra here
133-
134-
auto spanning_tre = naive_spanning_tree(source);
135-
std::vector<Path> relevant_paths{};
136-
137-
std::copy_if(spanning_tre.begin(), spanning_tre.end(), std::back_inserter(relevant_paths),
138-
[&, destination](Path path) { return path[path.size() - 1].second == destination; });
139-
140-
if (relevant_paths.empty()) {
141-
return std::nullopt;
142-
}
143-
144-
Path best_path = *relevant_paths.begin();
145-
146-
for (auto path : relevant_paths) {
147-
if (path.size() < best_path.size()) {
148-
best_path = path;
149-
}
150-
}
151-
152-
return best_path;
153-
}
154-
155150
[[nodiscard]] auto get_destinations(E source) const noexcept -> std::vector<std::pair<P, E>> {
156-
return graph_[source];
157-
}
158-
159-
[[nodiscard]] auto get_upstream(E vertex) const noexcept -> std::optional<E> {
160-
for (const auto& [source, sinks] : graph_) {
161-
if (sinks.second.contains(vertex)) {
162-
return source;
163-
}
164-
}
151+
return this->graph_.at(source);
165152
}
166153

167154
[[nodiscard]] auto to_mermaid() const noexcept -> std::string {
155+
std::string mermaid_string = "graph TD;\n";
168156
std::size_t index{0};
169157
std::map<E, std::string> name_map{};
170-
std::string mermaid_string = "graph TD;\n";
171158

172159
auto name_resolver = [&](E object) -> std::string {
173160
char names[] = "ABCDEFGHIJKLMNOPQRSTUVGXYZabcdefghijklmnopqrstuvgxyz"; // NOLINT
@@ -188,6 +175,126 @@ public:
188175
return mermaid_string;
189176
}
190177

178+
void optimize(Graph<X>& optimized_graph) {
179+
optimized_graph.clear();
180+
181+
static std::map<std::pair<ConnectionType, ConnectionType>, ConnectionType> construction_table = {
182+
// Normal + x
183+
{std::make_pair<ConnectionType, ConnectionType>(Normal, Normal), Normal},
184+
{std::make_pair<ConnectionType, ConnectionType>(Normal, Delayed), Delayed},
185+
{std::make_pair<ConnectionType, ConnectionType>(Normal, Enclaved), Enclaved},
186+
{std::make_pair<ConnectionType, ConnectionType>(Normal, Physical), Physical},
187+
{std::make_pair<ConnectionType, ConnectionType>(Normal, DelayedEnclaved), DelayedEnclaved},
188+
{std::make_pair<ConnectionType, ConnectionType>(Normal, PhysicalEnclaved), PhysicalEnclaved},
189+
{std::make_pair<ConnectionType, ConnectionType>(Normal, Plugin), Plugin},
190+
// Delayed + x
191+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Normal), Delayed},
192+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Delayed), Delayed},
193+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Enclaved), DelayedEnclaved},
194+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Physical), Invalid}, //!!!
195+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, DelayedEnclaved), DelayedEnclaved},
196+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, PhysicalEnclaved), Invalid}, //!!!
197+
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Plugin), Invalid},
198+
// Enclaved + x
199+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Normal), Enclaved},
200+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Delayed), DelayedEnclaved},
201+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Enclaved), Enclaved},
202+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Physical), PhysicalEnclaved},
203+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, DelayedEnclaved), DelayedEnclaved},
204+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, PhysicalEnclaved), PhysicalEnclaved},
205+
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Plugin), Invalid},
206+
// Physical + x
207+
{std::make_pair<ConnectionType, ConnectionType>(Physical, Normal), Physical},
208+
{std::make_pair<ConnectionType, ConnectionType>(Physical, Delayed), Invalid}, // !!!
209+
{std::make_pair<ConnectionType, ConnectionType>(Physical, Enclaved), PhysicalEnclaved},
210+
{std::make_pair<ConnectionType, ConnectionType>(Physical, Physical), Physical},
211+
{std::make_pair<ConnectionType, ConnectionType>(Physical, DelayedEnclaved), Invalid}, // !!!
212+
{std::make_pair<ConnectionType, ConnectionType>(Physical, PhysicalEnclaved), PhysicalEnclaved},
213+
{std::make_pair<ConnectionType, ConnectionType>(Physical, Plugin), Invalid},
214+
// DelayedEnclaved + x
215+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Normal), DelayedEnclaved},
216+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Delayed), DelayedEnclaved},
217+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Enclaved), DelayedEnclaved},
218+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Physical), Invalid}, // !!!
219+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, DelayedEnclaved), DelayedEnclaved},
220+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, PhysicalEnclaved), Invalid}, // !!!
221+
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Plugin), Invalid},
222+
// PhysicalEnclaved + x
223+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Normal), PhysicalEnclaved},
224+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Delayed), Invalid}, // !!!
225+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Enclaved), PhysicalEnclaved},
226+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Physical), PhysicalEnclaved},
227+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, DelayedEnclaved), Invalid}, // !!!
228+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, PhysicalEnclaved), PhysicalEnclaved},
229+
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Plugin), Invalid},
230+
// Plugin + x = Invalid
231+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Normal), Invalid}, // !!!
232+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Delayed), Invalid}, // !!!
233+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Enclaved), Invalid}, // !!!
234+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Physical), Invalid}, // !!!
235+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, DelayedEnclaved), Invalid}, // !!!
236+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, PhysicalEnclaved), Invalid}, // !!!
237+
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Plugin), Invalid}, // !!!
238+
};
239+
240+
// getting all the sources from the graph
241+
auto keys = this->keys();
242+
243+
std::vector<E> has_downstreams{};
244+
std::copy_if(keys.begin(), keys.end(), std::back_inserter(has_downstreams),
245+
[](auto element) { return element->connected_to_downstream_actions(); });
246+
247+
std::vector<E> has_upstreams{};
248+
std::copy_if(keys.begin(), keys.end(), std::back_inserter(has_upstreams),
249+
[](auto element) { return element->connected_to_upstream_actions(); });
250+
251+
// generating all the possible destinations for all sources
252+
for (auto* source : has_upstreams) {
253+
auto spanning_tree = naive_spanning_tree(source);
254+
255+
for (auto& path : spanning_tree) {
256+
ConnectionProperties merged_properties{};
257+
auto* final_destination = std::get<2>(*std::begin(path));
258+
std::size_t current_rating = 0;
259+
260+
for (auto edge : path) {
261+
auto property = std::get<1>(edge);
262+
// auto source_port = std::get<0>(edge);
263+
auto* destination_port = std::get<2>(edge);
264+
265+
current_rating += destination_port->rating();
266+
267+
if (current_rating > 0) {
268+
auto return_type =
269+
construction_table[std::pair<ConnectionType, ConnectionType>(merged_properties.type_, property.type_)];
270+
// invalid will split the connections
271+
if (return_type == Invalid) {
272+
// first add connection until this point
273+
optimized_graph.add_edge(destination_port, final_destination, merged_properties); // NOLINT
274+
275+
// resetting the properties and destination_port
276+
final_destination = destination_port;
277+
merged_properties = property;
278+
279+
} else {
280+
281+
// merging the connections
282+
merged_properties.type_ = return_type;
283+
284+
// adding up delays
285+
merged_properties.delay_ += property.delay_;
286+
287+
// updating target enclave if not nullptr
288+
merged_properties.enclave_ =
289+
(property.enclave_ != nullptr) ? property.enclave_ : merged_properties.enclave_;
290+
}
291+
}
292+
}
293+
optimized_graph.add_edge(std::get<0>(*(std::end(path) - 1)), final_destination, merged_properties);
294+
}
295+
}
296+
}
297+
191298
friend auto operator<<(std::ostream& outstream, const Graph& graph) -> std::ostream& {
192299
for (auto const& [source, destinations] : graph.graph_) {
193300
for (auto destination : destinations) {

‎include/reactor-cpp/port.hh

+15-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "assert.hh"
1616
#include "connection_properties.hh"
1717
#include "fwd.hh"
18+
#include "graph.hh"
1819
#include "multiport.hh"
1920
#include "reactor_element.hh"
2021
#include "value_ptr.hh"
@@ -23,7 +24,7 @@ namespace reactor {
2324

2425
enum class PortType { Input, Output, Delay };
2526

26-
class BasePort : public ReactorElement {
27+
class BasePort : public ReactorElement, public GraphElement { // NOLINT
2728
private:
2829
BasePort* inward_binding_{nullptr};
2930
std::set<BasePort*> outward_bindings_{};
@@ -39,10 +40,6 @@ private:
3940
protected:
4041
bool present_{false}; // NOLINT cppcoreguidelines-non-private-member-variables-in-classes
4142

42-
BasePort(const std::string& name, PortType type, Reactor* container)
43-
: ReactorElement(name, match_port_enum(type), container)
44-
, type_(type) {}
45-
4643
void register_dependency(Reaction* reaction, bool is_trigger) noexcept;
4744
void register_antidependency(Reaction* reaction) noexcept;
4845
virtual void cleanup() = 0;
@@ -71,6 +68,11 @@ protected:
7168
}
7269

7370
public:
71+
BasePort(const std::string& name, PortType type, Reactor* container)
72+
: ReactorElement(name, match_port_enum(type), container)
73+
, type_(type) {}
74+
~BasePort() noexcept override = default;
75+
7476
void set_inward_binding(BasePort* port) noexcept { inward_binding_ = port; }
7577
void add_outward_binding(BasePort* port) noexcept {
7678
outward_bindings_.insert(port); // NOLINT
@@ -93,7 +95,6 @@ public:
9395
[[nodiscard]] inline auto has_dependencies() const noexcept -> bool { return !dependencies_.empty(); }
9496
[[nodiscard]] inline auto has_anti_dependencies() const noexcept -> bool { return !anti_dependencies_.empty(); }
9597
[[nodiscard]] inline auto has_triggers() const noexcept -> bool { return !triggers_.empty(); }
96-
[[nodiscard]] inline auto rating() const noexcept -> std::size_t { return triggers_.size() + dependencies_.size(); }
9798

9899
[[nodiscard]] inline auto inward_binding() const noexcept -> BasePort* { return inward_binding_; }
99100
[[nodiscard]] inline auto outward_bindings() const noexcept -> const auto& { return outward_bindings_; }
@@ -103,6 +104,14 @@ public:
103104
[[nodiscard]] inline auto anti_dependencies() const noexcept -> const auto& { return anti_dependencies_; }
104105
[[nodiscard]] inline auto port_type() const noexcept -> PortType { return type_; }
105106

107+
[[nodiscard]] auto connected_to_downstream_actions() const noexcept -> bool final {
108+
return has_dependencies() || has_triggers();
109+
};
110+
[[nodiscard]] auto connected_to_upstream_actions() const noexcept -> bool final { return has_anti_dependencies(); };
111+
[[nodiscard]] auto rating() const noexcept -> std::size_t final {
112+
return dependencies_.size() + triggers_.size() + ((set_callback_ != nullptr) ? 1 : 0);
113+
}
114+
106115
void register_set_callback(const PortCallback& callback);
107116
void register_clean_callback(const PortCallback& callback);
108117

‎lib/environment.cc

+1-126
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,6 @@
2424

2525
namespace reactor {
2626

27-
void vector_shuffle(std::vector<std::pair<ConnectionProperties, BasePort*>>& path, BasePort* source) {
28-
for (auto it = std::begin(path); it != std::end(path); ++it) {
29-
if (std::next(it) == std::end(path)) {
30-
it->second = source;
31-
} else {
32-
it->second = std::next(it)->second;
33-
}
34-
}
35-
};
36-
3727
Environment::Environment(unsigned int num_workers, bool fast_fwd_execution, const Duration& timeout)
3828
: log_("Environment")
3929
, num_workers_(num_workers)
@@ -81,129 +71,14 @@ void Environment::optimize() {
8171
log::Debug() << "Opimizations:" << enable_optimizations;
8272
if constexpr (enable_optimizations) {
8373
log::Debug() << graph_.to_mermaid();
84-
expand_and_merge();
74+
graph_.optimize(optimized_graph_);
8575
log::Debug() << optimized_graph_.to_mermaid();
8676
} else {
8777
// no optimizations
8878
optimized_graph_ = graph_;
8979
}
9080
}
9181

92-
void Environment::expand_and_merge() {
93-
94-
static std::map<std::pair<ConnectionType, ConnectionType>, ConnectionType> construction_table = {
95-
// Normal + x
96-
{std::make_pair<ConnectionType, ConnectionType>(Normal, Normal), Normal},
97-
{std::make_pair<ConnectionType, ConnectionType>(Normal, Delayed), Delayed},
98-
{std::make_pair<ConnectionType, ConnectionType>(Normal, Enclaved), Enclaved},
99-
{std::make_pair<ConnectionType, ConnectionType>(Normal, Physical), Physical},
100-
{std::make_pair<ConnectionType, ConnectionType>(Normal, DelayedEnclaved), DelayedEnclaved},
101-
{std::make_pair<ConnectionType, ConnectionType>(Normal, PhysicalEnclaved), PhysicalEnclaved},
102-
{std::make_pair<ConnectionType, ConnectionType>(Normal, Plugin), Plugin},
103-
// Delayed + x
104-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Normal), Delayed},
105-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Delayed), Delayed},
106-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Enclaved), DelayedEnclaved},
107-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Physical), Invalid}, //!!!
108-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, DelayedEnclaved), DelayedEnclaved},
109-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, PhysicalEnclaved), Invalid}, //!!!
110-
{std::make_pair<ConnectionType, ConnectionType>(Delayed, Plugin), Invalid},
111-
// Enclaved + x
112-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Normal), Enclaved},
113-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Delayed), DelayedEnclaved},
114-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Enclaved), Enclaved},
115-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Physical), PhysicalEnclaved},
116-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, DelayedEnclaved), DelayedEnclaved},
117-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, PhysicalEnclaved), PhysicalEnclaved},
118-
{std::make_pair<ConnectionType, ConnectionType>(Enclaved, Plugin), Invalid},
119-
// Physical + x
120-
{std::make_pair<ConnectionType, ConnectionType>(Physical, Normal), Physical},
121-
{std::make_pair<ConnectionType, ConnectionType>(Physical, Delayed), Invalid}, // !!!
122-
{std::make_pair<ConnectionType, ConnectionType>(Physical, Enclaved), PhysicalEnclaved},
123-
{std::make_pair<ConnectionType, ConnectionType>(Physical, Physical), Physical},
124-
{std::make_pair<ConnectionType, ConnectionType>(Physical, DelayedEnclaved), Invalid}, // !!!
125-
{std::make_pair<ConnectionType, ConnectionType>(Physical, PhysicalEnclaved), PhysicalEnclaved},
126-
{std::make_pair<ConnectionType, ConnectionType>(Physical, Plugin), Invalid},
127-
// DelayedEnclaved + x
128-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Normal), DelayedEnclaved},
129-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Delayed), DelayedEnclaved},
130-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Enclaved), DelayedEnclaved},
131-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Physical), Invalid}, // !!!
132-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, DelayedEnclaved), DelayedEnclaved},
133-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, PhysicalEnclaved), Invalid}, // !!!
134-
{std::make_pair<ConnectionType, ConnectionType>(DelayedEnclaved, Plugin), Invalid},
135-
// PhysicalEnclaved + x
136-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Normal), PhysicalEnclaved},
137-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Delayed), Invalid}, // !!!
138-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Enclaved), PhysicalEnclaved},
139-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Physical), PhysicalEnclaved},
140-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, DelayedEnclaved), Invalid}, // !!!
141-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, PhysicalEnclaved), PhysicalEnclaved},
142-
{std::make_pair<ConnectionType, ConnectionType>(PhysicalEnclaved, Plugin), Invalid},
143-
// Plugin + x = Invalid
144-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Normal), Invalid}, // !!!
145-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Delayed), Invalid}, // !!!
146-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Enclaved), Invalid}, // !!!
147-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Physical), Invalid}, // !!!
148-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, DelayedEnclaved), Invalid}, // !!!
149-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, PhysicalEnclaved), Invalid}, // !!!
150-
{std::make_pair<ConnectionType, ConnectionType>(Plugin, Plugin), Invalid}, // !!!
151-
};
152-
153-
// discards all current changes
154-
optimized_graph_.clear();
155-
156-
// getting all the sources from the graph
157-
auto keys = graph_.keys();
158-
159-
// generating all the possible destinations for all sources
160-
for (auto* source : keys) {
161-
auto spanning_tree = graph_.naive_spanning_tree(source);
162-
for (auto& path : spanning_tree) {
163-
ConnectionProperties merged_properties{};
164-
165-
std::reverse(path.begin(), path.end());
166-
167-
auto* previous_element = std::begin(path)->second;
168-
vector_shuffle(path, source);
169-
170-
auto current_rating = previous_element->rating();
171-
172-
for (auto element : path) {
173-
auto property = element.first;
174-
current_rating += element.second->rating();
175-
176-
if (current_rating > 0) {
177-
auto return_type =
178-
construction_table[std::pair<ConnectionType, ConnectionType>(merged_properties.type_, property.type_)];
179-
// invalid will split the connections
180-
if (return_type == Invalid) {
181-
// first add connection until this point
182-
optimized_graph_.add_edge(element.second, previous_element, merged_properties);
183-
184-
// updating the source of the connection and resetting the properties
185-
previous_element = element.second;
186-
merged_properties = property;
187-
188-
} else {
189-
// merging the connections
190-
merged_properties.type_ = return_type;
191-
192-
// adding up delays
193-
merged_properties.delay_ += property.delay_;
194-
195-
// updating target enclave if not nullptr
196-
merged_properties.enclave_ =
197-
(property.enclave_ != nullptr) ? property.enclave_ : merged_properties.enclave_;
198-
199-
optimized_graph_.add_edge(element.second, previous_element, merged_properties);
200-
}
201-
}
202-
}
203-
}
204-
}
205-
}
206-
20782
void recursive_assemble(Reactor* container) { // NOLINT
20883
container->assemble();
20984
for (auto* reactor : container->reactors()) {

0 commit comments

Comments
 (0)
Please sign in to comment.