[Gradle] Implement IdeaKotlinClasspath interner

This very simple interner mechanism ensures that when import runs
within the IDE process, we de-duplicate existing file instances.

This might have an effect, because during GradleProjectResolution
we could have plenty source sets that refer to the same
files.

^KT-55492 Verification Pending
This commit is contained in:
Sebastian Sellmair
2022-12-16 10:11:41 +01:00
committed by Space Team
parent e32cff3b38
commit 38f310467a
2 changed files with 29 additions and 5 deletions
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.idea.tcs
import java.io.File
import java.io.Serializable
import java.lang.ref.WeakReference
import java.util.*
fun IdeaKotlinClasspath(files: Iterable<File>): IdeaKotlinClasspath = IdeaKotlinClasspath.from(files)
@@ -76,7 +78,8 @@ class IdeaKotlinClasspath private constructor(private val files: MutableSet<File
private const val serialVersionUID = 0L
fun normalise(file: File): File {
return file.absoluteFile.normalize()
val normalized = file.absoluteFile.normalize()
return intern(normalized)
}
fun from(files: Iterable<File>): IdeaKotlinClasspath {
@@ -88,5 +91,14 @@ class IdeaKotlinClasspath private constructor(private val files: MutableSet<File
}
fun empty() = IdeaKotlinClasspath(mutableSetOf())
private val interner = WeakHashMap<File, WeakReference<File>>()
private fun intern(file: File): File {
return interner.getOrPut(file) { WeakReference(file) }.get() ?: run {
interner[file] = WeakReference(file)
file
}
}
}
}
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.gradle.idea.test.tcs
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinClasspath
import java.io.File
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
import kotlin.test.*
class IdeaKotlinClasspathTest {
@@ -62,4 +59,19 @@ class IdeaKotlinClasspathTest {
classpath.remove(File("test").absoluteFile)
assertTrue(classpath.isEmpty())
}
@Test
fun `test - classpath interner`() {
val classpath1 = IdeaKotlinClasspath()
val classpath2 = IdeaKotlinClasspath()
val fileAInstance1 = File("a")
val fileAInstance2 = File("a")
classpath1.add(fileAInstance1)
classpath2.add(fileAInstance2)
/* Check that fileAInstance2 got interned and will re-use instance 1 */
assertSame(classpath1.single(), classpath2.single())
}
}