From ac3221470fa4bafd534adaf366aa16e665646874 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 21 May 2019 16:28:53 +0300 Subject: [PATCH] refactor interners: extract common super class, generalize usages GitOrigin-RevId: 7958f52e8fb1c6a1b95b9f9c88e6cc3e0e5b5d90 --- .../intellij/compiler/impl/TreeBasedMap.java | 12 ++-- .../compiler/impl/TreeBasedPathsSet.java | 4 +- .../ide/util/importProject/ModuleInsight.java | 3 +- .../psi/impl/ConstantExpressionVisitor.java | 3 +- .../psi/impl/source/PsiModifierListImpl.java | 3 +- .../reference/RefManagerImpl.java | 3 +- .../ide/plugins/IdeaPluginDescriptorImpl.java | 3 +- .../ide/plugins/LoadDescriptorsContext.java | 4 +- .../psi/impl/smartPointers/Identikit.java | 10 +++- .../intellij/diff/util/DiffPerformanceTest.kt | 3 +- .../manage/DeduplicateVisitorsSupplier.kt | 5 +- .../daemon/impl/LocalInspectionsPass.java | 3 +- .../impl/config/IntentionManagerSettings.java | 4 +- .../offlineViewer/OfflineViewParseUtil.java | 3 +- .../codeInspection/ui/InspectionTreeNode.java | 5 +- .../InspectionViewSuppressActionHolder.java | 3 +- .../ui/ProblemDescriptionNode.java | 3 +- .../ui/SuppressableInspectionTreeNode.java | 5 +- .../compiler/PatternCompilerImpl.java | 3 +- .../module/impl/ModuleManagerImpl.java | 3 +- .../util/objectTree/ThrowableInterner.java | 3 +- .../util/containers/HashSetInterner.java | 58 +++++++++++++++++++ .../intellij/util/containers/Interner.java | 45 ++------------ .../util/containers/StringInterner.java | 2 +- .../util/containers/WeakInterner.java | 5 +- platform/util/src/org/jdom/JDOMInterner.java | 3 +- .../vcs/log/data/VcsUserRegistryImpl.kt | 3 +- .../com/intellij/vcs/log/impl/VcsRefImpl.java | 3 +- .../annotate/GitAnnotationProvider.java | 3 +- .../ui/GeneratedStructureModel.java | 9 +-- .../util/xml/impl/DynamicGenericInfo.java | 7 ++- 31 files changed, 138 insertions(+), 88 deletions(-) create mode 100644 platform/util/src/com/intellij/util/containers/HashSetInterner.java diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java index a88ef1c76376..bbbe8c86062b 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java @@ -2,7 +2,7 @@ package com.intellij.compiler.impl; import com.intellij.util.containers.EmptyIterator; -import com.intellij.util.containers.StringInterner; +import com.intellij.util.containers.Interner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -15,11 +15,11 @@ import java.util.Stack; */ public class TreeBasedMap { private Node myRoot = new Node<>(); - private final StringInterner myInterner; + private final Interner myInterner; private final char mySeparator; private int mySize = 0; - public TreeBasedMap(StringInterner table, final char separator) { + public TreeBasedMap(Interner table, final char separator) { myInterner = table; mySeparator = separator; } @@ -48,12 +48,12 @@ public class TreeBasedMap { } @Nullable - public Node findRelative(String text, boolean create, final StringInterner table) { + public Node findRelative(String text, boolean create, final Interner table) { return findRelative(text, 0, create, table); } @Nullable - private Node findRelative(final String text, final int nameStartIndex, final boolean create, final StringInterner table) { + private Node findRelative(final String text, final int nameStartIndex, final boolean create, final Interner table) { if (myChildren == null && !create) { return null; } @@ -80,7 +80,7 @@ public class TreeBasedMap { } @NotNull - private Node addChild(final StringInterner table, final String text, final int nameStartIndex, final int nameEndIndex) { + private Node addChild(final Interner table, final String text, final int nameStartIndex, final int nameEndIndex) { if (myChildren == null) { myChildren = new HashMap<>(3, 0.95f); } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java index f4e327df0cc0..a5b1d596f929 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java @@ -15,7 +15,7 @@ */ package com.intellij.compiler.impl; -import com.intellij.util.containers.StringInterner; +import com.intellij.util.containers.Interner; /** * @author Eugene Zhuravlev @@ -23,7 +23,7 @@ import com.intellij.util.containers.StringInterner; public class TreeBasedPathsSet { private final TreeBasedMap myMap; - public TreeBasedPathsSet(StringInterner interner, char separator) { + public TreeBasedPathsSet(Interner interner, char separator) { myMap = new TreeBasedMap<>(interner, separator); } diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java b/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java index b5124f68f279..73c3a1e7a5bc 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/ModuleInsight.java @@ -24,6 +24,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import com.intellij.util.text.StringFactory; import org.jetbrains.annotations.NotNull; @@ -47,7 +48,7 @@ public abstract class ModuleInsight { private final Map> mySourceRootToReferencedPackagesMap = new HashMap<>(); private final Map> mySourceRootToPackagesMap = new HashMap<>(); private final Map> myJarToPackagesMap = new HashMap<>(); - private final StringInterner myInterner = new StringInterner(); + private final Interner myInterner = new StringInterner(); private List myModules; private List myLibraries; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java index ea962e14139a..aff7ef73259f 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java @@ -21,6 +21,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.ConstantEvaluationOverflowException; import com.intellij.psi.util.ConstantExpressionUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -34,7 +35,7 @@ import java.util.concurrent.ConcurrentMap; @SuppressWarnings("UnnecessaryBoxing") class ConstantExpressionVisitor extends JavaElementVisitor implements PsiConstantEvaluationHelper.AuxEvaluator { - private final StringInterner myInterner = new StringInterner(); + private final Interner myInterner = new StringInterner(); private Set myVisitedVars; private final Map myCachedValues = new HashMap<>(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java index 9563bcc4c37c..b769d2d69d85 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java @@ -19,6 +19,7 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.BitUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakInterner; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; @@ -303,7 +304,7 @@ public class PsiModifierListImpl extends JavaStubPsiElement } private static class ModifierCache { - static final WeakInterner> ourInterner = new WeakInterner<>(); + static final Interner> ourInterner = new WeakInterner<>(); final PsiFile file; final List modifiers; final long modCount; diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java index 70764d0f684c..8904e77f3170 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java @@ -41,6 +41,7 @@ import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.ConcurrencyUtil; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import gnu.trove.THashMap; import org.jdom.Element; @@ -82,7 +83,7 @@ public class RefManagerImpl extends RefManager { private final Map myExtensions = new THashMap<>(); private final Map myLanguageExtensions = new HashMap<>(); - private final StringInterner myNameInterner = new StringInterner(); + private final Interner myNameInterner = new StringInterner(); public RefManagerImpl(@NotNull Project project, @Nullable AnalysisScope scope, @NotNull GlobalInspectionContext context) { myProject = project; diff --git a/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java b/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java index 9f7e8e57108c..ef3d32ae0025 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/IdeaPluginDescriptorImpl.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtilRt; import com.intellij.util.ObjectUtils; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSetInterner; import com.intellij.util.containers.Interner; import com.intellij.util.containers.MultiMap; import com.intellij.util.xmlb.BeanBinding; @@ -241,7 +242,7 @@ public class IdeaPluginDescriptorImpl implements IdeaPluginDescriptor { // only for CoreApplicationEnvironment if (stringInterner == null) { - stringInterner = new Interner<>(SERVICE_QUALIFIED_ELEMENT_NAMES); + stringInterner = new HashSetInterner<>(SERVICE_QUALIFIED_ELEMENT_NAMES); } MultiMap extensions = myExtensions; diff --git a/platform/core-impl/src/com/intellij/ide/plugins/LoadDescriptorsContext.java b/platform/core-impl/src/com/intellij/ide/plugins/LoadDescriptorsContext.java index d36cd130d5b7..58c4e4aa71a6 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/LoadDescriptorsContext.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/LoadDescriptorsContext.java @@ -6,6 +6,7 @@ import com.intellij.openapi.util.SafeJdomFactory; import com.intellij.util.SmartList; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSetInterner; import com.intellij.util.containers.Interner; import org.jdom.*; import org.jetbrains.annotations.NotNull; @@ -89,7 +90,8 @@ final class LoadDescriptorsContext implements AutoCloseable { private static final Set CLASS_NAMES = ContainerUtil.newIdentityTroveSet(CLASS_NAME_LIST); - private final Interner stringInterner = new Interner(ContainerUtil.concat(CLASS_NAME_LIST, IdeaPluginDescriptorImpl.SERVICE_QUALIFIED_ELEMENT_NAMES)) { + private final Interner + stringInterner = new HashSetInterner(ContainerUtil.concat(CLASS_NAME_LIST, IdeaPluginDescriptorImpl.SERVICE_QUALIFIED_ELEMENT_NAMES)) { @NotNull @Override public String intern(@NotNull String name) { diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java index 916916e85e51..1ab9e91aa36c 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/Identikit.java @@ -20,11 +20,15 @@ import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.psi.AbstractFileViewProvider; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakInterner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,8 +38,8 @@ import org.jetbrains.annotations.Nullable; */ public abstract class Identikit { private static final Logger LOG = Logger.getInstance(Identikit.class); - private static final WeakInterner ourPlainInterner = new WeakInterner<>(); - private static final WeakInterner ourAnchorInterner = new WeakInterner<>(); + private static final Interner ourPlainInterner = new WeakInterner<>(); + private static final Interner ourAnchorInterner = new WeakInterner<>(); @Nullable public abstract PsiElement findPsiElement(@NotNull PsiFile file, int startOffset, int endOffset); diff --git a/platform/diff-impl/tests/testSrc/com/intellij/diff/util/DiffPerformanceTest.kt b/platform/diff-impl/tests/testSrc/com/intellij/diff/util/DiffPerformanceTest.kt index 6784ff52170c..15f2a6886297 100644 --- a/platform/diff-impl/tests/testSrc/com/intellij/diff/util/DiffPerformanceTest.kt +++ b/platform/diff-impl/tests/testSrc/com/intellij/diff/util/DiffPerformanceTest.kt @@ -17,6 +17,7 @@ package com.intellij.diff.util import com.intellij.testFramework.PlatformTestUtil +import com.intellij.util.containers.Interner import com.intellij.util.containers.StringInterner import com.intellij.util.diff.Diff import com.intellij.util.diff.FilesTooBigForDiffException @@ -28,7 +29,7 @@ class DiffPerformanceTest : TestCase() { private var needWarmUp = true } - private val interner: StringInterner = StringInterner() + private val interner: Interner = StringInterner() val data = generateData(2000000) private val arr_200000 = data.take(200000).toTypedArray() diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/DeduplicateVisitorsSupplier.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/DeduplicateVisitorsSupplier.kt index 205a50ac6b69..b0ecf4e75a19 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/DeduplicateVisitorsSupplier.kt +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/DeduplicateVisitorsSupplier.kt @@ -7,13 +7,14 @@ import com.intellij.openapi.externalSystem.model.project.LibraryData import com.intellij.openapi.externalSystem.model.project.LibraryDependencyData import com.intellij.openapi.externalSystem.model.project.ModuleData import com.intellij.openapi.externalSystem.model.project.ModuleDependencyData +import com.intellij.util.containers.HashSetInterner import com.intellij.util.containers.Interner import java.util.function.Function class DeduplicateVisitorsSupplier { - private val myModuleData: Interner = Interner() - private val myLibraryData: Interner = Interner() + private val myModuleData: Interner = HashSetInterner() + private val myLibraryData: Interner = HashSetInterner() fun getVisitor(key: Key<*>): Function<*,*>? = when (key) { ProjectKeys.LIBRARY_DEPENDENCY -> Function { dep: LibraryDependencyData? -> visit(dep) } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index fa52ad5d013a..f9d3761764cf 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -40,6 +40,7 @@ import com.intellij.profile.codeInspection.ProjectInspectionProfileManager; import com.intellij.psi.*; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.SmartHashSet; import com.intellij.util.containers.WeakInterner; import com.intellij.util.ui.UIUtil; @@ -592,7 +593,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } - private static final WeakInterner tooltips = new WeakInterner<>(); + private static final Interner tooltips = new WeakInterner<>(); private static boolean showToolDescription(@NotNull LocalInspectionToolWrapper tool) { return tool.getStaticDescription() == null || !tool.getStaticDescription().isEmpty(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java index afb00282b4b5..215d52f400d9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionManagerSettings.java @@ -16,7 +16,7 @@ import com.intellij.openapi.extensions.ExtensionNotApplicableException; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.concurrency.SequentialTaskExecutor; -import com.intellij.util.containers.StringInterner; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakStringInterner; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -32,7 +32,7 @@ public final class IntentionManagerSettings implements PersistentStateComponent< private static final Logger LOG = Logger.getInstance(IntentionManagerSettings.class); private static final class MetaDataKey extends Pair { - private static final StringInterner ourInterner = new WeakStringInterner(); + private static final Interner ourInterner = new WeakStringInterner(); private MetaDataKey(@NotNull String[] categoryNames, @NotNull final String familyName) { super(StringUtil.join(categoryNames, ":"), ourInterner.intern(familyName)); } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java index bf143cad7593..a3a5366429f1 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/offlineViewer/OfflineViewParseUtil.java @@ -5,6 +5,7 @@ package com.intellij.codeInspection.offlineViewer; import com.intellij.codeInspection.InspectionApplication; import com.intellij.codeInspection.offline.OfflineProblemDescriptor; import com.intellij.codeInspection.reference.SmartRefElementPointerImpl; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import com.thoughtworks.xstream.io.xml.XppReader; import gnu.trove.THashSet; @@ -37,7 +38,7 @@ public class OfflineViewParseUtil { public static Map> parse(Reader problemReader) { TObjectIntHashMap fqName2IdxMap = new TObjectIntHashMap<>(); - StringInterner stringInterner = new StringInterner(); + Interner stringInterner = new StringInterner(); Map> package2Result = new HashMap<>(); XppReader reader = new XppReader(problemReader, new MXParser()); try { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java index 5a1c1f2da8c5..7934fe56a6c8 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeNode.java @@ -5,10 +5,9 @@ package com.intellij.codeInspection.ui; import com.intellij.codeHighlighting.HighlightDisplayLevel; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.lang.annotation.HighlightSeverity; -import com.intellij.openapi.util.AtomicClearableLazyValue; -import com.intellij.openapi.util.RecursionGuard; import com.intellij.util.containers.BidirectionalMap; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakInterner; import gnu.trove.TObjectHashingStrategy; import gnu.trove.TObjectIntHashMap; @@ -23,7 +22,7 @@ import java.util.*; * @author max */ public abstract class InspectionTreeNode implements TreeNode { - private static final WeakInterner LEVEL_AND_COUNT_INTERNER = new WeakInterner<>(new TObjectHashingStrategy() { + private static final Interner LEVEL_AND_COUNT_INTERNER = new WeakInterner<>(new TObjectHashingStrategy() { @Override public int computeHashCode(LevelAndCount[] object) { return Arrays.hashCode(object); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewSuppressActionHolder.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewSuppressActionHolder.java index e5fa0cd41a2f..9c5c0abbf9b3 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewSuppressActionHolder.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionViewSuppressActionHolder.java @@ -27,6 +27,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiLanguageInjectionHost; import com.intellij.util.containers.FactoryMap; +import com.intellij.util.containers.HashSetInterner; import com.intellij.util.containers.Interner; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; @@ -42,7 +43,7 @@ import java.util.stream.Stream; public class InspectionViewSuppressActionHolder { private final Map> mySuppressActions = FactoryMap.create(__ -> new THashMap<>()); - private final Interner> myActionSetInterner = new Interner<>(); + private final Interner> myActionSetInterner = new HashSetInterner<>(); @NotNull public synchronized SuppressIntentionAction[] getSuppressActions(@NotNull InspectionToolWrapper wrapper, @NotNull PsiElement context) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java index 2713dc056239..ea8d8c2154f9 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemDescriptionNode.java @@ -18,6 +18,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.psi.PsiElement; import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakStringInterner; import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; @@ -159,7 +160,7 @@ public class ProblemDescriptionNode extends SuppressableInspectionTreeNode { return descriptor != null && getPresentation().isExcluded(descriptor); } - private static final WeakStringInterner NAME_INTERNER = new WeakStringInterner(); + private static final Interner NAME_INTERNER = new WeakStringInterner(); @NotNull @Override diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/SuppressableInspectionTreeNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/SuppressableInspectionTreeNode.java index 74de18b5ddb9..71a121890b17 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/SuppressableInspectionTreeNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/SuppressableInspectionTreeNode.java @@ -5,15 +5,14 @@ package com.intellij.codeInspection.ui; import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.SuppressIntentionAction; -import com.intellij.codeInspection.offlineViewer.OfflineProblemDescriptorNode; import com.intellij.codeInspection.reference.RefEntity; import com.intellij.concurrency.ConcurrentCollectionFactory; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSetInterner; import com.intellij.util.containers.Interner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -181,7 +180,7 @@ public abstract class SuppressableInspectionTreeNode extends InspectionTreeNode } private static class NodeState { - private static final Interner INTERNER = new Interner<>(); + private static final Interner INTERNER = new HashSetInterner<>(); private final boolean isValid; private final boolean isSuppressed; private final boolean isFixApplied; diff --git a/platform/platform-impl/src/com/intellij/patterns/compiler/PatternCompilerImpl.java b/platform/platform-impl/src/com/intellij/patterns/compiler/PatternCompilerImpl.java index 59626655403c..6b115dab2468 100644 --- a/platform/platform-impl/src/com/intellij/patterns/compiler/PatternCompilerImpl.java +++ b/platform/platform-impl/src/com/intellij/patterns/compiler/PatternCompilerImpl.java @@ -30,6 +30,7 @@ import com.intellij.util.Function; import com.intellij.util.ProcessingContext; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.Stack; import com.intellij.util.containers.StringInterner; import gnu.trove.THashMap; @@ -48,7 +49,7 @@ public class PatternCompilerImpl implements PatternCompiler { private static final Logger LOG = Logger.getInstance(PatternCompilerImpl.class.getName()); private final Set myStaticMethods; - private final StringInterner myStringInterner = new StringInterner(); + private final Interner myStringInterner = new StringInterner(); public PatternCompilerImpl(final List patternClasses) { myStaticMethods = getStaticMethods(patternClasses); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java index 2a2a9b512e8c..91e096b19e3a 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java @@ -36,6 +36,7 @@ import com.intellij.util.ObjectUtils; import com.intellij.util.SmartList; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import com.intellij.util.graph.*; import com.intellij.util.messages.MessageBus; @@ -128,7 +129,7 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Disposa } private static class ModuleGroupInterner { - private final StringInterner groups = new StringInterner(); + private final Interner groups = new StringInterner(); private final Map paths = new THashMap<>(new TObjectHashingStrategy() { @Override public int computeHashCode(String[] object) { diff --git a/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java b/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java index 169222651e4c..6895c226e7ad 100644 --- a/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java +++ b/platform/util/src/com/intellij/openapi/util/objectTree/ThrowableInterner.java @@ -7,6 +7,7 @@ import com.intellij.util.ReflectionUtil; import com.intellij.util.concurrency.AtomicFieldUpdater; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.FilteringIterator; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakInterner; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; @@ -26,7 +27,7 @@ import java.util.Arrays; * 1) too slow and 2) explodes Throwable retained size by polluting Throwable.stackTrace fields. */ public class ThrowableInterner { - private static final WeakInterner myTraceInterner = new WeakInterner<>(new TObjectHashingStrategy() { + private static final Interner myTraceInterner = new WeakInterner<>(new TObjectHashingStrategy() { @Override public int computeHashCode(Throwable throwable) { String message = throwable.getMessage(); diff --git a/platform/util/src/com/intellij/util/containers/HashSetInterner.java b/platform/util/src/com/intellij/util/containers/HashSetInterner.java new file mode 100644 index 000000000000..b222ca98a242 --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/HashSetInterner.java @@ -0,0 +1,58 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.util.containers; + +import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Set; + +/** + * Allow to reuse structurally equal objects to avoid memory being wasted on them. Note: objects are cached inside + * and on hard references, so even the ones that are not used anymore will be still present in the memory. + * + * @see WeakInterner + * @author peter + */ + +public class HashSetInterner extends Interner { + private final OpenTHashSet mySet; + + public HashSetInterner() { + mySet = new OpenTHashSet<>(); + } + + public HashSetInterner(@NotNull Collection initialItems) { + mySet = new OpenTHashSet<>(initialItems); + } + + public HashSetInterner(@NotNull TObjectHashingStrategy strategy) { + mySet = new OpenTHashSet<>(strategy); + } + + @Override + @NotNull + public T intern(@NotNull T name) { + T interned = mySet.get(name); + if (interned != null) { + return interned; + } + + boolean added = mySet.add(name); + assert added; + + return name; + } + + @Override + public void clear() { + mySet.clear(); + } + + @Override + @NotNull + public Set getValues() { + return mySet; + } + +} diff --git a/platform/util/src/com/intellij/util/containers/Interner.java b/platform/util/src/com/intellij/util/containers/Interner.java index e6a75940e216..c1ca1c6bfecc 100644 --- a/platform/util/src/com/intellij/util/containers/Interner.java +++ b/platform/util/src/com/intellij/util/containers/Interner.java @@ -1,55 +1,20 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.containers; -import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; -import java.util.Collection; import java.util.Set; -/** - * Allow to reuse structurally equal objects to avoid memory being wasted on them. Note: objects are cached inside - * and on hard references, so even the ones that are not used anymore will be still present in the memory. - * - * @see WeakInterner - * @author peter - */ - -public class Interner { - private final OpenTHashSet mySet; - - public Interner() { - mySet = new OpenTHashSet<>(); - } - - public Interner(@NotNull Collection initialItems) { - mySet = new OpenTHashSet<>(initialItems); - } - - public Interner(@NotNull TObjectHashingStrategy strategy) { - mySet = new OpenTHashSet<>(strategy); - } - +public abstract class Interner { @NotNull - public T intern(@NotNull T name) { - T interned = mySet.get(name); - if (interned != null) { - return interned; - } - - boolean added = mySet.add(name); - assert added; - - return name; + public T intern(@NotNull T name){ + throw new AbstractMethodError(); } - public void clear() { - mySet.clear(); - } + public abstract void clear(); @NotNull public Set getValues() { - return mySet; + throw new AbstractMethodError(); } - } diff --git a/platform/util/src/com/intellij/util/containers/StringInterner.java b/platform/util/src/com/intellij/util/containers/StringInterner.java index 8b417922980c..c40d66771009 100644 --- a/platform/util/src/com/intellij/util/containers/StringInterner.java +++ b/platform/util/src/com/intellij/util/containers/StringInterner.java @@ -18,6 +18,6 @@ package com.intellij.util.containers; /** * @author max */ -public class StringInterner extends Interner { +public class StringInterner extends HashSetInterner { } diff --git a/platform/util/src/com/intellij/util/containers/WeakInterner.java b/platform/util/src/com/intellij/util/containers/WeakInterner.java index 25441f9548e5..3eadd3573da4 100644 --- a/platform/util/src/com/intellij/util/containers/WeakInterner.java +++ b/platform/util/src/com/intellij/util/containers/WeakInterner.java @@ -15,7 +15,7 @@ import java.util.concurrent.ConcurrentMap; * * @author peter */ -public class WeakInterner { +public class WeakInterner extends Interner { private final ConcurrentMap myMap; public WeakInterner() { @@ -25,15 +25,18 @@ public class WeakInterner { myMap = ContainerUtil.createConcurrentWeakKeyWeakValueMap(strategy); } + @Override @NotNull public T intern(@NotNull T name) { return ConcurrencyUtil.cacheOrGet(myMap, name, name); } + @Override public void clear() { myMap.clear(); } + @Override @NotNull public Set getValues() { return new THashSet<>(myMap.values()); diff --git a/platform/util/src/org/jdom/JDOMInterner.java b/platform/util/src/org/jdom/JDOMInterner.java index 3d8d1a41a6b9..d343c365c0fc 100644 --- a/platform/util/src/org/jdom/JDOMInterner.java +++ b/platform/util/src/org/jdom/JDOMInterner.java @@ -5,6 +5,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.OpenTHashSet; import com.intellij.util.containers.StringInterner; import gnu.trove.TObjectHashingStrategy; @@ -16,7 +17,7 @@ import static com.intellij.openapi.util.JDOMUtil.getAttributes; public class JDOMInterner { private static final Condition IS_ELEMENT = Conditions.instanceOf(Element.class); - private final StringInterner myStrings = new StringInterner(); + private final Interner myStrings = new StringInterner(); private final OpenTHashSet myElements = new OpenTHashSet<>(new TObjectHashingStrategy() { @Override public int computeHashCode(Element e) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.kt b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.kt index bf933010b05d..89755b9ee448 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.kt +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.kt @@ -7,6 +7,7 @@ import com.intellij.openapi.application.PathManager import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.project.Project +import com.intellij.util.containers.HashSetInterner import com.intellij.util.containers.Interner import com.intellij.util.io.* import com.intellij.vcs.log.VcsUser @@ -30,7 +31,7 @@ class VcsUserRegistryImpl internal constructor(project: Project) : Disposable, V init { initEnumerator() - interner = Interner() + interner = HashSetInterner() } private fun initEnumerator(): Boolean { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java index 9398f8c64bbc..b5cbda8a8585 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsRefImpl.java @@ -1,6 +1,7 @@ package com.intellij.vcs.log.impl; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakStringInterner; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.VcsRef; @@ -11,7 +12,7 @@ import org.jetbrains.annotations.NotNull; * @author erokhins */ public final class VcsRefImpl implements VcsRef { - private static final WeakStringInterner ourNames = new WeakStringInterner(); + private static final Interner ourNames = new WeakStringInterner(); @NotNull private final Hash myCommitHash; @NotNull private final String myName; @NotNull private final VcsRefType myType; diff --git a/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java b/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java index 70dcd3596d97..33be61b84c76 100644 --- a/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java +++ b/plugins/git4idea/src/git4idea/annotate/GitAnnotationProvider.java @@ -20,6 +20,7 @@ import com.intellij.openapi.vcs.vfs.VcsFileSystem; import com.intellij.openapi.vcs.vfs.VcsVirtualFile; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.HashSetInterner; import com.intellij.util.containers.Interner; import com.intellij.vcs.AnnotationProviderEx; import com.intellij.vcs.log.VcsUser; @@ -261,7 +262,7 @@ public class GitAnnotationProvider implements AnnotationProviderEx { @NotNull VirtualFile file, @NotNull VirtualFile root, @NotNull String output) throws VcsException { - Interner pathInterner = new Interner<>(); + Interner pathInterner = new HashSetInterner<>(); try { List lines = new ArrayList<>(); diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/GeneratedStructureModel.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/GeneratedStructureModel.java index 78d4ab22ff76..b26bd99c227c 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/GeneratedStructureModel.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/ui/GeneratedStructureModel.java @@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; import com.intellij.reference.SoftReference; import com.intellij.util.SmartList; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import org.intellij.plugins.xsltDebugger.XsltDebuggerSession; import org.intellij.plugins.xsltDebugger.rt.engine.OutputEventQueue; @@ -43,18 +44,18 @@ public class GeneratedStructureModel extends DefaultTreeModel { @NonNls private static final String PENDING = "..."; - private static WeakReference ourSharedInterner; + private static WeakReference> ourSharedInterner; private final LinkedList myCurrentPath = new LinkedList<>(); private final List myLastNodes = new LinkedList<>(); - private final StringInterner myInterner = getInterner(); + private final Interner myInterner = getInterner(); // we keep a shared string interner across all currently running xslt debugger instances. it should go away once // all instances (and their toolwindow contents) are gone. This should minimize the memory usage of the generated // structure tree. - private static StringInterner getInterner() { - StringInterner interner = SoftReference.dereference(ourSharedInterner); + private static Interner getInterner() { + Interner interner = SoftReference.dereference(ourSharedInterner); if (interner == null) { interner = new StringInterner(); ourSharedInterner = new WeakReference<>(interner); diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java index 80a7901cdf59..f60ceacfc431 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DynamicGenericInfo.java @@ -9,6 +9,7 @@ import com.intellij.reference.SoftReference; import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.Interner; import com.intellij.util.containers.WeakInterner; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.GenericDomValue; @@ -27,7 +28,7 @@ import java.util.Set; * @author peter */ public class DynamicGenericInfo extends DomGenericInfoEx { - private static final Key>> HOLDERS_CACHE = Key.create("DOM_CHILDREN_HOLDERS_CACHE"); + private static final Key>> HOLDERS_CACHE = Key.create("DOM_CHILDREN_HOLDERS_CACHE"); private final StaticGenericInfo myStaticGenericInfo; @NotNull private final DomInvocationHandler myInvocationHandler; private volatile boolean myInitialized; @@ -106,8 +107,8 @@ public class DynamicGenericInfo extends DomGenericInfoEx { } private static ChildrenDescriptionsHolder internChildrenHolder(XmlFile file, ChildrenDescriptionsHolder holder) { - SoftReference> ref = file.getUserData(HOLDERS_CACHE); - WeakInterner cache = SoftReference.dereference(ref); + SoftReference> ref = file.getUserData(HOLDERS_CACHE); + Interner cache = SoftReference.dereference(ref); if (cache == null) { cache = new WeakInterner<>(); file.putUserData(HOLDERS_CACHE, new SoftReference<>(cache));