when deciding whether to start dumb mode, consider number of pending invalidation...
authorEugene Zhuravlev <jeka@intellij.com>
Tue, 9 Mar 2010 14:45:16 +0000 (17:45 +0300)
committerEugene Zhuravlev <jeka@intellij.com>
Tue, 9 Mar 2010 14:54:03 +0000 (17:54 +0300)
12 files changed:
platform/lang-impl/src/com/intellij/util/fileIndex/AbstractFileIndex.java
platform/lang-impl/src/com/intellij/util/fileIndex/FileIndexRefreshCacheUpdater.java
platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java
platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java
platform/lang-impl/src/com/intellij/util/indexing/UnindexedFilesUpdater.java
platform/lvcs-impl/src/com/intellij/history/integration/EventDispatcher.java
platform/lvcs-impl/src/com/intellij/history/integration/LocalHistoryCacheUpdater.java
platform/platform-api/src/com/intellij/ide/caches/CacheUpdater.java
platform/platform-impl/src/com/intellij/internal/ToggleDumbModeAction.java
platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java
platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateSession.java
platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java

index ab91bfbb14c4de3735e95905652ec0cd5254fc05..c6d83e13535e86bfb033fe8f0cd7da0272ecf41f 100644 (file)
@@ -344,6 +344,10 @@ public abstract class AbstractFileIndex<IndexEntry extends FileIndexEntry> imple
       return AbstractFileIndex.this.queryNeededFiles(myIncludeChangedFiles, myFileTypesToRefresh);
     }
 
+    public int getNumberOfPendingUpdateJobs() {
+      return 0;
+    }
+
     public void processFile(FileContent fileContent) {
       updateIndexEntry(fileContent.getVirtualFile());
     }
index e9c5350a9c806f9b3ef19d002e4d0a3e33b729ad..a535a7b86742cdad432ee84170763b3d0f02a982 100644 (file)
@@ -66,6 +66,10 @@ public class FileIndexRefreshCacheUpdater extends VirtualFileAdapter implements
     }
   }
 
+  public int getNumberOfPendingUpdateJobs() {
+    return 0;
+  }
+
   public VirtualFile[] queryNeededFiles() {
     return VfsUtil.toVirtualFileArray(myChangedFiles);
   }
index 6474a292f85afaea65bb0076dff612ed3ca964fa..61dbf0e6387977396170f7316790da12967fbe0f 100644 (file)
@@ -1190,6 +1190,10 @@ private boolean indexUnsavedDocument(final Document document, final ID<?, ?> req
     return pair != null? pair.getSecond() : null;
   }
 
