Skip to content

Commit

Permalink
Optimize knownProducts for direct-to-JAR compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
retronym committed Nov 3, 2020
1 parent c26521f commit 46d2659
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,24 @@ object JarUtils {
* "C:\develop\zinc\target\output.jar!sbt\internal\inc\Compile.class"
*/
class ClassInJar(override val toString: String) extends AnyVal {
def toClassFilePath: Option[ClassFilePath] = splitJarReference._2
def toClassFilePath: Option[ClassFilePath] = Option(toClassFilePathOrNull)
def toClassFilePathOrNull: ClassFilePath = {
val idx = toString.indexOf('!')
if (idx < 0) null
else toClassFilePath(idx)
}
def splitJarReference: (File, Option[ClassFilePath]) = {
if (toString.contains("!")) {
val Array(jar, cls) = toString.split("!")
// ClassInJar stores RelClass part with File.separatorChar, however actual paths in zips always use '/'
val classFilePath = cls.replace('\\', '/')
(new File(jar), Some(classFilePath))
} else {
val idx = toString.indexOf('!')
if (idx < 0) {
(new File(toString), None)
} else {
(new File(toString.substring(0, idx)), Some(toClassFilePath(idx)))
}
}
private def toClassFilePath(idx: Int): String = {
// ClassInJar stores RelClass part with File.separatorChar, however actual paths in zips always use '/'
toString.substring(idx + 1).replace('\\', '/')
}

/**
* Wraps the string value inside a java.io.File object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,10 @@ object Incremental {

private object AnalysisCallback {

private val parallelKnownProducts = "true" == System.getProperty(
"sbt.analysis.known.products.parallel"
)

/** Allow creating new callback instance to be used in each compile iteration */
class Builder(
internalBinaryToSourceClassName: String => Option[String],
Expand Down Expand Up @@ -1086,20 +1090,29 @@ private final class AnalysisCallback(

private def knownProducts(merged: Analysis) = {
// List classes defined in the files that were compiled in this run.
val ps = java.util.concurrent.ConcurrentHashMap.newKeySet[String]
val knownProducts: ParVector[VirtualFileRef] =
new ParVector(merged.relations.allSources.toVector)
.flatMap(merged.relations.products)
// extract product paths in parallel
val ps: java.util.Set[String] =
if (AnalysisCallback.parallelKnownProducts)
java.util.concurrent.ConcurrentHashMap.newKeySet[String]
else
new java.util.HashSet[String]()
val knownProducts: Vector[VirtualFileRef] =
merged.relations.allSources.toVector.flatMap(merged.relations.products)

def knownProductsPar =
if (AnalysisCallback.parallelKnownProducts) new ParVector(knownProducts) else knownProducts

// extract product paths
jo2o(output.getSingleOutputAsPath) match {
case Some(so) if so.getFileName.toString.endsWith(".jar") =>
knownProducts foreach { product =>
new JarUtils.ClassInJar(product.id).toClassFilePath foreach { path =>
ps.add(path.replace('\\', '/'))
knownProductsPar foreach { product =>
new JarUtils.ClassInJar(product.id).toClassFilePathOrNull match {
case null =>
case path =>
ps.add(path.replace('\\', '/'))
}
}
case Some(so) =>
knownProducts foreach { product =>
knownProductsPar foreach { product =>
val productPath = converter.toPath(product)
try {
ps.add(so.relativize(productPath).toString.replace('\\', '/'))
Expand Down

0 comments on commit 46d2659

Please sign in to comment.