before accessing index data forcibly update only those 'dirty' files that can affect...
authorEugene Zhuravlev <jeka@intellij.com>
Tue, 6 Oct 2009 07:05:45 +0000 (11:05 +0400)
committerEugene Zhuravlev <jeka@intellij.com>
Tue, 6 Oct 2009 07:05:45 +0000 (11:05 +0400)
platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java
platform/lang-impl/src/com/intellij/util/indexing/BackgroundCacheUpdaterRunner.java
platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java

index f6d6283ef069e212dc556da506d2b9a939f19fe1..556784eefaab2bd6adbe03abdb5ddabd033050ca 100644 (file)
@@ -151,7 +151,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
                                                            final GlobalSearchScope scope) {
     checkRebuild(project);
 
-    FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project);
+    FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, scope);
 
     final PersistentFS fs = (PersistentFS)ManagingFS.getInstance();
     final PsiManager psiManager = PsiManager.getInstance(project);
@@ -289,7 +289,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe
 
   public <K> Collection<K> getAllKeys(final StubIndexKey<K, ?> indexKey, @NotNull Project project) {
     checkRebuild(project);
-    FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project);
+    FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, GlobalSearchScope.allScope(project));
 
     final MyIndex<K> index = (MyIndex<K>)myIndices.get(indexKey);
     try {
index 7ccf4b3a0554de52b28660531b99463d6283bcb2..75a623f211205e5d2cf0d5992ad77c7a12a3755c 100644 (file)
@@ -13,7 +13,6 @@ import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.progress.util.ProgressIndicatorBase;
 import com.intellij.openapi.project.DumbServiceImpl;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.project.ProjectUtil;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.Ref;
@@ -25,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
-import java.util.concurrent.CountDownLatch;
 
 /**
  * @author Eugene Zhuravlev
@@ -53,25 +51,6 @@ public class BackgroundCacheUpdaterRunner {
   }
 
   public void processFiles(final CacheUpdater updater) {
-    final CountDownLatch latch = new CountDownLatch(myProjectToFileMap.size());
-    
-    for (Project project : ProjectManager.getInstance().getOpenProjects()) {
-      if (!myProjectToFileMap.containsKey(project)) {
-        // if the project is not affected still need to enter dumb mode to keep indices updating in background
-        // otherwise index access from this project may cause forceUpdate() which will index all the files in the calling thread
-        DumbServiceImpl.getInstance(project).queueIndexUpdate(new Consumer<ProgressIndicator>() {
-          public void consume(ProgressIndicator progressIndicator) {
-            try {
-              // just wait until update ends and exit dumb mode
-              latch.await();
-            }
-            catch (InterruptedException ignored) {
-            }
-          }
-        });
-      }
-    }
-
     for (Map.Entry<Project, Collection<VirtualFile>> entry : myProjectToFileMap.entrySet()) {
       final Project project = entry.getKey();
       final Collection<VirtualFile> files = entry.getValue();
@@ -106,14 +85,8 @@ public class BackgroundCacheUpdaterRunner {
             }
           }
           finally {
-            latch.countDown();
             queue.clear();
             updater.updatingDone();
-            try {
-              latch.await();
-            }
-            catch (InterruptedException ignored) {
-            }
           }
         }
       };
@@ -121,13 +94,8 @@ public class BackgroundCacheUpdaterRunner {
         DumbServiceImpl.getInstance(project).queueIndexUpdate(action);
       }
       else {
-        try {
-          final ProgressIndicator currentIndicator = ProgressManager.getInstance().getProgressIndicator();
-          action.consume(currentIndicator != null? currentIndicator : new EmptyProgressIndicator());
-        }
-        finally {
-          latch.countDown();
-        }
+        final ProgressIndicator currentIndicator = ProgressManager.getInstance().getProgressIndicator();
+        action.consume(currentIndicator != null? currentIndicator : new EmptyProgressIndicator());
       }
     }
   }
index 62fc4881112472b941d582da7f71bd1e5235f86c..c38046e52735a5c694cb2f2921e8930df0d2794e 100644 (file)
@@ -418,7 +418,7 @@ public class FileBasedIndex implements ApplicationComponent {
     
     LOG.info("START INDEX SHUTDOWN");
     try {
-      myChangedFilesUpdater.forceUpdate();
+      myChangedFilesUpdater.forceUpdate(null);
 
       for (ID<?, ?> indexId : myIndices.keySet()) {
         final UpdatableIndex<?, ?, FileContent> index = getIndex(indexId);
@@ -458,6 +458,10 @@ public class FileBasedIndex implements ApplicationComponent {
     });
   }
 
+  /**
+   * @param project it is guaranteeed to return data which is up-to-date withing the project
+   * Keys obtained from the files which do not belong to the project specified may not be up-to-date or even exist
+   */
   @NotNull
   public <K> Collection<K> getAllKeys(final ID<K, ?> indexId, @NotNull Project project) {
     Set<K> allKeys = new HashSet<K>();
@@ -465,9 +469,13 @@ public class FileBasedIndex implements ApplicationComponent {
     return allKeys;
   }
 
+  /**
+   * @param project it is guaranteeed to return data which is up-to-date withing the project
+   * Keys obtained from the files which do not belong to the project specified may not be up-to-date or even exist
+   */
   public <K> boolean processAllKeys(final ID<K, ?> indexId, Processor<K> processor, @NotNull Project project) {
     try {
-      ensureUpToDate(indexId, project);
+      ensureUpToDate(indexId, project, GlobalSearchScope.allScope(project));
       final UpdatableIndex<K, ?, FileContent> index = getIndex(indexId);
       if (index == null) return true;
       return index.processAllKeys(processor);
@@ -524,7 +532,7 @@ public class FileBasedIndex implements ApplicationComponent {
    * DO NOT CALL DIRECTLY IN CLIENT CODE
    * The method is internal to indexing engine end is called internally. The method is public due to implementation details
    */
-  public <K> void ensureUpToDate(final ID<K, ?> indexId, @NotNull Project project) {
+  public <K> void ensureUpToDate(final ID<K, ?> indexId, @NotNull Project project, @Nullable GlobalSearchScope filter) {
     if (isDumb(project)) {
       handleDumbMode(indexId, project);
     }
@@ -540,6 +548,7 @@ public class FileBasedIndex implements ApplicationComponent {
       if (isUpToDateCheckEnabled()) {
         try {
           checkRebuild(indexId, false);
+          myChangedFilesUpdater.forceUpdate(filter);
           indexUnsavedDocuments(indexId, project);
         }
         catch (StorageException e) {
@@ -636,7 +645,7 @@ public class FileBasedIndex implements ApplicationComponent {
     try {
       final Project project = filter.getProject();
       assert project != null : "GlobalSearchScope#getProject() should be not-null for all index queries";
-      ensureUpToDate(indexId, project);
+      ensureUpToDate(indexId, project, filter);
       final UpdatableIndex<K, V, FileContent> index = getIndex(indexId);
       if (index == null) {
         return true;
@@ -709,7 +718,7 @@ public class FileBasedIndex implements ApplicationComponent {
     try {
       final Project project = filter.getProject();
       assert project != null : "GlobalSearchScope#getProject() should be not-null for all index queries";
-      ensureUpToDate(indexId, project);
+      ensureUpToDate(indexId, project, filter);
       final UpdatableIndex<K, V, FileContent> index = getIndex(indexId);
       if (index == null) {
         return true;
@@ -794,7 +803,7 @@ public class FileBasedIndex implements ApplicationComponent {
 
   public <K, V> void processAllValues(final ID<K, V> indexId, AllValuesProcessor<V> processor, @NotNull Project project) {
     try {
-      ensureUpToDate(indexId, project);
+      ensureUpToDate(indexId, project, null);
       final UpdatableIndex<K, V, FileContent> index = getIndex(indexId);
       if (index == null) {
         return;
@@ -909,7 +918,6 @@ public class FileBasedIndex implements ApplicationComponent {
   }
 
   private void indexUnsavedDocuments(ID<?, ?> indexId, Project project) throws StorageException {
-    myChangedFilesUpdater.forceUpdate();
 
     if (myUpToDateIndices.contains(indexId)) {
       return; // no need to index unsaved docs
@@ -1526,19 +1534,22 @@ public class FileBasedIndex implements ApplicationComponent {
 
     private final Semaphore myForceUpdateSemaphore = new Semaphore();
 
-    public void forceUpdate() {
+    public void forceUpdate(@Nullable GlobalSearchScope filter) {
       myChangedFilesUpdater.ensureAllInvalidateTasksCompleted();
       final VirtualFile[] files = queryNeededFiles();
       if (files.length > 0) {
-        myForceUpdateSemaphore.down();
-        try {
-          for (VirtualFile file: files) {
-            processFileImpl(new com.intellij.ide.startup.FileContent(file));
+        for (VirtualFile file: files) {
+          if (filter == null || filter.accept(file)) {
+            try {
+              myForceUpdateSemaphore.down();
+              // process only files that can affect result
+              processFileImpl(new com.intellij.ide.startup.FileContent(file));
+            }
+            finally {
+              myForceUpdateSemaphore.up();
+            }
           }
         }
-        finally {
-          myForceUpdateSemaphore.up();
-        }
       }
 
       // If several threads entered the method at the same time and there were files to update,
@@ -1692,7 +1703,7 @@ public class FileBasedIndex implements ApplicationComponent {
   }
 
   public void removeIndexableSet(IndexableFileSet set) {
-    myChangedFilesUpdater.forceUpdate();
+    myChangedFilesUpdater.forceUpdate(null);
     myIndexableSets.remove(set);
   }