Skip to content

Commit f8aa12a

Browse files
NeloopMartin Kruliš
authored andcommitted
Repair BaseCompiler tests and discovered bugs in compilation
1 parent 1f3bd34 commit f8aa12a

File tree

5 files changed

+250
-164
lines changed

5 files changed

+250
-164
lines changed

app/helpers/ExerciseConfig/Compilation/BoxesCompiler.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ class BoxesCompiler {
2626
* Helper function which will create identification of task.
2727
* @param Node $node
2828
* @param string $postfix
29-
* @param CompilationContext $context
3029
* @return string
3130
*/
32-
private function createTaskIdentification(Node $node, string $postfix, CompilationContext $context): string {
33-
$testName = $context->getTestsNames()[$node->getTestId()];
34-
return $testName . self::$ID_DELIM . $node->getPipelineId() .
31+
private function createTaskIdentification(Node $node, string $postfix): string {
32+
$directoryName = $node->getBox()->getDirectory();
33+
return $directoryName . self::$ID_DELIM . $node->getPipelineId() .
3534
self::$ID_DELIM . $node->getBox()->getName() . self::$ID_DELIM . $postfix;
3635
}
3736

@@ -42,7 +41,7 @@ private function createTaskIdentification(Node $node, string $postfix, Compilati
4241
* @param ExerciseLimits[] $exerciseLimits indexed by hwgroup
4342
*/
4443
private function setLimits(Node $node, Task $task, array $exerciseLimits) {
45-
if (!$task->getSandboxConfig() ||
44+
if (!$task->getSandboxConfig() || !$node->getTestId() ||
4645
$task->getType() !== TaskType::$EXECUTION) {
4746
return;
4847
}
@@ -93,7 +92,7 @@ private function processTree(JobConfig $jobConfig, RootedTree $rootedTree,
9392
// set additional attributes to the tasks
9493
foreach ($tasks as $task) {
9594
// create and set task identification
96-
$taskId = $this->createTaskIdentification($current, $order, $context);
95+
$taskId = $this->createTaskIdentification($current, $order);
9796
$current->addTaskId($taskId);
9897
$task->setId($taskId);
9998

app/helpers/ExerciseConfig/Compilation/BoxesOptimizer.php

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
use App\Helpers\ExerciseConfig\Compilation\Tree\Node;
66
use App\Helpers\ExerciseConfig\Compilation\Tree\RootedTree;
7+
use App\Helpers\ExerciseConfig\Pipeline\Box\DataInBox;
78
use App\Helpers\ExerciseConfig\Pipeline\Ports\Port;
8-
use Nette\Utils\Arrays;
9+
use App\Helpers\ExerciseConfig\Variable;
910

1011
/**
1112
* Internal exercise configuration compilation service. Handles optimisation
@@ -16,6 +17,29 @@
1617
*/
1718
class BoxesOptimizer {
1819

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+
1943
/**
2044
* Determine if given ports can be optimized or not.
2145
* @param Port $first could not be null
@@ -29,12 +53,7 @@ private static function canPortsBeOptimized(Port $first, Port $second) {
2953

3054
$variableValue = $first->getVariableValue();
3155
$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) {
3857
return false;
3958
}
4059

@@ -84,6 +103,12 @@ private static function canNodesBeOptimized(Node $first, Node $second): bool {
84103
}
85104
}
86105

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+
87112
return true;
88113
}
89114

@@ -137,6 +162,11 @@ private function optimizeTree(Node $rootNode) {
137162
});
138163
$child->setTestId(null); // clear the test identification
139164

165+
// resolve dependencies transfer from compared to child
166+
foreach ($compared->getDependencies() as $dependency) {
167+
$child->addDependency($dependency);
168+
}
169+
140170
foreach ($compared->getChildren() as $comparedChild) {
141171
$comparedChild->removeParent($compared);
142172
$comparedChild->addParent($child);
@@ -153,8 +183,12 @@ private function optimizeTree(Node $rootNode) {
153183
}
154184

155185
// 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+
}
158192
}
159193
}
160194

app/helpers/ExerciseConfig/Compilation/DirectoriesResolver.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ private function processNode(Node $node, string $directoryName, array &$director
6464
private function findOptimizedNodesDirectory(Node $current): string {
6565
$name = "";
6666
while ($current->getTestId() === null) {
67-
$name .= $current->getBox() ? $current->getBox()->getCategory() : "";
68-
$name .= "_"; // delimiter
67+
$category = $current->getBox() ? $current->getBox()->getCategory() : "";
68+
$name .= !empty($category) ? $category . "_" : "";
6969

7070
if (count($current->getChildren()) < 1) {
7171
break;
@@ -202,7 +202,7 @@ private function addCopyTasks(RootedTree $tree) {
202202
$box = $current->getBox(); /** @var $box Box */
203203
if ($box) {
204204
foreach ($box->getInputPorts() as $port) {
205-
if (!$port->getVariableValue()->isFile() ||
205+
if (!$port->getVariableValue() || !$port->getVariableValue()->isFile() ||
206206
$port->getVariableValue()->getDirectory() === $box->getDirectory()) {
207207
continue;
208208
}
@@ -221,6 +221,7 @@ private function addCopyTasks(RootedTree $tree) {
221221
}
222222
$current->clearParents();
223223
$current->addParent($copy);
224+
$current->addDependency($copy);
224225

225226
// we also have to plug newly created output variable from copy box to the current input port...
226227
// this is needed because we need to have valid information in current box about directory of the variable

0 commit comments

Comments
 (0)