mirror of
https://github.com/sbt/sbt.git
synced 2026-08-22 06:07:24 +02:00
Don't use Set[Incomplete]
It's very expensive to compute the hash code of a deeply nested Incomplete. To prevent a loop, we only want to check for object equality which we can do with IdentityHashMap
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user