Revert(inspections "fatal.errors" failing mysteriously): reuse PersistentFS directory cache to avoid re-creating and retaining VDirs unnecessarily

This commit is contained in:
Alexey Kudravtsev
2017-10-25 15:40:13 +03:00
parent 6f3cf388f9
commit de252f1eb2
2 changed files with 10 additions and 29 deletions
@@ -20,8 +20,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.InvalidVirtualFileAccessException;
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.concurrency.AtomicFieldUpdater;
import com.intellij.util.containers.ConcurrentBitSet;
@@ -64,12 +62,12 @@ import static com.intellij.util.ObjectUtils.assertNotNull;
* and creates the file instance. See {@link #initFile}
*
* 3. After that the file is live, an object representing it can be retrieved any time from its parent. File system roots are
* kept on hard references in {@link PersistentFS}
* kept on hard references in {@link com.intellij.openapi.vfs.newvfs.persistent.PersistentFS}
*
* 4. If a file is deleted (invalidated), then its data is not needed anymore, and should be removed. But this can only happen after
* all the listener have been notified about the file deletion and have had their chance to look at the data the last time. See {@link #killInvalidatedFiles()}
*
* 5. The file with removed data is marked as "dead" (see {@link #ourDeadMarker}, any access to it will throw {@link InvalidVirtualFileAccessException}
* 5. The file with removed data is marked as "dead" (see {@link #ourDeadMarker}, any access to it will throw {@link com.intellij.openapi.vfs.InvalidVirtualFileAccessException}
* Dead ids won't be reused in the same session of the IDE.
*
* @author peter
@@ -112,11 +110,7 @@ public class VfsData {
}
@Nullable
static VirtualFileSystemEntry getFileById(int id, @NotNull VirtualDirectoryImpl parent) {
PersistentFSImpl persistentFS = (PersistentFSImpl)PersistentFS.getInstance();
VirtualFileSystemEntry dir = persistentFS.getCachedDir(id);
if (dir != null) return dir;
static VirtualFileSystemEntry getFileById(int id, VirtualDirectoryImpl parent) {
Segment segment = getSegment(id, false);
if (segment == null) return null;
@@ -133,7 +127,7 @@ public class VfsData {
throw new AssertionError("nameId=" + nameId + "; data=" + o + "; parent=" + parent + "; parent.id=" + parent.getId() + "; db.parent=" + FSRecords.getParent(id));
}
return o instanceof DirectoryData ? persistentFS.getOrCacheDir(id, segment, (DirectoryData)o, parent)
return o instanceof DirectoryData ? new VirtualDirectoryImpl(id, segment, (DirectoryData)o, parent, parent.getFileSystem())
: new VirtualFileImpl(id, segment, parent);
}
@@ -279,7 +273,7 @@ public class VfsData {
private Set<CharSequence> myAdoptedNames; // guarded by this
@NotNull
VirtualFileSystemEntry[] getFileChildren(int fileId, @NotNull VirtualDirectoryImpl parent) {
VirtualFileSystemEntry[] getFileChildren(int fileId, VirtualDirectoryImpl parent) {
assert fileId > 0;
VirtualFileSystemEntry[] children = new VirtualFileSystemEntry[myChildrenIds.length];
for (int i = 0; i < myChildrenIds.length; i++) {
@@ -69,7 +69,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
private final ConcurrentIntObjectMap<VirtualFileSystemEntry> myRootsById = ContainerUtil.createConcurrentIntObjectMap(10, 0.4f, JobSchedulerImpl.CORES_COUNT);
// FS roots must be in this map too. findFileById() relies on this.
private final ConcurrentIntObjectMap<VirtualFileSystemEntry> myIdToDirCache = ContainerUtil.createConcurrentIntObjectSoftValueMap();
private final ConcurrentIntObjectMap<VirtualFileSystemEntry> myIdToDirCache = ContainerUtil.createConcurrentIntObjectMap();
private final Object myInputLock = new Object();
private final AtomicBoolean myShutDown = new AtomicBoolean(false);
@@ -121,20 +121,6 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
return FSRecords.getCreationTimestamp();
}
@NotNull
public VirtualFileSystemEntry getOrCacheDir(int id,
@NotNull VfsData.Segment segment,
@NotNull VfsData.DirectoryData o,
@NotNull VirtualDirectoryImpl parent) {
VirtualFileSystemEntry dir = myIdToDirCache.get(id);
if (dir != null) return dir;
dir = new VirtualDirectoryImpl(id, segment, o, parent, parent.getFileSystem());
return myIdToDirCache.cacheOrGet(id, dir);
}
public VirtualFileSystemEntry getCachedDir(int id) {
return myIdToDirCache.get(id);
}
@NotNull
private static NewVirtualFileSystem getDelegate(@NotNull VirtualFile file) {
return (NewVirtualFileSystem)file.getFileSystem();
@@ -1053,10 +1039,11 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
@Override
public void clearIdCache() {
// remove all except myRootsById contents
int[] ids = myIdToDirCache.keys();
for (int id : ids) {
for (Iterator<ConcurrentIntObjectMap.IntEntry<VirtualFileSystemEntry>> iterator = myIdToDirCache.entries().iterator(); iterator.hasNext(); ) {
ConcurrentIntObjectMap.IntEntry<VirtualFileSystemEntry> entry = iterator.next();
int id = entry.getKey();
if (!myRootsById.containsKey(id)) {
myIdToDirCache.remove(id);
iterator.remove();
}
}
}