From 86c255def7e86781446977664634afcb303f0cf3 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 5 Jul 2012 21:07:43 +0200 Subject: [PATCH] do less things on EDT during completion --- .../completion/JavaCompletionSorting.java | 5 +- .../impl/LiftShorterItemsClassifier.java | 97 ++++++++++++++----- 2 files changed, 73 insertions(+), 29 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java index 68d0d1a47424..821964c1d88e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java @@ -34,7 +34,6 @@ import com.intellij.psi.util.PropertyUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; @@ -88,8 +87,8 @@ public class JavaCompletionSorting { public Classifier createClassifier(Classifier next) { return new LiftShorterItemsClassifier(next, new LiftShorterItemsClassifier.LiftingCondition() { @Override - public boolean shouldLift(LookupElement shorterElement, LookupElement longerElement, ProcessingContext context) { - if (super.shouldLift(shorterElement, longerElement, context)) { + public boolean shouldLift(LookupElement shorterElement, LookupElement longerElement) { + if (super.shouldLift(shorterElement, longerElement)) { return true; } Object object = shorterElement.getObject(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java index 65649e6b82e6..7da9e8db5386 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/LiftShorterItemsClassifier.java @@ -22,8 +22,10 @@ import com.intellij.util.ProcessingContext; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import gnu.trove.THashMap; import gnu.trove.THashSet; import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -31,22 +33,24 @@ import java.util.*; * @author peter */ public class LiftShorterItemsClassifier extends Classifier { - private final TreeSet mySortedStrings; - private final MultiMap myElements; - private final MultiMap myPrefixes; + private final TreeSet mySortedStrings = new TreeSet(); + private final MultiMap myElements = new MultiMap(); + private final Map> myToLiftForSorting = new THashMap>(TObjectHashingStrategy.IDENTITY); + private final Map> myToLiftForPreselection = new THashMap>(TObjectHashingStrategy.IDENTITY); + private final MultiMap myPrefixes = new MultiMap(); private final Classifier myNext; private final LiftingCondition myCondition; public LiftShorterItemsClassifier(Classifier next, LiftingCondition condition) { myNext = next; myCondition = condition; - mySortedStrings = new TreeSet(); - myElements = new MultiMap(); - myPrefixes = new MultiMap(); } @Override public void addElement(LookupElement element) { + final Set toUpdate = new THashSet(TObjectHashingStrategy.IDENTITY); + toUpdate.add(element); + final Set strings = getAllLookupStrings(element); for (String string : strings) { if (string.length() == 0) continue; @@ -59,6 +63,7 @@ public class LiftShorterItemsClassifier extends Classifier { break; } myPrefixes.putValue(s, string); + toUpdate.addAll(myElements.get(s)); } final char first = string.charAt(0); @@ -74,6 +79,39 @@ public class LiftShorterItemsClassifier extends Classifier { } } myNext.addElement(element); + + for (LookupElement lookupElement : toUpdate) { + recalculateToLift(lookupElement); + } + } + + private void recalculateToLift(LookupElement element) { + final Set forPreselection = new THashSet(TObjectHashingStrategy.IDENTITY); + final Set forSorting = new THashSet(TObjectHashingStrategy.IDENTITY); + final List prefixes = new SmartList(); + for (String string : getAllLookupStrings(element)) { + prefixes.addAll(myPrefixes.get(string)); + } + Collections.sort(prefixes); + for (String prefix : prefixes) { + for (LookupElement shorterElement : myElements.get(prefix)) { + if (myCondition.shouldLift(shorterElement, element)) { + forPreselection.add(shorterElement); + } else { + forSorting.add(shorterElement); + } + } + } + + myToLiftForPreselection.remove(element); + myToLiftForSorting.remove(element); + + if (!forPreselection.isEmpty()) { + myToLiftForPreselection.put(element, forPreselection); + } + if (!forSorting.isEmpty()) { + myToLiftForSorting.put(element, forSorting); + } } @Override @@ -86,29 +124,19 @@ public class LiftShorterItemsClassifier extends Classifier { ContainerUtil.addAll(srcSet, source); final Set processed = new THashSet(TObjectHashingStrategy.IDENTITY); + boolean forSorting = context.get(CompletionLookupArranger.PURE_RELEVANCE) != Boolean.TRUE; final List result = new ArrayList(); for (LookupElement element : myNext.classify(source, context)) { assert srcSet.contains(element) : myNext; if (processed.add(element)) { - final List prefixes = new SmartList(); - for (String string : getAllLookupStrings(element)) { - prefixes.addAll(myPrefixes.get(string)); + //System.out.println("element = " + element); + List shorter = addShorterElements(srcSet, processed, null, myToLiftForPreselection.get(element)); + if (forSorting) { + shorter = addShorterElements(srcSet, processed, shorter, myToLiftForSorting.get(element)); } - Collections.sort(prefixes); - for (String prefix : prefixes) { - List shorter = new SmartList(); - for (LookupElement shorterElement : myElements.get(prefix)) { - if (srcSet.contains(shorterElement) && - myCondition.shouldLift(shorterElement, element, context) && - processed.add(shorterElement)) { - shorter.add(shorterElement); - } - } - - if (!shorter.isEmpty()) { - lifted.addAll(shorter); - ContainerUtil.addAll(result, myNext.classify(shorter, context)); - } + if (shorter != null) { + lifted.addAll(shorter); + ContainerUtil.addAll(result, myNext.classify(shorter, context)); } result.add(element); } @@ -116,6 +144,23 @@ public class LiftShorterItemsClassifier extends Classifier { return result; } + @Nullable + private static List addShorterElements(Set srcSet, + Set processed, + @Nullable List toLift, + @Nullable Set from) { + if (from != null) { + for (LookupElement shorterElement : from) { + //System.out.println("shorterElement = " + shorterElement); + if (srcSet.contains(shorterElement) && processed.add(shorterElement)) { + if (toLift == null) toLift = new SmartList(); + toLift.add(shorterElement); + } + } + } + return toLift; + } + private static Set getAllLookupStrings(LookupElement element) { return element.getAllLookupStrings(); } @@ -138,8 +183,8 @@ public class LiftShorterItemsClassifier extends Classifier { } public static class LiftingCondition { - public boolean shouldLift(LookupElement shorterElement, LookupElement longerElement, ProcessingContext context) { - return context.get(CompletionLookupArranger.PURE_RELEVANCE) != Boolean.TRUE; + public boolean shouldLift(LookupElement shorterElement, LookupElement longerElement) { + return false; } } }