summaryrefslogtreecommitdiff
path: root/src/main/scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-10-28 17:42:30 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2017-10-28 17:47:00 -0700
commit25716b9040a64eb0f3b80dd20480a323222db8ca (patch)
tree9f514a5798145c458136e35a4360cb7284063bc4 /src/main/scala
parent8a85ac816b5514c481341456061ed26a83f72bb0 (diff)
downloadmill-25716b9040a64eb0f3b80dd20480a323222db8ca.tar.gz
mill-25716b9040a64eb0f3b80dd20480a323222db8ca.tar.bz2
mill-25716b9040a64eb0f3b80dd20480a323222db8ca.zip
Break up `Evaluator#evaluateGroup` into a few smaller methods
Diffstat (limited to 'src/main/scala')
-rw-r--r--src/main/scala/forge/Evaluator.scala103
1 files changed, 57 insertions, 46 deletions
diff --git a/src/main/scala/forge/Evaluator.scala b/src/main/scala/forge/Evaluator.scala
index 4d9a435e..36ef20f6 100644
--- a/src/main/scala/forge/Evaluator.scala
+++ b/src/main/scala/forge/Evaluator.scala
@@ -1,5 +1,6 @@
package forge
+import java.nio.file.Path
import java.nio.{file => jnio}
import play.api.libs.json.Json
@@ -27,8 +28,7 @@ class Evaluator(workspacePath: jnio.Path,
val evaluated = new MutableOSet[Target[_]]
val results = mutable.Map.empty[Target[_], Any]
for (group <- sortedGroups){
- println("Evaluating group " + group)
- val (newResults, newEvaluated) = evaluateGroup(group, results)
+ val (newResults, newEvaluated) = evaluateGroupCached(group, results)
evaluated.appendAll(newEvaluated)
for((k, v) <- newResults) results.put(k, v)
@@ -36,61 +36,71 @@ class Evaluator(workspacePath: jnio.Path,
Evaluator.Results(targets.items.map(results), evaluated)
}
- def evaluateGroup(group: OSet[Target[_]],
- results: collection.Map[Target[_], Any]) = {
- val allInputs = group.items.flatMap(_.inputs)
- val (internalInputs, externalInputs) = allInputs.partition(group.contains)
- val internalInputSet = internalInputs.toSet
- val inputResults = externalInputs.distinct.map(results).toIndexedSeq
+ def evaluateGroupCached(group: OSet[Target[_]],
+ results: collection.Map[Target[_], Any]) = {
- val newResults = mutable.Map.empty[Target[_], Any]
- val newEvaluated = mutable.Buffer.empty[Target[_]]
-
- val terminals = group.filter(!internalInputSet(_))
- val primeTerminal = terminals.items(0)
+ val (inputsHash, terminals) = partitionGroupInputOutput(group, results)
+ val primeLabel = labeling(terminals.items(0)).mkString("/")
- val primeLabel = labeling(primeTerminal).mkString("/")
- val targetDestPath = workspacePath.resolve(
- jnio.Paths.get(primeLabel)
- )
- val anyDirty = group.exists(_.dirty)
- deleteRec(targetDestPath)
-
- val inputsHash = inputResults.hashCode
resultCache.get(primeLabel) match{
- case Some((hash, terminalResults))
- if hash == inputsHash && !anyDirty =>
+ case Some((hash, terminalResults)) if hash == inputsHash && !group.exists(_.dirty) =>
+ val newResults = mutable.Map.empty[Target[_], Any]
for((terminal, res) <- terminals.items.zip(terminalResults)){
- newResults(terminal) = primeTerminal.formatter.reads(Json.parse(res)).get
+ newResults(terminal) = terminal.formatter.reads(Json.parse(res)).get
}
+ (newResults, Nil)
case _ =>
- val terminalResults = mutable.Buffer.empty[String]
- for(target <- group.items){
- newEvaluated.append(target)
- val targetInputValues = target.inputs.toVector.map(x =>
- newResults.getOrElse(x, results(x))
- )
- if (!labeling.contains(target)) {
- val res = target.evaluate(new Args(targetInputValues, targetDestPath))
- newResults(target) = res
- }else{
- val (res, serialized) = target.evaluateAndWrite(
- new Args(targetInputValues, targetDestPath)
- )
- if (!internalInputSet(target)){
- terminalResults.append(serialized)
-
- }
- newResults(target) = res
- }
+ val (newResults, newEvaluated, terminalResults) = {
+ evaluateGroup(group, results, terminals, primeLabel)
}
resultCache(primeLabel) = (inputsHash, terminalResults)
+ (newResults, newEvaluated)
+ }
+ }
+ def partitionGroupInputOutput(group: OSet[Target[_]],
+ results: collection.Map[Target[_], Any]) = {
+ val allInputs = group.items.flatMap(_.inputs)
+ val (internalInputs, externalInputs) = allInputs.partition(group.contains)
+ val internalInputSet = internalInputs.toSet
+ val inputResults = externalInputs.distinct.map(results).toIndexedSeq
+ val inputsHash = inputResults.hashCode
+ val terminals = group.filter(!internalInputSet(_))
+ (inputsHash, terminals)
+ }
+
+ def evaluateGroup(group: OSet[Target[_]],
+ results: collection.Map[Target[_], Any],
+ terminals: OSet[Target[_]],
+ primeLabel: String) = {
+ val targetDestPath = workspacePath.resolve(jnio.Paths.get(primeLabel))
+ deleteRec(targetDestPath)
+ val terminalResults = mutable.Buffer.empty[String]
+ val newEvaluated = mutable.Buffer.empty[Target[_]]
+ val newResults = mutable.Map.empty[Target[_], Any]
+ for (target <- group.items) {
+ newEvaluated.append(target)
+ val targetInputValues = target.inputs.toVector.map(x =>
+ newResults.getOrElse(x, results(x))
+ )
+ if (!labeling.contains(target)) {
+ newResults(target) = target.evaluate(new Args(targetInputValues, targetDestPath))
+ } else {
+ val (res, serialized) = target.evaluateAndWrite(
+ new Args(targetInputValues, targetDestPath)
+ )
+ if (terminals.contains(target)) {
+ terminalResults.append(serialized)
+
+ }
+ newResults(target) = res
+ }
}
- (newResults, newEvaluated)
+ (newResults, newEvaluated, terminalResults)
}
+
def deleteRec(path: jnio.Path) = {
if (jnio.Files.exists(path)){
import collection.JavaConverters._
@@ -148,7 +158,8 @@ object Evaluator{
}
/**
- * Takes the given targets, finds
+ * Takes the given targets, finds all the targets they transitively depend
+ * on, and sort them topologically. Fails if there are dependency cycles
*/
def topoSortedTransitiveTargets(sourceTargets: OSet[Target[_]]): TopoSorted = {
val transitiveTargets = new MutableOSet[Target[_]]
@@ -165,7 +176,7 @@ object Evaluator{
val numberedEdges =
for(t <- transitiveTargets.items)
- yield t.inputs.map(targetIndices)
+ yield t.inputs.map(targetIndices)
val sortedClusters = Tarjans(numberedEdges)
val nonTrivialClusters = sortedClusters.filter(_.length > 1)