Reduce number of FS operations on refresh

This commit is contained in:
Roman Shevchenko
2012-12-18 19:09:01 +01:00
parent 6e732bb036
commit e94f80bd20
@@ -27,14 +27,12 @@ import com.intellij.openapi.vfs.newvfs.events.*;
import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl;
import com.intellij.openapi.vfs.newvfs.impl.VirtualFileSystemEntry;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Queue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.*;
import static com.intellij.openapi.diagnostic.LogUtil.debug;
import static com.intellij.util.containers.ContainerUtil.newHashSet;
@@ -49,6 +47,7 @@ public class RefreshWorker {
private final Queue<VirtualFile> myRefreshQueue = new Queue<VirtualFile>(100);
private final List<VFileEvent> myEvents = new ArrayList<VFileEvent>();
private volatile boolean myCancelled = false;
private final Map<String, FileAttributes> myFsCache = ContainerUtil.newTroveMap();
public RefreshWorker(final VirtualFile refreshRoot, final boolean isRecursive) {
myIsRecursive = isRecursive;
@@ -67,7 +66,7 @@ public class RefreshWorker {
final long t = System.currentTimeMillis();
NewVirtualFileSystem fs = root.getFileSystem();
final FileAttributes rootAttributes = fs.getAttributes(root);
final FileAttributes rootAttributes = getAttributes(fs, root);
if (rootAttributes == null) {
scheduleDeletion(root);
@@ -89,7 +88,7 @@ public class RefreshWorker {
debug(LOG, "file=%s dirty=%b", file, fileDirty);
if (!fileDirty) continue;
final FileAttributes attributes = Comparing.equal(file, root) ? rootAttributes : fs.getAttributes(file);
final FileAttributes attributes = getAttributes(fs, file);
if (attributes == null) {
scheduleDeletion(file);
continue;
@@ -121,7 +120,7 @@ public class RefreshWorker {
for (String name : newNames) {
if (myCancelled) break main;
final FileAttributes childAttributes = fs.getAttributes(new FakeVirtualFile(file, name));
final FileAttributes childAttributes = getAttributes(fs, new FakeVirtualFile(file, name));
if (childAttributes != null) {
scheduleCreation(file, name, childAttributes.isDirectory());
}
@@ -133,7 +132,7 @@ public class RefreshWorker {
for (VirtualFile child : file.getChildren()) {
if (myCancelled) break main;
if (!deletedNames.contains(child.getName())) {
final FileAttributes childAttributes = fs.getAttributes(child);
final FileAttributes childAttributes = getAttributes(fs, child);
if (childAttributes != null) {
checkAndScheduleChildRefresh(file, child, childAttributes);
}
@@ -149,7 +148,7 @@ public class RefreshWorker {
debug(LOG, "cached=%s", cachedChildren);
for (VirtualFile child : cachedChildren) {
if (myCancelled) break main;
final FileAttributes childAttributes = fs.getAttributes(child);
final FileAttributes childAttributes = getAttributes(fs, child);
if (childAttributes != null) {
checkAndScheduleChildRefresh(file, child, childAttributes);
}
@@ -165,7 +164,7 @@ public class RefreshWorker {
if (name.isEmpty()) continue;
final VirtualFile fake = new FakeVirtualFile(file, name);
final FileAttributes childAttributes = fs.getAttributes(fake);
final FileAttributes childAttributes = getAttributes(fs, fake);
if (childAttributes != null) {
scheduleCreation(file, name, childAttributes.isDirectory());
}
@@ -195,9 +194,21 @@ public class RefreshWorker {
file.markClean();
}
myFsCache.clear();
debug(LOG, "root=%s time=%d", root, System.currentTimeMillis() - t);
}
@Nullable
private FileAttributes getAttributes(@NotNull NewVirtualFileSystem fs, @NotNull VirtualFile file) {
String path = file.getPath();
FileAttributes attributes = myFsCache.get(path);
if (attributes == null) {
attributes = fs.getAttributes(file);
myFsCache.put(path, attributes);
}
return attributes;
}
private void checkAndScheduleChildRefresh(@NotNull VirtualFileSystemEntry parent,
@NotNull VirtualFile child,
@NotNull FileAttributes childAttributes) {