4
4
5
5
use App \Helpers \ExerciseConfig \Compilation \Tree \Node ;
6
6
use App \Helpers \ExerciseConfig \Compilation \Tree \RootedTree ;
7
+ use App \Helpers \ExerciseConfig \Pipeline \Box \DataInBox ;
7
8
use App \Helpers \ExerciseConfig \Pipeline \Ports \Port ;
8
- use Nette \ Utils \ Arrays ;
9
+ use App \ Helpers \ ExerciseConfig \ Variable ;
9
10
10
11
/**
11
12
* Internal exercise configuration compilation service. Handles optimisation
16
17
*/
17
18
class BoxesOptimizer {
18
19
20
+ /**
21
+ * Determine if given variables can be optimized or not.
22
+ * @param Variable|null $first
23
+ * @param Variable|null $second
24
+ * @return bool
25
+ */
26
+ private static function canVariablesBeOptimized (?Variable $ first , ?Variable $ second ) {
27
+ if ($ first === null && $ second === null ) {
28
+ return true ;
29
+ }
30
+
31
+ if ($ first === null || $ second === null ||
32
+ $ first ->getValue () !== $ second ->getValue ()) {
33
+ return false ;
34
+ }
35
+
36
+ if ($ first ->getType () !== $ second ->getType ()) {
37
+ return false ;
38
+ }
39
+
40
+ return true ;
41
+ }
42
+
19
43
/**
20
44
* Determine if given ports can be optimized or not.
21
45
* @param Port $first could not be null
@@ -29,12 +53,7 @@ private static function canPortsBeOptimized(Port $first, Port $second) {
29
53
30
54
$ variableValue = $ first ->getVariableValue ();
31
55
$ otherVariableValue = $ second ->getVariableValue ();
32
- if ($ variableValue === null && $ otherVariableValue === null ) {
33
- return true ;
34
- }
35
-
36
- if ($ variableValue === null || $ otherVariableValue === null ||
37
- $ variableValue ->getValue () !== $ otherVariableValue ->getValue ()) {
56
+ if (self ::canVariablesBeOptimized ($ variableValue , $ otherVariableValue ) === false ) {
38
57
return false ;
39
58
}
40
59
@@ -84,6 +103,12 @@ private static function canNodesBeOptimized(Node $first, Node $second): bool {
84
103
}
85
104
}
86
105
106
+ // special case if boxes are of data type, then they have special input variable which has to be checked as well
107
+ if ($ firstBox instanceof DataInBox && $ secondBox instanceof DataInBox &&
108
+ self ::canVariablesBeOptimized ($ firstBox ->getInputVariable (), $ secondBox ->getInputVariable ()) === false ) {
109
+ return false ;
110
+ }
111
+
87
112
return true ;
88
113
}
89
114
@@ -137,6 +162,11 @@ private function optimizeTree(Node $rootNode) {
137
162
});
138
163
$ child ->setTestId (null ); // clear the test identification
139
164
165
+ // resolve dependencies transfer from compared to child
166
+ foreach ($ compared ->getDependencies () as $ dependency ) {
167
+ $ child ->addDependency ($ dependency );
168
+ }
169
+
140
170
foreach ($ compared ->getChildren () as $ comparedChild ) {
141
171
$ comparedChild ->removeParent ($ compared );
142
172
$ comparedChild ->addParent ($ child );
@@ -153,8 +183,12 @@ private function optimizeTree(Node $rootNode) {
153
183
}
154
184
155
185
// do not forget to add newly created children from current node to
156
- // processing queue
157
- $ queue = array_merge ($ queue , $ node ->getChildren ());
186
+ // processing queue, only if the node was optimised... otherwise we should not proceed
187
+ foreach ($ node ->getChildren () as $ child ) {
188
+ if ($ child ->getTestId () === null ) {
189
+ $ queue [] = $ child ;
190
+ }
191
+ }
158
192
}
159
193
}
160
194
0 commit comments