mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
save some completion memory by replacing weak maps with user data
This commit is contained in:
+8
-5
@@ -25,10 +25,7 @@ import com.intellij.codeInsight.template.impl.LiveTemplateLookupElement;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.patterns.StandardPatterns;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
@@ -66,6 +63,7 @@ public class CompletionLookupArranger extends LookupArranger {
|
||||
private final CompletionProgressIndicator myProcess;
|
||||
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
|
||||
private final Map<CompletionSorterImpl, Classifier<LookupElement>> myClassifiers = new LinkedHashMap<>();
|
||||
private final Key<CompletionSorterImpl> mySorterKey = Key.create("SORTER_KEY");
|
||||
private final CompletionFinalSorter myFinalSorter = CompletionFinalSorter.newSorter();
|
||||
private int myPrefixChanges;
|
||||
|
||||
@@ -89,7 +87,8 @@ public class CompletionLookupArranger extends LookupArranger {
|
||||
|
||||
@NotNull
|
||||
private CompletionSorterImpl obtainSorter(LookupElement element) {
|
||||
return myProcess.getSorter(element);
|
||||
//noinspection ConstantConditions
|
||||
return element.getUserData(mySorterKey);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -132,6 +131,10 @@ public class CompletionLookupArranger extends LookupArranger {
|
||||
return result;
|
||||
}
|
||||
|
||||
void associateSorter(LookupElement element, CompletionSorterImpl sorter) {
|
||||
element.putUserData(mySorterKey, sorter);
|
||||
}
|
||||
|
||||
private static boolean haveSameWeights(List<Pair<LookupElement, Object>> pairs) {
|
||||
if (pairs.isEmpty()) return true;
|
||||
|
||||
|
||||
+4
-10
@@ -82,7 +82,6 @@ import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -97,6 +96,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
private final Caret myCaret;
|
||||
private final CompletionParameters myParameters;
|
||||
private final CodeCompletionHandlerBase myHandler;
|
||||
private final CompletionLookupArranger myArranger;
|
||||
private OffsetsInFile myHostOffsets;
|
||||
private final LookupImpl myLookup;
|
||||
private final MergingUpdateQueue myQueue;
|
||||
@@ -128,8 +128,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
private volatile int myCount;
|
||||
private volatile boolean myHasPsiElements;
|
||||
private boolean myLookupUpdated;
|
||||
private final ConcurrentMap<LookupElement, CompletionSorterImpl> myItemSorters =
|
||||
ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy());
|
||||
private final PropertyChangeListener myLookupManagerListener;
|
||||
private final Queue<Runnable> myAdvertiserChanges = new ConcurrentLinkedQueue<>();
|
||||
private final List<CompletionResult> myDelayedMiddleMatches = ContainerUtil.newArrayList();
|
||||
@@ -155,7 +153,8 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
|
||||
myAdvertiserChanges.offer(() -> myLookup.getAdvertiser().clearAdvertisements());
|
||||
|
||||
myLookup.setArranger(new CompletionLookupArranger(parameters, this));
|
||||
myArranger = new CompletionLookupArranger(parameters, this);
|
||||
myLookup.setArranger(myArranger);
|
||||
|
||||
myLookup.addLookupListener(myLookupListener);
|
||||
myLookup.setCalculating(true);
|
||||
@@ -291,11 +290,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
CompletionSorterImpl getSorter(LookupElement element) {
|
||||
return myItemSorters.get(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
@@ -451,7 +445,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
addDelayedMiddleMatches();
|
||||
}
|
||||
|
||||
myItemSorters.put(lookupElement, (CompletionSorterImpl)item.getSorter());
|
||||
myArranger.associateSorter(lookupElement, (CompletionSorterImpl)item.getSorter());
|
||||
if (item.isStartMatch() || allowMiddleMatches) {
|
||||
addItemToLookup(item);
|
||||
} else {
|
||||
|
||||
@@ -19,10 +19,9 @@ package com.intellij.codeInsight.lookup;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.EqualityPolicy;
|
||||
import com.intellij.util.containers.hash.LinkedHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -36,7 +35,7 @@ public abstract class LookupArranger implements WeighingContext {
|
||||
private final List<LookupElement> myMatchingItems = new ArrayList<>();
|
||||
private final List<LookupElement> myExactPrefixItems = new ArrayList<>();
|
||||
private final List<LookupElement> myInexactPrefixItems = new ArrayList<>();
|
||||
private final Map<LookupElement, PrefixMatcher> myMatchers = ContainerUtil.createConcurrentWeakMap(ContainerUtil.identityStrategy());
|
||||
private final Key<PrefixMatcher> myMatcherKey = Key.create("LookupArrangerMatcher");
|
||||
private String myAdditionalPrefix = "";
|
||||
|
||||
public void addElement(LookupElement item, LookupElementPresentation presentation) {
|
||||
@@ -58,7 +57,7 @@ public abstract class LookupArranger implements WeighingContext {
|
||||
}
|
||||
|
||||
public void registerMatcher(@NotNull LookupElement item, @NotNull PrefixMatcher matcher) {
|
||||
myMatchers.put(item, matcher);
|
||||
item.putUserData(myMatcherKey, matcher);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -70,7 +69,7 @@ public abstract class LookupArranger implements WeighingContext {
|
||||
|
||||
@NotNull
|
||||
public PrefixMatcher itemMatcher(@NotNull LookupElement item) {
|
||||
PrefixMatcher matcher = myMatchers.get(item);
|
||||
PrefixMatcher matcher = item.getUserData(myMatcherKey);
|
||||
if (matcher == null) {
|
||||
throw new AssertionError("Item not in lookup: item=" + item + "; lookup items=" + myItems);
|
||||
}
|
||||
@@ -89,20 +88,17 @@ public abstract class LookupArranger implements WeighingContext {
|
||||
}
|
||||
|
||||
public final void prefixReplaced(Lookup lookup, String newPrefix) {
|
||||
//noinspection unchecked
|
||||
Map<LookupElement, PrefixMatcher> newMatchers = new LinkedHashMap(EqualityPolicy.IDENTITY);
|
||||
for (LookupElement item : myItems) {
|
||||
ArrayList<LookupElement> itemCopy = ContainerUtil.newArrayList(myItems);
|
||||
myItems.clear();
|
||||
for (LookupElement item : itemCopy) {
|
||||
if (item.isValid()) {
|
||||
PrefixMatcher matcher = itemMatcher(item).cloneWithPrefix(newPrefix);
|
||||
if (matcher.prefixMatches(item)) {
|
||||
newMatchers.put(item, matcher);
|
||||
item.putUserData(myMatcherKey, matcher);
|
||||
myItems.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
myMatchers.clear();
|
||||
myMatchers.putAll(newMatchers);
|
||||
myItems.clear();
|
||||
myItems.addAll(newMatchers.keySet());
|
||||
|
||||
prefixChanged(lookup);
|
||||
}
|
||||
|
||||
@@ -42,10 +42,7 @@ import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
@@ -79,6 +76,7 @@ import java.util.Map;
|
||||
|
||||
public class LookupImpl extends LightweightHint implements LookupEx, Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.lookup.impl.LookupImpl");
|
||||
private static final Key<Font> CUSTOM_FONT_KEY = Key.create("CustomLookupElementFont");
|
||||
|
||||
private final LookupOffsets myOffsets;
|
||||
private final Project myProject;
|
||||
@@ -123,8 +121,6 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
private boolean myChangeGuard;
|
||||
private volatile LookupArranger myArranger;
|
||||
private LookupArranger myPresentableArranger;
|
||||
private final Map<LookupElement, Font> myCustomFonts = ContainerUtil.createConcurrentWeakMap(10, 0.75f, Runtime.getRuntime().availableProcessors(),
|
||||
ContainerUtil.identityStrategy());
|
||||
private boolean myStartCompletionWhenNothingMatches;
|
||||
boolean myResizePending;
|
||||
private boolean myFinishing;
|
||||
@@ -273,15 +269,15 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
|
||||
private void updateLookupWidth(LookupElement item, LookupElementPresentation presentation) {
|
||||
final Font customFont = myCellRenderer.getFontAbleToDisplay(presentation);
|
||||
if (customFont != null) {
|
||||
myCustomFonts.put(item, customFont);
|
||||
item.putUserData(CUSTOM_FONT_KEY, customFont);
|
||||
}
|
||||
int maxWidth = myCellRenderer.updateMaximumWidth(presentation, item);
|
||||
myLookupTextWidth = Math.max(maxWidth, myLookupTextWidth);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Font getCustomFont(LookupElement item, boolean bold) {
|
||||
Font font = myCustomFonts.get(item);
|
||||
Font getCustomFont(LookupElement item, boolean bold) {
|
||||
Font font = item.getUserData(CUSTOM_FONT_KEY);
|
||||
return font == null ? null : bold ? font.deriveFont(Font.BOLD) : font;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user