diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt index f82c20fd689..be0fe7fc6de 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/file/structure/FileStructureCache.kt @@ -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() + /** + * 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 = ContainerUtil.createConcurrentSoftKeySoftValueMap() fun getFileStructure(ktFile: KtFile): FileStructure = cache.computeIfAbsent(ktFile) { FileStructure.build(ktFile, moduleResolveComponents) } fun getCachedFileStructure(ktFile: KtFile): FileStructure? = cache[ktFile] -} \ No newline at end of file +}