no 'too many ids' heuristic in isCheapEnoughToSearch, as this depends largely on...
authorpeter <peter@jetbrains.com>
Fri, 20 Jan 2012 14:21:53 +0000 (15:21 +0100)
committerpeter <peter@jetbrains.com>
Fri, 20 Jan 2012 16:02:01 +0000 (17:02 +0100)
platform/lang-impl/src/com/intellij/psi/impl/cache/CacheManager.java
platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java
platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java

index cc945d7ea04a0e0639ee9527844074d830a6997f..5773600672f65037ef67352c2692fc38f143cda4 100644 (file)
@@ -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
    */
index 8b23fb509d01958442a41b82d67f802f435448da..689b68b7725db2f608d0956f68444fc67c2349d4 100644 (file)
@@ -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()) {
index 15d6995c4c413cce7b9f65e8b90417d56ddc9f5f..5cbfb27eefe610f5dcbe2719854b590ec3590c91 100644 (file)
@@ -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>();
index ced92a753e96862508bd3508c28d421a3815a4a4..75491603c11a866465ac888c2bb7e919d8069f9c 100644 (file)
@@ -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