[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,15 +5,22 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure 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.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.psi.KtFile 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) { 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) { fun getFileStructure(ktFile: KtFile): FileStructure = cache.computeIfAbsent(ktFile) {
FileStructure.build(ktFile, moduleResolveComponents) FileStructure.build(ktFile, moduleResolveComponents)