Merge pull request #4806 from eatkins/incomplete-hash

Don't use Set[Incomplete]
This commit is contained in:
eugene yokota 2019-06-14 09:10:39 +02:00 committed by GitHub
commit 57a86e60f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 13 additions and 8 deletions

View File

@ -9,6 +9,7 @@ package sbt
package internal package internal
import java.text.DateFormat import java.text.DateFormat
import java.util.{ Collections, IdentityHashMap }
import Def.ScopedKey import Def.ScopedKey
import Keys.{ showSuccess, showTiming, timingFormat } import Keys.{ showSuccess, showTiming, timingFormat }
@ -114,19 +115,23 @@ object Aggregation {
)(implicit display: Show[ScopedKey[_]]): State = { )(implicit display: Show[ScopedKey[_]]): State = {
val complete = timedRun[T](s, ts, extra) val complete = timedRun[T](s, ts, extra)
showRun(complete, show) showRun(complete, show)
@tailrec def findReload( /*
incomplete: Incomplete, * In the first implementation, we tried to use Set[Incomplete] for visited. It had very poor
remaining: List[Incomplete], * performance because hashCode can be expensive on Incomplete -- especially when the
visited: Set[Incomplete] * Incomplete has many instances in the causes field.
): Boolean = { */
lazy val visited = Collections
.newSetFromMap[Incomplete](new IdentityHashMap[Incomplete, java.lang.Boolean])
@tailrec def findReload(incomplete: Incomplete, remaining: List[Incomplete]): Boolean = {
visited.add(incomplete)
incomplete.directCause.contains(Reload) || ((remaining ::: incomplete.causes.toList) incomplete.directCause.contains(Reload) || ((remaining ::: incomplete.causes.toList)
.filterNot(visited) match { .filterNot(visited.contains) match {
case Nil => false case Nil => false
case h :: tail => findReload(h, tail.filterNot(visited), visited + incomplete) case h :: tail => findReload(h, tail.filterNot(visited.contains))
}) })
} }
complete.results match { complete.results match {
case Inc(i) if findReload(i, i.causes.toList, Set.empty) => case Inc(i) if findReload(i, i.causes.toList) =>
val remaining = s.currentCommand.toList ::: s.remainingCommands val remaining = s.currentCommand.toList ::: s.remainingCommands
complete.state.copy(remainingCommands = Exec("reload", None, None) :: remaining) complete.state.copy(remainingCommands = Exec("reload", None, None) :: remaining)
case Inc(i) => complete.state.handleError(i) case Inc(i) => complete.state.handleError(i)