Local History: do not iterate newly created directories, unless they are under a project's context (IDEA-122495)

This commit is contained in:
Anton Makeev
2014-03-21 14:17:27 +01:00
parent 089b5de8df
commit d4878138fd
2 changed files with 24 additions and 11 deletions
@@ -29,6 +29,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Clock;
import com.intellij.openapi.util.Comparing;
@@ -46,26 +47,38 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class IdeaGateway {
private static final Key<ContentAndTimestamps> SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY
= Key.create("LocalHistory.SAVED_DOCUMENT_CONTENT_AND_STAMP_KEY");
public boolean isVersioned(@NotNull VirtualFile f) {
return isVersioned(f, false);
}
public boolean isVersioned(@NotNull VirtualFile f, boolean shouldBeInContent) {
if (!f.isInLocalFileSystem()) return false;
String fileName = f.getName();
if (!f.isDirectory() && fileName.endsWith(".class")) return false;
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
boolean isInContent = false;
for (Project each : openProjects) {
if (each.isDefault()) continue;
if (!each.isInitialized()) continue;
if (Comparing.equal(each.getWorkspaceFile(), f)) return false;
if (ProjectRootManager.getInstance(each).getFileIndex().isIgnored(f)) return false;
ProjectFileIndex index = ProjectRootManager.getInstance(each).getFileIndex();
if (index.isIgnored(f)) return false;
isInContent |= index.isInContent(f);
}
if (shouldBeInContent && !isInContent) return false;
// optimisation: FileTypeManager.isFileIgnored(f) already checked inside ProjectFileIndex.isIgnored()
return openProjects.length != 0 || !FileTypeManager.getInstance().isFileIgnored(f);
}
@@ -140,14 +153,14 @@ public class IdeaGateway {
}
@NotNull
public static Collection<VirtualFile> iterateDBChildren(VirtualFile f) {
public static Iterable<VirtualFile> iterateDBChildren(VirtualFile f) {
if (!(f instanceof NewVirtualFile)) return Collections.emptyList();
NewVirtualFile nf = (NewVirtualFile)f;
return nf.getCachedChildren();
return nf.iterInDbChildren();
}
@NotNull
public static Collection<VirtualFile> loadAndIterateChildren(VirtualFile f) {
public static Iterable<VirtualFile> loadAndIterateChildren(VirtualFile f) {
if (!(f instanceof NewVirtualFile)) return Collections.emptyList();
NewVirtualFile nf = (NewVirtualFile)f;
return Arrays.asList(nf.getChildren());
@@ -175,7 +188,7 @@ public class IdeaGateway {
private void doCreateChildrenForPathOnly(@NotNull DirectoryEntry parent,
@NotNull String path,
@NotNull Collection<VirtualFile> children) {
@NotNull Iterable<VirtualFile> children) {
for (VirtualFile child : children) {
String name = StringUtil.trimStart(child.getName(), "/"); // on Mac FS root name is "/"
if (!path.startsWith(name)) continue;
@@ -238,7 +251,7 @@ public class IdeaGateway {
return newDir;
}
private void doCreateChildren(@NotNull DirectoryEntry parent, Collection<VirtualFile> children, final boolean forDeletion) {
private void doCreateChildren(@NotNull DirectoryEntry parent, Iterable<VirtualFile> children, final boolean forDeletion) {
List<Entry> entries = ContainerUtil.mapNotNull(children, new NullableFunction<VirtualFile, Entry>() {
@Override
public Entry fun(@NotNull VirtualFile each) {
@@ -26,8 +26,6 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.*;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements VirtualFileManagerListener, CommandListener {
private static final Key<Boolean> WAS_VERSIONED_KEY =
Key.create(LocalHistoryEventDispatcher.class.getSimpleName() + ".WAS_VERSIONED_KEY");
@@ -97,7 +95,9 @@ public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements V
if (f.isDirectory()) {
// For unversioned files we try to get cached children in hope that they are already generated by content root manager:
// cached children may mean that there are versioned sub-folders or sub-files.
Collection<VirtualFile> children = isVersioned(f) ? IdeaGateway.loadAndIterateChildren(f) : IdeaGateway.iterateDBChildren(f);
Iterable<VirtualFile> children = myGateway.isVersioned(f, true)
? IdeaGateway.loadAndIterateChildren(f)
: IdeaGateway.iterateDBChildren(f);
for (VirtualFile each : children) {
createRecursively(each);
}