[vfs] minor optimizations and cleanup in LocalFileSystem

- watch request management reduced to a single method
- read action removed (not needed)
- post-test cleanup fix
This commit is contained in:
Roman Shevchenko
2016-03-17 21:00:26 +01:00
parent 8351fcb532
commit e8c62be3e6
6 changed files with 72 additions and 135 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,36 +75,48 @@ public abstract class LocalFileSystem extends NewVirtualFileSystem {
}
@Nullable
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean watchRecursively) {
final Set<WatchRequest> result = addRootsToWatch(singleton(rootPath), watchRecursively);
public WatchRequest addRootToWatch(@NotNull String rootPath, boolean watchRecursively) {
Set<WatchRequest> result = addRootsToWatch(singleton(rootPath), watchRecursively);
return result.size() == 1 ? result.iterator().next() : null;
}
@NotNull
public abstract Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively);
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean watchRecursively) {
if (rootPaths.isEmpty()) {
return Collections.emptySet();
}
else if (watchRecursively) {
return replaceWatchedRoots(Collections.emptySet(), rootPaths, null);
}
else {
return replaceWatchedRoots(Collections.emptySet(), null, rootPaths);
}
}
public void removeWatchedRoot(@Nullable final WatchRequest watchRequest) {
public void removeWatchedRoot(@Nullable WatchRequest watchRequest) {
if (watchRequest != null) {
removeWatchedRoots(singleton(watchRequest));
}
}
public abstract void removeWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests);
public void removeWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
if (!watchRequests.isEmpty()) {
replaceWatchedRoots(watchRequests, null, null);
}
}
@Nullable
public WatchRequest replaceWatchedRoot(@Nullable final WatchRequest watchRequest,
@NotNull final String rootPath,
final boolean watchRecursively) {
final Set<WatchRequest> requests = watchRequest != null ? singleton(watchRequest) : Collections.<WatchRequest>emptySet();
final Set<WatchRequest> result = watchRecursively ? replaceWatchedRoots(requests, singleton(rootPath), null)
: replaceWatchedRoots(requests, null, singleton(rootPath));
public WatchRequest replaceWatchedRoot(@Nullable WatchRequest watchRequest, @NotNull String rootPath, boolean watchRecursively) {
Set<WatchRequest> requests = watchRequest != null ? singleton(watchRequest) : Collections.emptySet();
Set<String> roots = singleton(rootPath);
Set<WatchRequest> result = watchRecursively ? replaceWatchedRoots(requests, roots, null) : replaceWatchedRoots(requests, null, roots);
return result.size() == 1 ? result.iterator().next() : null;
}
@NotNull
public abstract Set<WatchRequest> replaceWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests,
@Nullable final Collection<String> recursiveRoots,
@Nullable final Collection<String> flatRoots);
public abstract Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests,
@Nullable Collection<String> recursiveRoots,
@Nullable Collection<String> flatRoots);
/**
* Registers a handler that allows a version control system plugin to intercept file operations in the local file system
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -367,17 +367,6 @@ public class TempFileSystem extends LocalFileSystemBase {
return new FileAttributes(item.isDirectory(), false, false, false, length, item.myTimestamp, item.myWritable);
}
@NotNull
@Override
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean watchRecursively) {
throw new IncorrectOperationException();
}
@Override
public void removeWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
throw new IncorrectOperationException();
}
@NotNull
@Override
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests,
@@ -391,4 +380,4 @@ public class TempFileSystem extends LocalFileSystemBase {
protected String normalize(@NotNull String path) {
return path;
}
}
}
@@ -116,9 +116,8 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
}
private List<WatchRequestImpl> normalizeRootsForRefresh() {
final List<WatchRequestImpl> result = new ArrayList<WatchRequestImpl>();
List<WatchRequestImpl> result = new ArrayList<>();
// no need to call for a read action here since we're only called with it on hands already
synchronized (myLock) {
TreeNode rootNode = new TreeNode();
for (WatchRequestImpl request : myRootsToWatch) {
@@ -296,76 +295,23 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
}
}
private void setUpFileWatcher() {
Application app = ApplicationManager.getApplication();
app.assertReadAccessAllowed();
if (app.isDisposeInProgress() || !myWatcher.isOperational()) return;
synchronized (myLock) {
List<String> recursiveRoots = new ArrayList<>();
List<String> flatRoots = new ArrayList<>();
for (WatchRequestImpl request : normalizeRootsForRefresh()) {
(request.isToWatchRecursively() ? recursiveRoots : flatRoots).add(request.myFSRootPath);
}
myWatcher.setWatchRoots(recursiveRoots, flatRoots);
}
}
@Override
@NotNull
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively) {
if (rootPaths.isEmpty() || !myWatcher.isOperational()) {
return Collections.emptySet();
}
else if (watchRecursively) {
return replaceWatchedRoots(Collections.emptySet(), rootPaths, null);
}
else {
return replaceWatchedRoots(Collections.emptySet(), null, rootPaths);
}
}
@Override
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests) {
if (watchRequests.isEmpty()) return;
ApplicationManager.getApplication().runReadAction(() -> {
synchronized (myLock) {
boolean update = doRemoveWatchedRoots(watchRequests);
if (update) {
myNormalizedTree = null;
setUpFileWatcher();
}
}
});
}
@NotNull
@Override
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests,
@Nullable Collection<String> _recursiveRoots,
@Nullable Collection<String> _flatRoots) {
Collection<String> recursiveRoots = ObjectUtils.notNull(_recursiveRoots, Collections.<String>emptyList());
Collection<String> flatRoots = ObjectUtils.notNull(_flatRoots, Collections.<String>emptyList());
@Nullable Collection<String> recursiveRoots,
@Nullable Collection<String> flatRoots) {
recursiveRoots = ObjectUtils.notNull(recursiveRoots, Collections.emptyList());
flatRoots = ObjectUtils.notNull(flatRoots, Collections.emptyList());
if (recursiveRoots.isEmpty() && flatRoots.isEmpty() || !myWatcher.isOperational()) {
removeWatchedRoots(watchRequests);
return Collections.emptySet();
}
Set<WatchRequest> result = new HashSet<WatchRequest>();
ApplicationManager.getApplication().runReadAction(() -> {
synchronized (myLock) {
boolean update = doAddRootsToWatch(recursiveRoots, flatRoots, result) |
doRemoveWatchedRoots(watchRequests);
if (update) {
myNormalizedTree = null;
setUpFileWatcher();
}
Set<WatchRequest> result = new HashSet<>();
synchronized (myLock) {
boolean update = doAddRootsToWatch(recursiveRoots, flatRoots, result) |
doRemoveWatchedRoots(watchRequests);
if (update) {
myNormalizedTree = null;
setUpFileWatcher();
}
});
}
return result;
}
@@ -413,7 +359,7 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
return new WatchRequestImpl(rootFile.getAbsolutePath(), recursively);
}
private boolean doRemoveWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests) {
private boolean doRemoveWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
boolean update = false;
for (WatchRequest watchRequest : watchRequests) {
@@ -425,17 +371,26 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
return update;
}
private void setUpFileWatcher() {
if (!ApplicationManager.getApplication().isDisposeInProgress() && myWatcher.isOperational()) {
List<String> recursiveRoots = new ArrayList<>();
List<String> flatRoots = new ArrayList<>();
for (WatchRequestImpl request : normalizeRootsForRefresh()) {
(request.isToWatchRecursively() ? recursiveRoots : flatRoots).add(request.myFSRootPath);
}
myWatcher.setWatchRoots(recursiveRoots, flatRoots);
}
}
@Override
public void refreshWithoutFileWatcher(final boolean asynchronous) {
Runnable heavyRefresh = new Runnable() {
@Override
public void run() {
for (VirtualFile root : myManagingFS.getRoots(LocalFileSystemImpl.this)) {
((NewVirtualFile)root).markDirtyRecursively();
}
refresh(asynchronous);
Runnable heavyRefresh = () -> {
for (VirtualFile root : myManagingFS.getRoots(this)) {
((NewVirtualFile)root).markDirtyRecursively();
}
refresh(asynchronous);
};
if (asynchronous && myWatcher.isOperational()) {
@@ -455,6 +410,9 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
public void cleanupForNextTest() {
FileDocumentManager.getInstance().saveAllDocuments();
PersistentFS.getInstance().clearIdCache();
myRootsToWatch.clear();
synchronized (myLock) {
myRootsToWatch.clear();
myNormalizedTree = null;
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,17 +62,6 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
return myFsCache.getAttributes(file);
}
@NotNull
@Override
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean watchRecursively) {
throw new UnsupportedOperationException();
}
@Override
public void removeWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
throw new UnsupportedOperationException();
}
@NotNull
@Override
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests,
@@ -80,4 +69,4 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
@Nullable Collection<String> flatRoots) {
throw new UnsupportedOperationException();
}
}
}
@@ -49,6 +49,8 @@ public class RefreshSessionImpl extends RefreshSession {
private final boolean myIsRecursive;
private final Runnable myFinishRunnable;
private final ModalityState myModalityState;
private final DumbModePermission myDumbModePermission;
private final Throwable myStartTrace;
private final Semaphore mySemaphore = new Semaphore();
private List<VirtualFile> myWorkQueue = new ArrayList<VirtualFile>();
@@ -56,8 +58,6 @@ public class RefreshSessionImpl extends RefreshSession {
private volatile boolean iHaveEventsToFire;
private volatile RefreshWorker myWorker = null;
private volatile boolean myCancelled = false;
private final DumbModePermission myDumbModePermission;
private final Throwable myStartTrace;
public RefreshSessionImpl(boolean async, boolean recursive, @Nullable Runnable finishRunnable) {
this(async, recursive, finishRunnable, ModalityState.NON_MODAL);
@@ -150,7 +150,8 @@ public class RefreshSessionImpl extends RefreshSession {
nvf.markDirty();
}
RefreshWorker worker = myWorker = new RefreshWorker(nvf, myIsRecursive);
RefreshWorker worker = new RefreshWorker(nvf, myIsRecursive);
myWorker = worker;
worker.scan();
List<VFileEvent> events = worker.getEvents();
if (myEvents.addAll(events)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.mock;
import com.intellij.openapi.util.io.FileAttributes;
@@ -68,17 +67,6 @@ public class MockLocalFileSystem extends LocalFileSystem {
public void refreshFiles(@NotNull Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
}
@Override
@NotNull
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
}
@Override
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch) {
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
}
@NotNull
@Override
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests,
@@ -236,4 +224,4 @@ public class MockLocalFileSystem extends LocalFileSystem {
public FileAttributes getAttributes(@NotNull VirtualFile file) {
return null;
}
}
}