From 2bea19631d495488fcea9b7bae2c644903ae1da6 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 26 May 2015 15:18:32 +0200 Subject: [PATCH] introduce ManagingFS.getCheapFileSystemStructureModificationCount that increments only on structural VFS changes to save VirtualFilePointer-s from being recalculated on every workspace.xml change --- .../openapi/vfs/newvfs/ManagingFS.java | 18 +++++++++++++++++- .../openapi/vfs/impl/FilePointerPartNode.java | 4 +++- .../vfs/newvfs/impl/VirtualDirectoryImpl.java | 3 +++ .../newvfs/impl/VirtualFileSystemEntry.java | 2 ++ .../newvfs/persistent/PersistentFSImpl.java | 12 ++++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ManagingFS.java b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ManagingFS.java index 6bf7937f9e87..660f9f6ebd68 100644 --- a/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ManagingFS.java +++ b/platform/platform-api/src/com/intellij/openapi/vfs/newvfs/ManagingFS.java @@ -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(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java index 766134e43dda..abebf03e0fa9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java @@ -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 fileAndUrl) { this.part = part; @@ -242,7 +244,7 @@ class FilePointerPartNode { Pair update() { long lastUpdated = myLastUpdated; Pair fileAndUrl = myFileAndUrl; - long fsModCount = ourFileManager.getModificationCount(); + long fsModCount = ourManagingFS.getCheapFileSystemStructureModificationCount(); if (lastUpdated == fsModCount) return fileAndUrl; VirtualFile file = fileAndUrl.first; String url = fileAndUrl.second; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index 42d97333b54a..661bf1f0cdf9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -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() { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java index fb40a8497bb7..7258d275daeb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java @@ -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); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index 63575727d84d..eeb65f8fcf11 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -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) {