[LL] Use soft references in FileStructureCache

- We can also soft-reference the `KtFile` key. Chances are, if the
  `KtFile` can be garbage-collected, we do not need a `FileStructure`
  instance for it either.

^KT-65978 fixed
This commit is contained in:
Marco Pennekamp
2024-02-27 17:45:14 +01:00
committed by Space Team
parent 8de680314e
commit 5dec87eba8
@@ -5,19 +5,26 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.psi.KtFile
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
/**
* Belongs to a [org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession]
* Caches [FileStructure] instances for an [LLFirResolveSession][org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession].
*/
internal class FileStructureCache(private val moduleResolveComponents: LLFirModuleResolveComponents) {
private val cache = ConcurrentHashMap<KtFile, FileStructure>()
/**
* File structure elements can be rebuilt at any time and do not need to be unique (like FIR symbols), so they can be soft-referenced
* from this cache to reduce memory consumption. Any `analyze` call in a file causes file structure elements to be built, so during
* operations which cause a lot of files to be analyzed (such as Find Usages), a session might accumulate a lot of file structure
* elements.
*/
private val cache: ConcurrentMap<KtFile, FileStructure> = ContainerUtil.createConcurrentSoftKeySoftValueMap()
fun getFileStructure(ktFile: KtFile): FileStructure = cache.computeIfAbsent(ktFile) {
FileStructure.build(ktFile, moduleResolveComponents)
}
fun getCachedFileStructure(ktFile: KtFile): FileStructure? = cache[ktFile]
}
}