mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cache text occurrences to speedup inspections, e.g. JSUnusedGlobalSymbolsInspection in HighlightingTrendPerformanceTest.testJsInspectionQuadraticOnMemberNumber
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,12 +32,17 @@ import com.intellij.psi.impl.source.tree.LeafElement;
|
||||
import com.intellij.psi.impl.source.tree.TreeElement;
|
||||
import com.intellij.psi.search.TextOccurenceProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ConcurrencyUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.text.StringSearcher;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class LowLevelSearchUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.LowLevelSearchUtil");
|
||||
@@ -224,6 +229,7 @@ public class LowLevelSearchUtil {
|
||||
LOG.error(msg);
|
||||
}
|
||||
|
||||
private static final ConcurrentMap<CharSequence, Map<StringSearcher, int[]>> cache = ContainerUtil.createConcurrentWeakMap();
|
||||
public static boolean processTextOccurrences(@NotNull CharSequence text,
|
||||
int startOffset,
|
||||
int endOffset,
|
||||
@@ -231,15 +237,31 @@ public class LowLevelSearchUtil {
|
||||
@Nullable ProgressIndicator progress,
|
||||
@NotNull TIntProcedure processor) {
|
||||
if (endOffset > text.length()) {
|
||||
throw new AssertionError("end>length");
|
||||
throw new IllegalArgumentException("end: " + endOffset + " > length: "+text.length());
|
||||
}
|
||||
for (int index = startOffset; index < endOffset; index++) {
|
||||
if (progress != null) progress.checkCanceled();
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
index = searcher.scan(text, index, endOffset);
|
||||
if (index < 0) break;
|
||||
if (checkJavaIdentifier(text, startOffset, endOffset, searcher, index)) {
|
||||
if (!processor.execute(index)) return false;
|
||||
Map<StringSearcher, int[]> cachedMap = cache.get(text);
|
||||
int[] cachedOccurrences = cachedMap == null ? null : cachedMap.get(searcher);
|
||||
if (cachedOccurrences == null) {
|
||||
TIntArrayList occurrences = new TIntArrayList();
|
||||
for (int index = 0; index < text.length(); index++) {
|
||||
if (progress != null) progress.checkCanceled();
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
index = searcher.scan(text, index, text.length());
|
||||
if (index < 0) break;
|
||||
if (checkJavaIdentifier(text, 0, text.length(), searcher, index)) {
|
||||
occurrences.add(index);
|
||||
}
|
||||
}
|
||||
cachedOccurrences = occurrences.toNativeArray();
|
||||
if (cachedMap == null) {
|
||||
cachedMap = ConcurrencyUtil.cacheOrGet(cache, text, ContainerUtil.createConcurrentSoftMap());
|
||||
}
|
||||
cachedMap.put(searcher, cachedOccurrences);
|
||||
}
|
||||
for (int index : cachedOccurrences) {
|
||||
if (index >= endOffset) break;
|
||||
if (index >= startOffset && !processor.execute(index)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user