@@ -2,33 +2,58 @@ package org.utbot.framework.minimization
2
2
3
3
import java.util.PriorityQueue
4
4
5
- private inline class ExecutionNumber (val number : Int )
5
+ @JvmInline
6
+ private value class ExecutionNumber (val number : Int )
6
7
7
- private inline class LineNumber (val number : Int )
8
+ @JvmInline
9
+ private value class LineNumber (val number : Int )
10
+
11
+ /* *
12
+ * Execution source priority (symbolic executions are considered more important than fuzzed executions).
13
+ * @see [UtSettings.preferSymbolicExecutionsDuringMinimization]
14
+ */
15
+ @JvmInline
16
+ private value class SourcePriority (val number : Int )
17
+
18
+ /* *
19
+ * A wrapper that combines covered lines with the execution source priority
20
+ */
21
+ private data class ExecutionCoverageInfo (
22
+ val sourcePriority : SourcePriority ,
23
+ val coveredLines : List <LineNumber >
24
+ )
8
25
9
26
/* *
10
27
* [Greedy essential algorithm](CONFLUENCE:Test+Minimization)
11
28
*/
12
29
class GreedyEssential private constructor(
13
- executionToCoveredLines : Map <ExecutionNumber , List < LineNumber > >
30
+ executionToCoveredLines : Map <ExecutionNumber , ExecutionCoverageInfo >
14
31
) {
32
+ private val executionToSourcePriority: Map <ExecutionNumber , SourcePriority > =
33
+ executionToCoveredLines
34
+ .mapValues { it.value.sourcePriority }
35
+
15
36
private val executionToUsefulLines: Map <ExecutionNumber , MutableSet <LineNumber >> =
16
37
executionToCoveredLines
17
- .mapValues { it.value.toMutableSet() }
38
+ .mapValues { it.value.coveredLines. toMutableSet() }
18
39
19
40
private val lineToUnusedCoveringExecutions: Map <LineNumber , MutableSet <ExecutionNumber >> =
20
41
executionToCoveredLines
21
- .flatMap { (execution, lines) -> lines.map { it to execution } }
42
+ .flatMap { (execution, lines) -> lines.coveredLines. map { it to execution } }
22
43
.groupBy({ it.first }) { it.second }
23
44
.mapValues { it.value.toMutableSet() }
24
45
25
46
private val executionByPriority =
26
- PriorityQueue (compareByDescending<Pair <ExecutionNumber , Int >> { it.second }.thenBy { it.first.number })
47
+ PriorityQueue (
48
+ compareByDescending<Triple <ExecutionNumber , Int , SourcePriority >> { it.second }
49
+ .thenBy { it.third.number }
50
+ .thenBy { it.first.number }
51
+ )
27
52
.apply {
28
53
addAll(
29
54
executionToCoveredLines
30
55
.keys
31
- .map { it to executionToUsefulLines[it]!! .size }
56
+ .map { Triple (it, executionToUsefulLines[it]!! .size, executionToSourcePriority[it] !! ) }
32
57
)
33
58
}
34
59
@@ -69,7 +94,7 @@ class GreedyEssential private constructor(
69
94
}
70
95
71
96
private fun executionToPriority (execution : ExecutionNumber ) =
72
- execution to executionToUsefulLines[execution]!! .size
97
+ Triple ( execution, executionToUsefulLines[execution]!! .size, executionToSourcePriority[execution] !! )
73
98
74
99
private fun removeLineFromExecution (execution : ExecutionNumber , line : LineNumber ) {
75
100
executionByPriority.remove(executionToPriority(execution))
@@ -87,12 +112,21 @@ class GreedyEssential private constructor(
87
112
* Minimizes the given [executions] assuming the map represents mapping from execution id to covered
88
113
* instruction ids.
89
114
*
115
+ * @param executions the mapping of execution ids to lists of lines covered by the execution.
116
+ * @param sourcePriorities execution priorities: lower values correspond to more important executions
117
+ * that should be kept everything else being equal.
118
+ *
90
119
* @return retained execution ids.
91
120
*/
92
- fun minimize (executions : Map <Int , List <Int >>): List <Int > {
121
+ fun minimize (executions : Map <Int , List <Int >>, sourcePriorities : Map < Int , Int > = emptyMap() ): List <Int > {
93
122
val convertedExecutions = executions
94
123
.entries
95
- .associate { (execution, lines) -> ExecutionNumber (execution) to lines.map { LineNumber (it) } }
124
+ .associate { (execution, lines) ->
125
+ ExecutionNumber (execution) to ExecutionCoverageInfo (
126
+ SourcePriority (sourcePriorities.getOrDefault(execution, 0 )),
127
+ lines.map { LineNumber (it) }
128
+ )
129
+ }
96
130
97
131
val prioritizer = GreedyEssential (convertedExecutions)
98
132
val list = mutableListOf<ExecutionNumber >()
0 commit comments