summaryrefslogtreecommitdiff
path: root/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java')
-rw-r--r--platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java67
1 files changed, 62 insertions, 5 deletions
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;