+  public int getNumberOfPendingInvalidations() {
+    return myChangedFilesCollector.getNumberOfPendingInvalidations();
+  }
+
   public Collection<VirtualFile> getFilesToUpdate(final Project project) {
     final ProjectFileIndex projectIndex = ProjectRootManager.getInstance(project).getFileIndex();
     return ContainerUtil.findAll(myChangedFilesCollector.getAllFilesToUpdate(), new Condition<VirtualFile>() {
@@ -1533,6 +1537,16 @@ private boolean indexUnsavedDocument(final Document document, final ID<?, ?> req
       }
     }
 
+    public int getNumberOfPendingInvalidations() {
+      r.lock();
+      try {
+        return myFutureInvalidations.size();
+      }
+      finally {
+        r.unlock();
+      }
+    }
+
     public void ensureAllInvalidateTasksCompleted() {
       final int size;
       r.lock();
index ef34fb6b0ce65a1970aed3a5ee4225cb410ec087..4dcee4416e012f25e71c79d72174bdd6f96e6517 100644 (file)
@@ -97,6 +97,10 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
   }
 
   private class RefreshCacheUpdater implements CacheUpdater {
+    public int getNumberOfPendingUpdateJobs() {
+      return myIndex.getNumberOfPendingInvalidations();
+    }
+
     public VirtualFile[] queryNeededFiles() {
       Collection<VirtualFile> files = myIndex.getFilesToUpdate(myProject);
       return VfsUtil.toVirtualFileArray(files);
index 27077909ab544c40a94fa459b0a10b921efc4719..5bfa6425d65b721bdfe326e93ac4fa984c01e187 100644 (file)
@@ -19,7 +19,7 @@ package com.intellij.util.indexing;
 import com.intellij.ide.caches.CacheUpdater;
 import com.intellij.ide.caches.FileContent;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.CollectingContentIterator;
 import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 
@@ -38,6 +38,10 @@ public class UnindexedFilesUpdater implements CacheUpdater {
     myProject = project;
   }
 
+  public int getNumberOfPendingUpdateJobs() {
+    return myIndex.getNumberOfPendingInvalidations();
+  }
+
   public VirtualFile[] queryNeededFiles() {
     CollectingContentIterator finder = myIndex.createContentIterator();
     FileBasedIndex.iterateIndexableFiles(finder, myProject);
index 6e44cd76cf788c170255b1bfb16a985a73485266..f0d596c800a65c0147c57fe5bfeea5042ecb6024 100644 (file)
@@ -20,8 +20,8 @@ import com.intellij.history.core.LocalVcs;
 import com.intellij.history.core.Paths;
 import com.intellij.history.core.tree.Entry;
 import com.intellij.history.utils.LocalHistoryLog;
-import com.intellij.ide.caches.FileContent;
 import com.intellij.ide.caches.CacheUpdater;
+import com.intellij.ide.caches.FileContent;
 import com.intellij.openapi.command.CommandEvent;
 import com.intellij.openapi.command.CommandListener;
 import com.intellij.openapi.vfs.*;
@@ -59,6 +59,10 @@ public class EventDispatcher extends VirtualFileAdapter implements VirtualFileMa
     return myRefreshDepth > 0;
   }
 
+  public int getNumberOfPendingUpdateJobs() {
+    return 0;
+  }
+
   public VirtualFile[] queryNeededFiles() {
     return getOrInitProcessor().queryNeededFiles();
   }
index 41e15a368b47e7d4385512f187343eda88d119e8..63266d6e6bea87cbf5705842ee9e208c77d58088 100644 (file)
@@ -26,7 +26,10 @@ import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.containers.ContainerUtil;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
 public class LocalHistoryCacheUpdater implements CacheUpdater {
   private final LocalVcs myVcs;
@@ -82,6 +85,10 @@ public class LocalHistoryCacheUpdater implements CacheUpdater {
     myProcessor.processFile(c);
   }
 
+  public int getNumberOfPendingUpdateJobs() {
+    return 0;
+  }
+
   public void updatingDone() {
     myVcs.endChangeSet(myChangeSetName);
     myVfsRoots = null;
index 8fd1aae440f5e1d404062fa0b1eda18b9896427a..68cece670ad2cb77acc132af3aa7d7357167f235 100644 (file)
@@ -19,8 +19,13 @@ package com.intellij.ide.caches;
 import com.intellij.openapi.vfs.VirtualFile;
 
 public interface CacheUpdater {
+  int getNumberOfPendingUpdateJobs();
+
   VirtualFile[] queryNeededFiles();
+
   void processFile(FileContent fileContent);
+
   void updatingDone();
+
   void canceled();
 }
index 7ab71dad99809be6dad2ce9aa948d65a3cfee881..51c59a3eb1ccc94a9a9c125cc1e797ee14a4c238 100644 (file)
@@ -44,6 +44,10 @@ public class ToggleDumbModeAction extends AnAction implements DumbAware {
       if (project == null) return;
 
       CacheUpdater updater = new CacheUpdater() {
+        public int getNumberOfPendingUpdateJobs() {
+          return 0;
+        }
+
         public VirtualFile[] queryNeededFiles() {
           while (myDumb) {
             try {
index cf9747ebd39f931f8bc0a728e981ee56f9245798..9c388e9bbe0e0137c05a284c34c297ae336334f4 100644 (file)
@@ -49,6 +49,13 @@ class CacheUpdateRunner {
     return mySession.getFilesToUpdate().size();
   }
 
+  public int getNumberOfPendingUpdateJobs(ProgressIndicator indicator) {
+    if (mySession == null) {
+      mySession = new CacheUpdateSession(myUpdaters, indicator);
+    }
+    return mySession.getNumberOfPendingUpdateJobs();
+  }
+
   public void processFiles(final ProgressIndicator indicator, boolean processInReadAction) {
     try {
       indicator.checkCanceled();
index 7c48de132107e002f0bc413ad4aa741ad0541d05..565cc27e79e05ee29cca2e8fe077cec896093c71 100644 (file)
@@ -31,6 +31,7 @@ public class CacheUpdateSession {
   private static final Logger LOG = Logger.getInstance("#" + CacheUpdateSession.class.getName());
   private static final Key<Boolean> FAILED_TO_INDEX = Key.create(CacheUpdateSession.class.getSimpleName() + ".FAILED_TO_INDEX");
   private final Collection<VirtualFile> myFilesToUpdate;
+  private final int myJobsToDo;
   private final List<Pair<CacheUpdater, Collection<VirtualFile>>> myUpdatersWithFiles =
     new ArrayList<Pair<CacheUpdater, Collection<VirtualFile>>>();
 
@@ -39,9 +40,11 @@ public class CacheUpdateSession {
 
     myFilesToUpdate = new LinkedHashSet<VirtualFile>();
     try {
+      int jobsCount = 0;
       for (CacheUpdater each : updaters) {
         indicator.checkCanceled();
         try {
+          jobsCount += each.getNumberOfPendingUpdateJobs();
           List<VirtualFile> updaterFiles = Arrays.asList(each.queryNeededFiles());
           processedUpdaters.add(each);
           myFilesToUpdate.addAll(updaterFiles);
@@ -54,6 +57,7 @@ public class CacheUpdateSession {
           LOG.error(e);
         }
       }
+      myJobsToDo = jobsCount;
     }
     catch (ProcessCanceledException e) {
       for (CacheUpdater each : processedUpdaters) {
@@ -63,6 +67,10 @@ public class CacheUpdateSession {
     }
   }
 
+  public int getNumberOfPendingUpdateJobs() {
+    return myJobsToDo;
+  }
+  
   public Collection<VirtualFile> getFilesToUpdate() {
     return myFilesToUpdate;
   }
index b2b1c86543bc64376850d55bb84facbe0ebd75f8..1d6fb06e5439d027b6f233d77d0ea0d7edf131e8 100644 (file)
@@ -111,8 +111,9 @@ public class DumbServiceImpl extends DumbService {
       }
       try {
         final int size = runner.queryNeededFiles(indicator);
-        if (size < 50) {
-          // if not that many files found, process them on the spot, avoiding entering dumb mode
+        if ((size + runner.getNumberOfPendingUpdateJobs(indicator)) < 50) {
+          // If not that many files found, process them on the spot, avoiding entering dumb mode
+          // Consider number of pending tasks as well, becase they may take noticeable time to process even if the number of files is small
           if (size > 0) {
             runner.processFiles(indicator, false);
           }