faster duplicates index, fix for IDEA-124624

This commit is contained in:
Maxim.Mossienko
2015-07-21 00:36:11 +02:00
parent 673edc94a6
commit 9284a926d4
2 changed files with 35 additions and 9 deletions
@@ -54,7 +54,8 @@ import java.util.Map;
public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayList> implements PsiDependentIndex {
static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.duplicates.online.calculation",
isEnabledByDefault());
static boolean ourEnabledLightProfiles = true;
static final boolean ourEnabledLightProfiles = true;
private static boolean ourEnabledOldProfiles = false;
private static boolean isEnabledByDefault() {
Application application = ApplicationManager.getApplication();
@@ -62,12 +63,15 @@ public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayL
}
@NonNls public static final ID<Integer, TIntArrayList> NAME = ID.create("DuplicatesIndex");
private static final int myBaseVersion = 15;
private static final int myBaseVersion = 16;
private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() {
@Override
public boolean acceptInput(@NotNull final VirtualFile file) {
return ourEnabled && findDuplicatesProfile(file.getFileType()) != null;
return ourEnabled &&
findDuplicatesProfile(file.getFileType()) != null &&
file.isInLocalFileSystem() // skip library sources
;
}
};
@@ -151,12 +155,14 @@ public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayL
if (!(fileType instanceof LanguageFileType)) return null;
Language language = ((LanguageFileType)fileType).getLanguage();
DuplicatesProfile profile = DuplicatesProfile.findProfileForLanguage(language);
return profile != null && (profile.supportDuplicatesIndex() || profile instanceof LightDuplicateProfile) ? profile : null;
return profile != null &&
(ourEnabledOldProfiles && profile.supportDuplicatesIndex() ||
profile instanceof LightDuplicateProfile) ? profile : null;
}
@Override
public int getVersion() {
return myBaseVersion + (ourEnabled ? 0xFF : 0) + (ourEnabledLightProfiles ? 0x7F : 0);
return myBaseVersion + (ourEnabled ? 0xFF : 0) + (ourEnabledLightProfiles ? 0x7F : 0) + (ourEnabledOldProfiles ? 0x21 : 0);
}
@Override
@@ -237,6 +243,13 @@ public class DuplicatesIndex extends FileBasedIndexExtension<Integer, TIntArrayL
return old;
}
@TestOnly
public static boolean setEnabledOldProfiles(boolean value) {
boolean old = ourEnabledOldProfiles;
ourEnabledOldProfiles = value;
return old;
}
@Override
public boolean hasSnapshotMapping() {
return true;
@@ -48,8 +48,10 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
final Ref<DuplicatedCodeProcessor> myProcessorRef = new Ref<DuplicatedCodeProcessor>();
final FileASTNode node = psiFile.getNode();
if (profile instanceof LightDuplicateProfile && node.getElementType() instanceof ILightStubFileElementType &&
DuplicatesIndex.ourEnabledLightProfiles) {
boolean usingLightProfile = profile instanceof LightDuplicateProfile &&
node.getElementType() instanceof ILightStubFileElementType &&
DuplicatesIndex.ourEnabledLightProfiles;
if (usingLightProfile) {
LighterAST ast = node.getLighterAST();
assert ast != null;
((LightDuplicateProfile)profile).process(ast, new LightDuplicateProfile.Callback() {
@@ -81,6 +83,11 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
protected int getEndOffset(LighterASTNode node) {
return node.getEndOffset();
}
@Override
protected boolean isLightProfile() {
return true;
}
}
if (myProcessor == null) {
myProcessor = new LightDuplicatedCodeProcessor(virtualFile, psiFile.getProject());
@@ -136,6 +143,11 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
protected int getEndOffset(PsiFragment node) {
return node.getEndOffset();
}
@Override
protected boolean isLightProfile() {
return false;
}
}
if (myProcessor == null) {
myProcessor = new OldDuplicatedCodeProcessor(virtualFile, psiFile.getProject());
@@ -154,7 +166,7 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
for(Map.Entry<Integer, TextRange> entry:processor.reportedRanges.entrySet()) {
final Integer offset = entry.getKey();
// todo 3 statements constant
if (processor.fragmentSize.get(offset) < MIN_FRAGMENT_SIZE) continue;
if (!usingLightProfile && processor.fragmentSize.get(offset) < MIN_FRAGMENT_SIZE) continue;
final VirtualFile file = processor.reportedFiles.get(offset);
String message = "Found duplicated code in " + file.getPath();
@@ -244,7 +256,7 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
reportedOffsetInOtherFiles.put(fragmentStartOffsetInteger, value);
reportedPsi.put(fragmentStartOffsetInteger, target);
fragmentSize.put(fragmentStartOffsetInteger, newFragmentSize);
if (newFragmentSize >= MIN_FRAGMENT_SIZE) fragmentHash.put(fragmentStartOffsetInteger, myHash);
if (newFragmentSize >= MIN_FRAGMENT_SIZE || isLightProfile()) fragmentHash.put(fragmentStartOffsetInteger, myHash);
return false;
}
return true;
@@ -255,5 +267,6 @@ public class DuplicatesInspectionBase extends LocalInspectionTool {
protected abstract int getStartOffset(T node);
protected abstract int getEndOffset(T node);
protected abstract boolean isLightProfile();
}
}