blob: 43b4f3536b5896bf82910aa146fa817b557e8038 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
package forge
import java.nio.{file => jnio}
import sourcecode.Enclosing
import scala.collection.mutable
class Evaluator(workspacePath: jnio.Path,
enclosingBase: DefCtx){
val resultCache = mutable.Map.empty[String, (Int, Any)]
def evaluate(targets: Seq[Target[_]]): Evaluator.Results = {
jnio.Files.createDirectories(workspacePath)
val sortedTargets = Evaluator.topoSortedTransitiveTargets(targets)
val evaluated = mutable.Buffer.empty[Target[_]]
val results = mutable.Map.empty[Target[_], Any]
for (target <- sortedTargets){
val inputResults = target.inputs.map(results).toIndexedSeq
val targetDestPath = {
val enclosingStr = target.defCtx.label
val targetDestPath = workspacePath.resolve(
jnio.Paths.get(enclosingStr.stripSuffix(enclosingBase.label))
)
deleteRec(targetDestPath)
targetDestPath
}
val inputsHash = inputResults.hashCode
resultCache.get(target.defCtx.label) match{
case Some((hash, res)) if hash == inputsHash && !target.dirty =>
results(target) = res
case _ =>
evaluated.append(target)
val res = target.evaluate(new Args(inputResults, targetDestPath))
resultCache(target.defCtx.label) = (inputsHash, res)
results(target) = res
}
}
Evaluator.Results(targets.map(results), evaluated)
}
def deleteRec(path: jnio.Path) = {
if (jnio.Files.exists(path)){
import collection.JavaConverters._
jnio.Files.walk(path).iterator()
.asScala
.toArray
.reverseIterator
.map(jnio.Files.deleteIfExists)
}
}
}
object Evaluator{
case class Results(values: Seq[Any], evaluated: Seq[Target[_]])
/**
* Takes the given targets, finds
*/
def topoSortedTransitiveTargets(sourceTargets: Seq[Target[_]]) = {
val transitiveTargetSet = mutable.Set.empty[Target[_]]
val transitiveTargets = mutable.Buffer.empty[Target[_]]
def rec(t: Target[_]): Unit = {
if (transitiveTargetSet.contains(t)) () // do nothing
else {
transitiveTargetSet.add(t)
transitiveTargets.append(t)
t.inputs.foreach(rec)
}
}
sourceTargets.foreach(rec)
val targetIndices = transitiveTargets.zipWithIndex.toMap
val numberedEdges =
for(i <- transitiveTargets.indices)
yield transitiveTargets(i).inputs.map(targetIndices)
val sortedClusters = Tarjans(numberedEdges)
val nonTrivialClusters = sortedClusters.filter(_.length > 1)
assert(nonTrivialClusters.isEmpty, nonTrivialClusters)
sortedClusters.flatten.map(transitiveTargets)
}
}
|