From 1f4d0df3058dc5b3d29833916702ac54985be802 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Sun, 1 Jun 2014 18:40:46 +0400 Subject: [PATCH] notify BuildManager only if file events affect opened and watched projects (second part of IDEA-122685) --- .../impl/TranslatingCompilerFilesMonitor.java | 196 ++++++++---------- .../compiler/server/BuildManager.java | 15 +- 2 files changed, 88 insertions(+), 123 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java index 6d2d798807c9..6fb96027dddc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -25,7 +25,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; @@ -78,7 +77,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { void execute(VirtualFile file); } - private static void processRecursively(final VirtualFile fromFile, final boolean dbOnly, final boolean needReadAction, final FileProcessor processor) { + private static void processRecursively(final VirtualFile fromFile, final boolean dbOnly, final FileProcessor processor) { if (!(fromFile.getFileSystem() instanceof LocalFileSystem)) { return; } @@ -103,77 +102,70 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { if (dbOnly) { return file.isDirectory()? ((NewVirtualFile)file).iterInDbChildren() : null; } - if (file.equals(fromFile) || !file.isDirectory()) { - return null; // skipping additional checks for the initial file and non-directory files - } - // optimization: for all files that are not under content of currently opened projects iterate over DB children - return isInContentOfOpenedProject(file, needReadAction)? null : ((NewVirtualFile)file).iterInDbChildren(); + return null; } }); } - private static boolean isInContentOfOpenedProject(@NotNull final VirtualFile file, boolean needReadAction) { + private static boolean isInContentOfOpenedProject(@NotNull final VirtualFile file) { // probably need a read action to ensure that the project was not disposed during the iteration over the project list - final Computable computation = new Computable() { - public Boolean compute() { - for (Project project : ProjectManager.getInstance().getOpenProjects()) { - if (!project.isInitialized()) { - continue; - } - if (ProjectRootManager.getInstance(project).getFileIndex().isInContent(file)) { - return Boolean.TRUE; - } - } - return Boolean.FALSE; + for (Project project : ProjectManager.getInstance().getOpenProjects()) { + if (!project.isInitialized() || !BuildManager.getInstance().isProjectWatched(project)) { + continue; } - }; - return needReadAction? ApplicationManager.getApplication().runReadAction(computation) : computation.compute(); + if (ProjectRootManager.getInstance(project).getFileIndex().isInContent(file)) { + return true; + } + } + return false; } private class MyVfsListener extends VirtualFileAdapter { public void propertyChanged(@NotNull final VirtualFilePropertyEvent event) { if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) { final VirtualFile eventFile = event.getFile(); - final VirtualFile parent = event.getParent(); - if (parent != null) { - final String oldName = (String)event.getOldValue(); - final String root = parent.getPath() + "/" + oldName; - final Set toMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - if (eventFile.isDirectory()) { - VfsUtilCore.visitChildrenRecursively(eventFile, new VirtualFileVisitor() { - private StringBuilder filePath = new StringBuilder(root); - - @Override - public boolean visitFile(@NotNull VirtualFile child) { - if (child.isDirectory()) { - if (!Comparing.equal(child, eventFile)) { - filePath.append("/").append(child.getName()); + if (isInContentOfOpenedProject(eventFile)) { + final VirtualFile parent = event.getParent(); + if (parent != null) { + final String oldName = (String)event.getOldValue(); + final String root = parent.getPath() + "/" + oldName; + final Set toMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + if (eventFile.isDirectory()) { + VfsUtilCore.visitChildrenRecursively(eventFile, new VirtualFileVisitor() { + private StringBuilder filePath = new StringBuilder(root); + + @Override + public boolean visitFile(@NotNull VirtualFile child) { + if (child.isDirectory()) { + if (!Comparing.equal(child, eventFile)) { + filePath.append("/").append(child.getName()); + } + } + else { + String childPath = filePath.toString(); + if (!Comparing.equal(child, eventFile)) { + childPath += "/" + child.getName(); + } + toMark.add(new File(childPath)); + } + return true; + } + + @Override + public void afterChildrenVisited(@NotNull VirtualFile file) { + if (file.isDirectory() && !Comparing.equal(file, eventFile)) { + filePath.delete(filePath.length() - file.getName().length() - 1, filePath.length()); } } - else { - String childPath = filePath.toString(); - if (!Comparing.equal(child, eventFile)) { - childPath += "/" + child.getName(); - } - toMark.add(new File(childPath)); - } - return true; - } - - @Override - public void afterChildrenVisited(@NotNull VirtualFile file) { - if (file.isDirectory() && !Comparing.equal(file, eventFile)) { - filePath.delete(filePath.length() - file.getName().length() - 1, filePath.length()); - } - } - }); + }); + } + else { + toMark.add(new File(root)); + } + notifyFilesDeleted(toMark); } - else { - toMark.add(new File(root)); - } - notifyFilesDeleted(toMark); + markDirtyIfSource(eventFile, false); } - markDirtyIfSource(eventFile, false); } } @@ -195,23 +187,25 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { public void beforeFileDeletion(@NotNull final VirtualFileEvent event) { final VirtualFile eventFile = event.getFile(); - if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) { - final String message = "Processing file deletion: " + eventFile.getPresentableUrl(); - LOG.debug(message); - if (ourDebugMode) { - System.out.println(message); + if (isInContentOfOpenedProject(eventFile)) { + if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) { + final String message = "Processing file deletion: " + eventFile.getPresentableUrl(); + LOG.debug(message); + if (ourDebugMode) { + System.out.println(message); + } } + + final Set pathsToMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + + processRecursively(eventFile, true, new FileProcessor() { + public void execute(final VirtualFile file) { + pathsToMark.add(new File(file.getPath())); + } + }); + + notifyFilesDeleted(pathsToMark); } - - final Set pathsToMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - - processRecursively(eventFile, true, false, new FileProcessor() { - public void execute(final VirtualFile file) { - pathsToMark.add(new File(file.getPath())); - } - }); - - notifyFilesDeleted(pathsToMark); } public void beforeFileMovement(@NotNull final VirtualFileMoveEvent event) { @@ -219,54 +213,34 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } private void markDirtyIfSource(final VirtualFile file, final boolean fromMove) { - final Set pathsToMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - processRecursively(file, false, false, new FileProcessor() { - public void execute(final VirtualFile file) { - pathsToMark.add(new File(file.getPath())); - } - }); - if (fromMove) { - notifyFilesDeleted(pathsToMark); - } - else if (!isIgnoredOrUnderIgnoredDirectory(file)) { - notifyFilesChanged(pathsToMark); - } - } - - private void processNewFile(final VirtualFile file) { - if (!isIgnoredOrUnderIgnoredDirectory(file)) { // todo: avoid duplicated isInContent check + if (isInContentOfOpenedProject(file)) { final Set pathsToMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); - boolean dbOnly = !isInContentOfOpenedProject(file, false); - processRecursively(file, dbOnly, false, new FileProcessor() { - @Override - public void execute(VirtualFile file) { + processRecursively(file, false, new FileProcessor() { + public void execute(final VirtualFile file) { pathsToMark.add(new File(file.getPath())); } }); - notifyFilesChanged(pathsToMark); + if (fromMove) { + notifyFilesDeleted(pathsToMark); + } + else { + notifyFilesChanged(pathsToMark); + } } } } - private static boolean isIgnoredOrUnderIgnoredDirectory(final VirtualFile file) { - final FileTypeManager fileTypeManager = FileTypeManager.getInstance(); - if (fileTypeManager.isFileIgnored(file)) { - return true; + private static void processNewFile(final VirtualFile file) { + if (isInContentOfOpenedProject(file)) { + final Set pathsToMark = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + processRecursively(file, false, new FileProcessor() { + @Override + public void execute(VirtualFile file) { + pathsToMark.add(new File(file.getPath())); + } + }); + notifyFilesChanged(pathsToMark); } - - //optimization: if file is in content of some project it's definitely not ignored - if (isInContentOfOpenedProject(file, true)) { - return false; - } - - VirtualFile current = file.getParent(); - while (current != null) { - if (fileTypeManager.isFileIgnored(current)) { - return true; - } - current = current.getParent(); - } - return false; } private static void notifyFilesChanged(Collection paths) { diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index a2404e863a6e..cb01abba6015 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -91,7 +91,6 @@ import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.TestOnly; import org.jetbrains.ide.PooledThreadExecutor; import org.jetbrains.io.ChannelRegistrar; import org.jetbrains.io.NettyUtil; @@ -383,12 +382,8 @@ public class BuildManager implements ApplicationComponent{ scheduleAutoMake(); } - public boolean rescanRequired(Project project) { - final String projectPath = getProjectPath(project); - synchronized (myProjectDataMap) { - final ProjectData data = myProjectDataMap.get(projectPath); - return data == null || data.myNeedRescan; - } + public boolean isProjectWatched(Project project) { + return myProjectDataMap.containsKey(getProjectPath(project)); } @Nullable @@ -915,6 +910,7 @@ public class BuildManager implements ApplicationComponent{ cmdLine.addParameter("-D" + GlobalOptions.LOG_DIR_OPTION + "=" + FileUtil.toSystemIndependentName(getBuildLogDirectory().getAbsolutePath())); final File workDirectory = getBuildSystemDirectory(); + //noinspection ResultOfMethodCallIgnored workDirectory.mkdirs(); cmdLine.addParameter("-Djava.io.tmpdir=" + FileUtil.toSystemIndependentName(workDirectory.getPath()) + "/" + TEMP_DIR_NAME); @@ -1034,11 +1030,6 @@ public class BuildManager implements ApplicationComponent{ return ((InetSocketAddress)serverChannel.localAddress()).getPort(); } - @TestOnly - public void stopWatchingProject(Project project) { - myProjectDataMap.remove(getProjectPath(project)); - } - private static String classpathToString(List cp) { StringBuilder builder = new StringBuilder(); for (String file : cp) {