@@ -7,12 +7,12 @@ import java.net.URLClassLoader
77import java .nio .file .{Files , Path , Paths }
88import java .util .Properties
99import java .util .concurrent .ConcurrentHashMap
10- import scala .collection .immutable .Map
10+ import scala .collection .immutable .TreeMap
1111
1212object AnnexScalaInstance {
1313 // See the comment on getAnnexScalaInstance as to why this is necessary
14- private val instanceCache : ConcurrentHashMap [String , AnnexScalaInstance ] =
15- new ConcurrentHashMap [String , AnnexScalaInstance ]()
14+ private val instanceCache : ConcurrentHashMap [Set [ Path ] , AnnexScalaInstance ] =
15+ new ConcurrentHashMap [Set [ Path ] , AnnexScalaInstance ]()
1616
1717 /**
1818 * We only need to care about minimizing the number of AnnexScalaInstances we create if things are being run as a
@@ -48,7 +48,7 @@ object AnnexScalaInstance {
4848 * from a prior compilation in combination with a new ScalaInstance for the current compilation. Or there's some issue
4949 * with Scala's classpath caching.
5050 *
51- * If all three caches are enabled (this cache + Zinc claspath + Scala compiler), then the non-determinism seems go
51+ * If all three caches are enabled (this cache + Zinc claspath + Scala compiler), then the non-determinism seems to go
5252 * away.
5353 *
5454 * If this cache is not used, but the Zinc classpath + Scala compiler caches are used, then non-determinsm shows up in
@@ -67,11 +67,22 @@ object AnnexScalaInstance {
6767 * any different from leaving Zinc's cache enabled.
6868 */
6969 private def getAnnexScalaInstance (allJars : Array [File ], workDir : Path ): AnnexScalaInstance = {
70- // We need to remove the sandbox prefix from the paths in order to compare them.
70+ // We want to compare short paths to avoid the Bazel sandbox prefix and arch/config specific parts of the path
71+ // We use a set because we don't care about ordering for comparison purposes
7172 val mapBuilder = Map .newBuilder[Path , Path ]
73+ val keyBuilder = Set .newBuilder[Path ]
74+ val absoluteWorkDir = workDir.toAbsolutePath().normalize()
7275 allJars.foreach { jar =>
73- val comparableJarPath = jar.toPath().toAbsolutePath().normalize()
74- mapBuilder.addOne(jar.toPath -> workDir.toAbsolutePath().normalize().relativize(comparableJarPath))
76+ val absoluteJarPath = jar.toPath().toAbsolutePath().normalize()
77+
78+ // Remove the arch/config specific parts of the path.
79+ val comparablePath = FileUtil .bazelShortPath(
80+ // Remove the sandbox prefix from the path
81+ absoluteWorkDir.relativize(absoluteJarPath),
82+ replaceExternal = false ,
83+ )
84+ mapBuilder.addOne(jar.toPath -> comparablePath)
85+ keyBuilder.addOne(comparablePath)
7586 }
7687 val workRequestJarToWorkerJar = mapBuilder.result()
7788
@@ -84,10 +95,10 @@ object AnnexScalaInstance {
8495 // but that would require hashing the all the classpath jars on every compilation request. I
8596 // imagine that would cause a performance hit.
8697 //
87- // I also imagine it is extremeley rare to be mutating the contents of compiler classpath jars
98+ // I also imagine it is extremely rare to be mutating the contents of compiler classpath jars
8899 // while keeping the names the same, e.g., generating new scala library jar for scala 2.13.14.
89100 // As a result I'm leaving this string based for now.
90- val key = workRequestJarToWorkerJar.values.mkString( " : " )
101+ val key = keyBuilder.result( )
91102
92103 Option (instanceCache.get(key)).getOrElse {
93104 // Copy all the jars to the worker's directory because in a sandboxed world the
0 commit comments