IDEA-124956 PsiShortNameCacheImpl.getClassesByName() is O(N^2)

This commit is contained in:
Maxim.Mossienko
2014-05-13 14:25:29 +02:00
parent 5b4eafc564
commit a0a681ea04
@@ -33,16 +33,14 @@ import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.HashSet;
import com.intellij.util.indexing.IdFilter;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.*;
public class PsiShortNamesCacheImpl extends PsiShortNamesCache {
private final PsiManagerEx myManager;
@@ -70,33 +68,46 @@ public class PsiShortNamesCacheImpl extends PsiShortNamesCache {
if (classes.isEmpty()) return PsiClass.EMPTY_ARRAY;
ArrayList<PsiClass> list = new ArrayList<PsiClass>(classes.size());
Map<String, List<PsiClass>> uniqueQName2Classes = new THashMap<String, List<PsiClass>>(classes.size());
List<PsiClass> hiddenClasses = null;
OuterLoop:
for (PsiClass aClass : classes) {
VirtualFile vFile = aClass.getContainingFile().getVirtualFile();
if (!scope.contains(vFile)) continue;
for (int j = 0; j < list.size(); j++) {
PsiClass aClass1 = list.get(j);
String qName = aClass.getQualifiedName();
if (qName != null) {
List<PsiClass> previousQNamedClasses = uniqueQName2Classes.get(qName);
List<PsiClass> qNamedClasses;
String qName = aClass.getQualifiedName();
String qName1 = aClass1.getQualifiedName();
if (qName != null && qName1 != null && qName.equals(qName1)) {
VirtualFile vFile1 = aClass1.getContainingFile().getVirtualFile();
int res = scope.compare(vFile1, vFile);
if (res > 0) {
continue OuterLoop; // aClass1 hides aClass
}
else if (res < 0) {
list.remove(j);
//noinspection AssignmentToForLoopParameter
j--; // aClass hides aClass1
if (previousQNamedClasses != null) {
qNamedClasses = new SmartList<PsiClass>();
for(PsiClass previousClass:previousQNamedClasses) {
VirtualFile previousClassVFile = previousClass.getContainingFile().getVirtualFile();
int res = scope.compare(previousClassVFile, vFile);
if (res > 0) {
continue OuterLoop; // previousClass hides aClass
}
else if (res < 0) {
// aClass hides previousClass
if (hiddenClasses == null) hiddenClasses = new SmartList<PsiClass>();
hiddenClasses.add(previousClass);
qNamedClasses.add(aClass);
} else {
qNamedClasses.add(aClass);
}
}
} else {
qNamedClasses = new SmartList<PsiClass>(aClass);
}
uniqueQName2Classes.put(qName, qNamedClasses);
}
list.add(aClass);
}
if (hiddenClasses != null) list.removeAll(hiddenClasses);
return list.toArray(new PsiClass[list.size()]);
}