summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/openapi/vfs
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/vfs')
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java29
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java4
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java67
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java4
4 files changed, 82 insertions, 22 deletions
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
index 071a260fe68c..a95597514bb1 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
@@ -15,12 +15,14 @@
*/
package com.intellij.openapi.vfs.ex.dummy;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.BidirectionalMap;
@@ -32,7 +34,6 @@ import org.jetbrains.annotations.TestOnly;
import java.io.IOException;
import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
/**
@@ -76,11 +77,6 @@ public abstract class DummyCachingFileSystem<T extends VirtualFile> extends Dumm
public void projectOpened(final Project project) {
onProjectOpened(project);
}
-
- @Override
- public void projectClosed(final Project project) {
- onProjectClosed(project);
- }
});
initProjectMap();
}
@@ -135,7 +131,16 @@ public abstract class DummyCachingFileSystem<T extends VirtualFile> extends Dumm
clearCache();
}
- public void onProjectOpened(Project project) {
+ public void onProjectOpened(final Project project) {
+ // use Disposer instead of ProjectManagerListener#projectClosed() because Disposer.dispose(project)
+ // is called later and some cached files should stay valid till the last moment
+ Disposer.register(project, new Disposable() {
+ @Override
+ public void dispose() {
+ onProjectClosed(project);
+ }
+ });
+
clearCache();
String projectId = project.getLocationHash();
myProject2Id.put(project, projectId);
@@ -157,13 +162,11 @@ public abstract class DummyCachingFileSystem<T extends VirtualFile> extends Dumm
}
protected void clearInvalidFiles() {
- for (Iterator<String> it = myCachedFiles.keySet().iterator(); it.hasNext(); ) {
- String path = it.next();
- T t = myCachedFiles.get(path);
- if (t == null || !t.isValid()) {
- it.remove();
- }
+ for (T t : myCachedFiles.notNullValues()) {
+ if (!t.isValid()) myCachedFiles.removeValue(t);
}
+ //noinspection StatementWithEmptyBody
+ while (myCachedFiles.removeValue(null)) ;
}
@TestOnly
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java
index b6fa97092059..5a0f433c7828 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsRootAccess.java
@@ -49,7 +49,7 @@ import java.util.Set;
public class VfsRootAccess {
private static final boolean SHOULD_PERFORM_ACCESS_CHECK = System.getenv("NO_FS_ROOTS_ACCESS_CHECK") == null;
// we don't want test subclasses to accidentally remove allowed files, added by base classes
- private static final Set<String> ourAdditionalRoots = new THashSet<String>();
+ private static final Set<String> ourAdditionalRoots = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
private static boolean insideGettingRoots;
@TestOnly
@@ -109,7 +109,7 @@ public class VfsRootAccess {
Project[] openProjects = ProjectManager.getInstance().getOpenProjects();
if (openProjects.length == 0) return null;
- final Set<String> allowed = new THashSet<String>();
+ final Set<String> allowed = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
allowed.add(FileUtil.toSystemIndependentName(PathManager.getHomePath()));
try {
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
index b05b7a285e7b..b8a55b333203 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.util.io.ByteSequence;
import com.intellij.openapi.util.io.FileAttributes;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.newvfs.FileAttribute;
import com.intellij.openapi.vfs.newvfs.impl.FileNameCache;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SystemProperties;
@@ -57,6 +58,7 @@ public class FSRecords implements Forceable {
private static final Logger LOG = Logger.getInstance("#com.intellij.vfs.persistent.FSRecords");
public static final boolean weHaveContentHashes = SystemProperties.getBooleanProperty("idea.share.contents", true);
+ public static final boolean lazyVfsDataCleaning = SystemProperties.getBooleanProperty("idea.lazy.vfs.data.cleaning", true);
private static final int VERSION = 20 + (weHaveContentHashes ? 0x10:0) + (IOUtil.ourByteBuffersUseNativeByteOrder ? 0x37:0);
private static final int PARENT_OFFSET = 0;
@@ -558,6 +560,7 @@ public class FSRecords implements Forceable {
return newRecord;
}
else {
+ if (lazyVfsDataCleaning) deleteContentAndAttributes(free);
DbConnection.cleanRecord(free);
return free;
}
@@ -588,7 +591,33 @@ public class FSRecords implements Forceable {
try {
w.lock();
incModCount(id);
- doDeleteRecursively(id);
+ if (lazyVfsDataCleaning) {
+ markAsDeletedRecursively(id);
+ } else {
+ doDeleteRecursively(id);
+ }
+ }
+ catch (Throwable e) {
+ throw DbConnection.handleError(e);
+ }
+ finally {
+ w.unlock();
+ }
+ }
+
+ private static void markAsDeletedRecursively(final int id) {
+ for (int subrecord : list(id)) {
+ markAsDeletedRecursively(subrecord);
+ }
+
+ markAsDeleted(id);
+ }
+
+ private static void markAsDeleted(final int id) {
+ try {
+ w.lock();
+ DbConnection.markDirty();
+ addToFreeRecordsList(id);
}
catch (Throwable e) {
throw DbConnection.handleError(e);
@@ -1206,12 +1235,26 @@ public class FSRecords implements Forceable {
}
@Nullable
- static DataInputStream readAttributeWithLock(int fileId, String attId) {
+ public static DataInputStream readAttributeWithLock(int fileId, FileAttribute att) {
try {
- synchronized (attId) {
+ synchronized (att.getId()) {
try {
r.lock();
- return readAttribute(fileId, attId);
+ DataInputStream stream = readAttribute(fileId, att.getId());
+ if (stream != null) {
+ try {
+ int actualVersion = DataInputOutputUtil.readINT(stream);
+ if (actualVersion != att.getVersion()) {
+ stream.close();
+ return null;
+ }
+ }
+ catch (IOException e) {
+ stream.close();
+ return null;
+ }
+ }
+ return stream;
}
finally {
r.unlock();
@@ -1280,7 +1323,9 @@ public class FSRecords implements Forceable {
private static void checkFileIsValid(int fileId) {
assert fileId > 0 : fileId;
// TODO: This assertion is a bit timey, will remove when bug is caught.
- assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Accessing attribute of a deleted page: " + fileId + ":" + getName(fileId);
+ if (!lazyVfsDataCleaning) {
+ assert (getFlags(fileId) & FREE_RECORD_FLAG) == 0 : "Accessing attribute of a deleted page: " + fileId + ":" + getName(fileId);
+ }
}
public static int acquireFileContent(int fileId) {
@@ -1374,6 +1419,18 @@ public class FSRecords implements Forceable {
return new AttributeOutputStream(fileId, attId, fixedSize);
}
+ @NotNull
+ public static DataOutputStream writeAttribute(final int fileId, @NotNull FileAttribute att) {
+ DataOutputStream stream = writeAttribute(fileId, att.getId(), att.isFixedSize());
+ try {
+ DataInputOutputUtil.writeINT(stream, att.getVersion());
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return stream;
+ }
+
private static class ContentOutputStream extends DataOutputStream {
protected final int myFileId;
protected final boolean myFixedSize;
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 db5de4258d41..6e135018d356 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
@@ -223,13 +223,13 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
@Override
@Nullable
public DataInputStream readAttribute(@NotNull final VirtualFile file, @NotNull final FileAttribute att) {
- return FSRecords.readAttributeWithLock(getFileId(file), att.getId());
+ return FSRecords.readAttributeWithLock(getFileId(file), att);
}
@Override
@NotNull
public DataOutputStream writeAttribute(@NotNull final VirtualFile file, @NotNull final FileAttribute att) {
- return FSRecords.writeAttribute(getFileId(file), att.getId(), att.isFixedSize());
+ return FSRecords.writeAttribute(getFileId(file), att);
}
@Nullable