summaryrefslogtreecommitdiff
path: root/src/main/scala/forge/Evaluator.scala
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-10-29 10:58:57 -0700
committerLi Haoyi <haoyi.sg@gmail.com>2017-10-29 10:58:57 -0700
commitd3ac2ca2c3a581152323d315d3765a18c2fb02c0 (patch)
treea84748888f6fa501f962f88b0000672742cbe17f /src/main/scala/forge/Evaluator.scala
parent1b940e9c1341f6f8e42293661b6dcdbffecbe66e (diff)
downloadmill-d3ac2ca2c3a581152323d315d3765a18c2fb02c0.tar.gz
mill-d3ac2ca2c3a581152323d315d3765a18c2fb02c0.tar.bz2
mill-d3ac2ca2c3a581152323d315d3765a18c2fb02c0.zip
WIP
- Making `groupAroundNamedTargets` return a `MutableBiMap` - Make `evaluateGroupCached` also take note of the `sideHash`es of upstream targets, to handle cases like `Path`s where the path you're returning doesn't change but we still want to invalidate it anyway
Diffstat (limited to 'src/main/scala/forge/Evaluator.scala')
-rw-r--r--src/main/scala/forge/Evaluator.scala67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/main/scala/forge/Evaluator.scala b/src/main/scala/forge/Evaluator.scala
index fae4447b..d19b8aa3 100644
--- a/src/main/scala/forge/Evaluator.scala
+++ b/src/main/scala/forge/Evaluator.scala
@@ -4,7 +4,6 @@ package forge
import play.api.libs.json.{JsValue, Json}
import scala.collection.mutable
-import scala.io.Codec
import ammonite.ops._
class Evaluator(workspacePath: Path,
labeling: Map[Target[_], Seq[String]]){
@@ -19,38 +18,58 @@ class Evaluator(workspacePath: Path,
val evaluated = new MutableOSet[Target[_]]
val results = mutable.Map.empty[Target[_], Any]
- for (group <- sortedGroups){
- val (newResults, newEvaluated) = evaluateGroupCached(group, results)
+ val groupHashes = mutable.Map.empty[Int, Int]
+ for (groupIndex <- sortedGroups.keys()){
+ val group = sortedGroups.lookupKey(groupIndex)
+ val (inputsHash, newResults, newEvaluated) = evaluateGroupCached(
+ group,
+ results,
+ groupHashes,
+ sortedGroups
+ )
evaluated.appendAll(newEvaluated)
for((k, v) <- newResults) results.put(k, v)
+ groupHashes(groupIndex) = inputsHash
}
+
Evaluator.Results(targets.items.map(results), evaluated)
}
def evaluateGroupCached(group: OSet[Target[_]],
- results: collection.Map[Target[_], Any]) = {
+ results: collection.Map[Target[_], Any],
+ groupHashes: collection.Map[Int, Int],
+ sortedGroups: MultiBiMap[Int, Target[_]]) = {
+
+ pprint.log(group)
+ val (externalInputs, terminals) = partitionGroupInputOutput(group, results)
+ val upstreamGroupIds = OSet.from(externalInputs.map(sortedGroups.lookupValue), dedup = true)
+
+ val inputsHash =
+ externalInputs.toIterator.map(results).hashCode +
+ group.toIterator.map(_.sideHash).hashCode +
+ upstreamGroupIds.toIterator.map(groupHashes).hashCode
- val (inputsHash0, terminals) = partitionGroupInputOutput(group, results)
- val inputsHash = inputsHash0 + group.toIterator.map(_.externalHash).sum
val primeLabel = labeling(terminals.items(0))
+
val targetDestPath = workspacePath / primeLabel
val metadataPath = targetDestPath / up / (targetDestPath.last + ".forge.json")
val cached = for{
json <- util.Try(Json.parse(read.getInputStream(metadataPath))).toOption
(hash, terminalResults) <- Json.fromJson[(Int, Seq[JsValue])](json).asOpt
+ _ = println("cached hash " + hash)
if hash == inputsHash
- } yield (hash, terminalResults)
+ } yield terminalResults
cached match{
- case Some((hash, terminalResults)) =>
+ case Some(terminalResults) =>
val newResults = mutable.Map.empty[Target[_], Any]
for((terminal, res) <- terminals.items.zip(terminalResults)){
newResults(terminal) = terminal.formatter.reads(res).get
}
- (newResults, Nil)
+ (inputsHash, newResults, Nil)
case _ =>
val (newResults, newEvaluated, terminalResults) = {
@@ -60,10 +79,12 @@ class Evaluator(workspacePath: Path,
write.over(
metadataPath,
- Json.prettyPrint(Json.toJson((inputsHash , terminalResults))).getBytes(Codec.UTF8.charSet),
+ Json.prettyPrint(
+ Json.toJson((inputsHash , terminalResults))
+ ),
)
- (newResults, newEvaluated)
+ (inputsHash, newResults, newEvaluated)
}
}
@@ -72,10 +93,8 @@ class Evaluator(workspacePath: Path,
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)
+ (OSet.from(externalInputs, dedup=true), terminals)
}
def evaluateGroup(group: OSet[Target[_]],
@@ -115,13 +134,13 @@ object Evaluator{
class TopoSorted private[Evaluator] (val values: OSet[Target[_]])
case class Results(values: Seq[Any], evaluated: OSet[Target[_]])
def groupAroundNamedTargets(topoSortedTargets: TopoSorted,
- labeling: Map[Target[_], Seq[String]]): OSet[OSet[Target[_]]] = {
- val grouping = new MultiBiMap[Int, Target[_]]()
+ labeling: Map[Target[_], Seq[String]]): MultiBiMap[Int, Target[_]] = {
+
+ val grouping = new MutableMultiBiMap[Int, Target[_]]()
var groupCount = 0
for(target <- topoSortedTargets.values.items.reverseIterator){
-
if (!grouping.containsValue(target)){
grouping.add(groupCount, target)
groupCount += 1
@@ -140,18 +159,14 @@ object Evaluator{
}
}
}
- val output = mutable.Buffer.empty[OSet[Target[_]]]
- for(target <- topoSortedTargets.values.items.reverseIterator){
+ val output = new MutableMultiBiMap[Int, Target[_]]
+ for(target <- topoSortedTargets.values.items){
for(targetGroup <- grouping.lookupValueOpt(target)){
- output.append(
- OSet.from(
- grouping.removeAll(targetGroup)
- .sortBy(topoSortedTargets.values.items.indexOf)
- )
- )
+ val shifted = grouping.removeAll(targetGroup)
+ output.addAll(output.keys().length, shifted.reverse)
}
}
- OSet.from(output.reverse)
+ output
}
/**