no 'too many ids' heuristic in isCheapEnoughToSearch, as this depends largely on the number of files ever touched by VFS in any project

This commit is contained in:
peter
2012-01-20 17:02:01 +01:00
parent 74726edfb5
commit 0c8d0cb9b0
4 changed files with 29 additions and 58 deletions
@@ -23,7 +23,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.IndexPattern;
import com.intellij.psi.search.IndexPatternProvider;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
@@ -41,12 +40,6 @@ public interface CacheManager {
boolean processFilesWithWord(@NotNull Processor<PsiFile> processor,@NotNull String word, short occurenceMask, @NotNull GlobalSearchScope scope, final boolean caseSensitively);
// IMPORTANT!!!
// Do not call indices directly or indirectly from 'process' method, deadlocks are possible (IDEADEV-42137).
public boolean collectVirtualFilesWithWord(@NotNull final CommonProcessors.CollectProcessor<VirtualFile> fileProcessor,
@NotNull final String word, final short occurrenceMask,
@NotNull final GlobalSearchScope scope, final boolean caseSensitively);
/**
* @return all VirtualFile's that contain todo-items under project roots
*/
@@ -80,8 +80,7 @@ public class IndexCacheManagerImpl implements CacheManager{
// Since implementation of virtualFileProcessor.process() may call indices directly or indirectly,
// we cannot call it inside FileBasedIndex.processValues() method except in collecting form
// If we do, deadlocks are possible (IDEADEV-42137). Process the files without not holding indices' read lock.
@Override
public boolean collectVirtualFilesWithWord(@NotNull final CommonProcessors.CollectProcessor<VirtualFile> fileProcessor,
private boolean collectVirtualFilesWithWord(@NotNull final Processor<VirtualFile> fileProcessor,
@NotNull final String word, final short occurrenceMask,
@NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
if (myProject.isDefault()) {
@@ -48,7 +48,6 @@ import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.text.StringSearcher;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -369,22 +368,16 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
final ArrayList<IdIndexEntry> entries = getWordEntries(text, caseSensitively);
if (entries.isEmpty()) return true;
final Collection<VirtualFile> fileSet = ApplicationManager.getApplication().runReadAction(new Computable<Collection<VirtualFile>>() {
final CommonProcessors.CollectProcessor<VirtualFile> collectProcessor = new CommonProcessors.CollectProcessor<VirtualFile>();
processFilesContainingAllKeys(scope, new Condition<Integer>() {
@Override
public Collection<VirtualFile> compute() {
final CommonProcessors.CollectProcessor<VirtualFile> collectProcessor = new CommonProcessors.CollectProcessor<VirtualFile>();
FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, entries, scope, new Condition<Integer>() {
@Override
public boolean value(Integer integer) {
return (integer.intValue() & searchContext) != 0;
}
}, collectProcessor);
return collectProcessor.getResults();
public boolean value(Integer integer) {
return (integer.intValue() & searchContext) != 0;
}
});
}, collectProcessor, getWordEntries(text, caseSensitively));
final FileIndexFacade index = FileIndexFacade.getInstance(myManager.getProject());
return ContainerUtil.process(fileSet, new ReadActionProcessor<VirtualFile>() {
return ContainerUtil.process(collectProcessor.getResults(), new ReadActionProcessor<VirtualFile>() {
@Override
public boolean processInReadAction(VirtualFile virtualFile) {
return !IndexCacheManagerImpl.shouldBeFound(scope, virtualFile, index) || processor.process(virtualFile);
@@ -690,16 +683,9 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
continue;
}
final Collection<VirtualFile> fileSet = ApplicationManager.getApplication().runReadAction(new Computable<Collection<VirtualFile>>() {
@Override
public Collection<VirtualFile> compute() {
final CommonProcessors.CollectProcessor<VirtualFile> processor = new CommonProcessors.CollectProcessor<VirtualFile>();
FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, key, commonScope, null, processor);
return processor.getResults();
}
});
for (final VirtualFile file : fileSet) {
final CommonProcessors.CollectProcessor<VirtualFile> processor = new CommonProcessors.CollectProcessor<VirtualFile>();
processFilesContainingAllKeys(commonScope, null, processor, key);
for (final VirtualFile file : processor.getResults()) {
if (progress != null) {
progress.checkCanceled();
}
@@ -834,22 +820,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
@Nullable final PsiFile fileToIgnoreOccurencesIn,
@Nullable ProgressIndicator progress) {
final ArrayList<IdIndexEntry> keys = getWordEntries(name, true);
if (keys.isEmpty()) return SearchCostResult.ZERO_OCCURRENCES;
final TIntHashSet set = ApplicationManager.getApplication().runReadAction(new NullableComputable<TIntHashSet>() {
@Override
public TIntHashSet compute() {
return FileBasedIndex.getInstance().collectFileIdsContainingAllKeys(IdIndex.NAME, keys, scope, null);
}
});
if (set == null || set.size() > 1000 && !ApplicationManager.getApplication().isUnitTestMode()) {
return SearchCostResult.TOO_MANY_OCCURRENCES;
}
final AtomicInteger count = new AtomicInteger();
final FileIndexFacade index = FileIndexFacade.getInstance(myManager.getProject());
final Processor<VirtualFile> processor = new Processor<VirtualFile>() {
private final VirtualFile fileToIgnoreOccurencesInVirtualFile =
@@ -863,12 +834,8 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
return value < 10;
}
};
final boolean cheap = ApplicationManager.getApplication().runReadAction(new NullableComputable<Boolean>() {
@Override
public Boolean compute() {
return FileBasedIndex.processVirtualFiles(set, scope, processor);
}
});
final ArrayList<IdIndexEntry> keys = getWordEntries(name, true);
final boolean cheap = keys.isEmpty() || processFilesContainingAllKeys(scope, null, processor, keys);
if (!cheap) {
return SearchCostResult.TOO_MANY_OCCURRENCES;
@@ -877,6 +844,17 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
return count.get() == 0 ? SearchCostResult.ZERO_OCCURRENCES : SearchCostResult.FEW_OCCURRENCES;
}
private static boolean processFilesContainingAllKeys(final GlobalSearchScope scope,
@Nullable final Condition<Integer> checker,
final Processor<VirtualFile> processor, final Collection<IdIndexEntry> keys) {
return ApplicationManager.getApplication().runReadAction(new NullableComputable<Boolean>() {
@Override
public Boolean compute() {
return FileBasedIndex.getInstance().processFilesContainingAllKeys(IdIndex.NAME, keys, scope, checker, processor);
}
});
}
private static ArrayList<IdIndexEntry> getWordEntries(String name, boolean caseSensitively) {
List<String> words = StringUtil.getWordsIn(name);
final ArrayList<IdIndexEntry> keys = new ArrayList<IdIndexEntry>();
@@ -940,19 +940,20 @@ public class FileBasedIndex implements ApplicationComponent {
return result == null || result.booleanValue();
}
public <K, V> void processFilesContainingAllKeys(final ID<K, V> indexId,
public <K, V> boolean processFilesContainingAllKeys(final ID<K, V> indexId,
final Collection<K> dataKeys,
final GlobalSearchScope filter,
@Nullable Condition<V> valueChecker,
final Processor<VirtualFile> processor) {
final TIntHashSet set = collectFileIdsContainingAllKeys(indexId, dataKeys, filter, valueChecker);
if (set != null) {
processVirtualFiles(set, filter, processor);
if (set == null) {
return false;
}
return processVirtualFiles(set, filter, processor);
}
@Nullable
public <K, V> TIntHashSet collectFileIdsContainingAllKeys(final ID<K, V> indexId,
private <K, V> TIntHashSet collectFileIdsContainingAllKeys(final ID<K, V> indexId,
final Collection<K> dataKeys,
final GlobalSearchScope filter,
@Nullable final Condition<V> valueChecker) {
@@ -995,7 +996,7 @@ public class FileBasedIndex implements ApplicationComponent {
return processExceptions(indexId, null, filter, convertor);
}
public static boolean processVirtualFiles(TIntHashSet ids, final GlobalSearchScope filter, final Processor<VirtualFile> processor) {
private static boolean processVirtualFiles(TIntHashSet ids, final GlobalSearchScope filter, final Processor<VirtualFile> processor) {
final PersistentFS fs = (PersistentFS)ManagingFS.getInstance();
return ids.forEach(new TIntProcedure() {
@Override