introduce ManagingFS.getCheapFileSystemStructureModificationCount that increments only on structural VFS changes to save VirtualFilePointer-s from being recalculated on every workspace.xml change

This commit is contained in:
peter
2015-05-26 15:20:35 +02:00
parent 125b0ef148
commit 2bea19631d
5 changed files with 37 additions and 2 deletions
@@ -43,9 +43,25 @@ public abstract class ManagingFS implements FileSystemInterface {
public abstract int getModificationCount(@NotNull VirtualFile fileOrDirectory);
// Only counts modifications done in current IDEA session
/**
* @return a number that's incremented every time something changes in the VFS, i.e. file hierarchy, names, flags, attributes, contents.
* This only counts modifications done in current IDE session.
* @see #getCheapFileSystemStructureModificationCount()
* @see #getFilesystemModificationCount()
*/
public abstract int getCheapFileSystemModificationCount();
/**
* @return a number that's incremented every time something changes in the VFS structure, i.e. file hierarchy or names.
* This only counts modifications done in current IDE session.
* @see #getCheapFileSystemModificationCount()
*/
public abstract int getCheapFileSystemStructureModificationCount();
/**
* @return a number that's incremented every time something changes in the VFS, i.e. file hierarchy, names, flags, attributes, contents.
* This number is persisted between IDE sessions and so it'll always increase. This method invocation means disk access, so it's not terribly cheap.
*/
public abstract int getFilesystemModificationCount();
public abstract long getCreationTimestamp();
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -43,6 +44,7 @@ class FilePointerPartNode {
private int pointersUnder = 1; // number of alive pointers in this node plus all nodes beneath
private static final VirtualFileManager ourFileManager = VirtualFileManager.getInstance();
private static final ManagingFS ourManagingFS = ManagingFS.getInstance();
FilePointerPartNode(@NotNull String part, FilePointerPartNode parent, Pair<VirtualFile,String> fileAndUrl) {
this.part = part;
@@ -242,7 +244,7 @@ class FilePointerPartNode {
Pair<VirtualFile, String> update() {
long lastUpdated = myLastUpdated;
Pair<VirtualFile, String> fileAndUrl = myFileAndUrl;
long fsModCount = ourFileManager.getModificationCount();
long fsModCount = ourManagingFS.getCheapFileSystemStructureModificationCount();
if (lastUpdated == fsModCount) return fileAndUrl;
VirtualFile file = fileAndUrl.first;
String url = fileAndUrl.second;
@@ -31,6 +31,7 @@ import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent;
import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.UriUtil;
@@ -434,6 +435,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
assert appended[i] > 0 : file;
System.arraycopy(array, i, appended, i + 1, array.length - i);
myData.myChildrenIds = appended;
((PersistentFSImpl)PersistentFS.getInstance()).incStructuralModificationCount();
}
public void removeChild(@NotNull VirtualFile file) {
@@ -447,6 +449,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry {
private void removeFromArray(int index) {
myData.myChildrenIds = ArrayUtil.remove(myData.myChildrenIds, index);
((PersistentFSImpl)PersistentFS.getInstance()).incStructuralModificationCount();
}
public boolean allChildrenLoaded() {
@@ -29,6 +29,7 @@ import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.openapi.vfs.encoding.EncodingRegistry;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl;
import com.intellij.psi.SingleRootFileViewProvider;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.text.CharArrayUtil;
@@ -325,6 +326,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile {
VirtualDirectoryImpl parent = getParent();
parent.removeChild(this);
mySegment.setNameId(myId, FileNameCache.storeName(newName));
((PersistentFSImpl)PersistentFS.getInstance()).incStructuralModificationCount();
parent.addChild(this);
}
@@ -74,6 +74,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
clearIdCache();
}
});
private volatile int myStructureModificationCount;
public PersistentFSImpl(@NotNull MessageBus bus) {
myEventBus = bus;
@@ -266,6 +267,15 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
return FSRecords.getLocalModCount();
}
@Override
public int getCheapFileSystemStructureModificationCount() {
return myStructureModificationCount;
}
public void incStructuralModificationCount() {
myStructureModificationCount++;
}
@Override
public int getFilesystemModificationCount() {
return FSRecords.getModCount();
@@ -910,6 +920,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
if (root != null) return root;
VfsData.initFile(rootId, segment, -1, directoryData);
incStructuralModificationCount();
mark = writeAttributesToRecord(rootId, 0, newRoot, fs, attributes);
myRoots.put(rootUrl, newRoot);
@@ -1172,6 +1183,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
FSRecords.deleteRecordRecursively(id);
invalidateSubtree(file);
incStructuralModificationCount();
}
private static void invalidateSubtree(@NotNull VirtualFile file) {