From 7a6e6be7bd0773c6fefcb391212e648f67637486 Mon Sep 17 00:00:00 2001 From: Nikolay Rykunov Date: Wed, 4 Feb 2026 13:44:49 +0100 Subject: [PATCH] [fus] LSP-424: Don't recreate empty providers for each call GitOrigin-RevId: 3f9d6266b1f7a8a9b6f296a5beff5c4250764bfc --- .../StatisticsEventLogProvidersHolder.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogProvidersHolder.kt b/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogProvidersHolder.kt index 932966602f6c..ef18259798b7 100644 --- a/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogProvidersHolder.kt +++ b/platform/statistics/src/com/intellij/internal/statistic/eventLog/StatisticsEventLogProvidersHolder.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.internal.statistic.eventLog import com.intellij.ide.plugins.PluginManagerCore @@ -13,6 +13,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.Service import com.intellij.util.PlatformUtils import kotlinx.coroutines.CoroutineScope +import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicReference @Service(Service.Level.APP) @@ -24,6 +25,9 @@ internal class StatisticsEventLogProvidersHolder(coroutineScope: CoroutineScope) private val eventLoggerProvidersExt: AtomicReference>> = AtomicReference(calculateEventLogProviderExt()) + // Cache for empty providers by [recorderId] to avoid creating new instances on every call + private val emptyProviders: MutableMap = ConcurrentHashMap() + init { if (ApplicationManager.getApplication().extensionArea.hasExtensionPoint(EP_NAME)) { EP_NAME.addChangeListener(coroutineScope) { eventLoggerProviders.set(calculateEventLogProvider()) } @@ -31,14 +35,19 @@ internal class StatisticsEventLogProvidersHolder(coroutineScope: CoroutineScope) } } + private fun getOrCreateEmptyProvider(recorderId: String): StatisticsEventLoggerProvider { + return emptyProviders.computeIfAbsent(recorderId) { EmptyStatisticsEventLoggerProvider(recorderId) } + } + fun getEventLogProvider(recorderId: String): StatisticsEventLoggerProvider = - eventLoggerProviders.get()[recorderId] ?: EmptyStatisticsEventLoggerProvider(recorderId) + eventLoggerProviders.get()[recorderId] ?: getOrCreateEmptyProvider(recorderId) fun getEventLogProviders(): Collection = eventLoggerProviders.get().values fun getEventLogProvidersExt(recorderId: String): Collection = - eventLoggerProvidersExt.get()[recorderId] ?: listOf(EmptyStatisticsEventLoggerProvider(recorderId)) + eventLoggerProvidersExt.get()[recorderId] + ?: listOf(getOrCreateEmptyProvider(recorderId)) private fun calculateEventLogProvider(): Map { return calculateEventLogProviderExt().mapValues { @@ -47,7 +56,7 @@ internal class StatisticsEventLogProvidersHolder(coroutineScope: CoroutineScope) else PluginUtils.getPluginDescriptorOrPlatformByClassName(provider::class.java.name) ?.let { plugin -> PluginManagerCore.isDevelopedExclusivelyByJetBrains(plugin) } ?: false - } ?: EmptyStatisticsEventLoggerProvider(it.key) + } ?: getOrCreateEmptyProvider(it.key) } }