mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
store vfs children as nonversioned file attribute
This commit is contained in:
@@ -21,6 +21,7 @@ package com.intellij.openapi.vfs.newvfs;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -28,15 +29,19 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class FileAttribute {
|
||||
private static final Set<String> ourRegisteredIds = new HashSet<String>();
|
||||
private static final Set<String> ourRegisteredIds = new THashSet<String>();
|
||||
private static final int UNDEFINED_VERSION = -1;
|
||||
private final String myId;
|
||||
private final int myVersion;
|
||||
private final boolean myFixedSize;
|
||||
|
||||
public FileAttribute(@NonNls @NotNull String id) {
|
||||
this(id, UNDEFINED_VERSION, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #FileAttribute(String, int, boolean)
|
||||
@@ -113,4 +118,8 @@ public class FileAttribute {
|
||||
public int getVersion() {
|
||||
return myVersion;
|
||||
}
|
||||
|
||||
public boolean isVersioned() {
|
||||
return myVersion != UNDEFINED_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-35
@@ -94,7 +94,7 @@ public class FSRecords implements Forceable {
|
||||
private static final int SAFELY_CLOSED_MAGIC = 0x1f2f3f4f;
|
||||
private static final int CORRUPTED_MAGIC = 0xabcf7f7f;
|
||||
|
||||
private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN";
|
||||
private static final FileAttribute ourChildrenAttr = new FileAttribute("FsRecords.DIRECTORY_CHILDREN");
|
||||
|
||||
private static final ReentrantReadWriteLock.ReadLock r;
|
||||
private static final ReentrantReadWriteLock.WriteLock w;
|
||||
@@ -685,7 +685,7 @@ public class FSRecords implements Forceable {
|
||||
try {
|
||||
try {
|
||||
r.lock();
|
||||
final DataInputStream input = readAttribute(1, CHILDREN_ATT);
|
||||
final DataInputStream input = readAttribute(1, ourChildrenAttr);
|
||||
if (input == null) return ArrayUtil.EMPTY_INT_ARRAY;
|
||||
|
||||
try {
|
||||
@@ -727,7 +727,7 @@ public class FSRecords implements Forceable {
|
||||
DbConnection.markDirty();
|
||||
final int root = getNames().enumerate(rootUrl);
|
||||
|
||||
final DataInputStream input = readAttribute(1, CHILDREN_ATT);
|
||||
final DataInputStream input = readAttribute(1, ourChildrenAttr);
|
||||
int[] names = ArrayUtil.EMPTY_INT_ARRAY;
|
||||
int[] ids = ArrayUtil.EMPTY_INT_ARRAY;
|
||||
|
||||
@@ -752,7 +752,7 @@ public class FSRecords implements Forceable {
|
||||
}
|
||||
}
|
||||
|
||||
final DataOutputStream output = writeAttribute(1, CHILDREN_ATT, false);
|
||||
final DataOutputStream output = writeAttribute(1, ourChildrenAttr);
|
||||
int id;
|
||||
try {
|
||||
id = createRecord();
|
||||
@@ -784,7 +784,7 @@ public class FSRecords implements Forceable {
|
||||
try {
|
||||
w.lock();
|
||||
DbConnection.markDirty();
|
||||
final DataInputStream input = readAttribute(1, CHILDREN_ATT);
|
||||
final DataInputStream input = readAttribute(1, ourChildrenAttr);
|
||||
assert input != null;
|
||||
int count;
|
||||
int[] names;
|
||||
@@ -809,7 +809,7 @@ public class FSRecords implements Forceable {
|
||||
names = ArrayUtil.remove(names, index);
|
||||
ids = ArrayUtil.remove(ids, index);
|
||||
|
||||
final DataOutputStream output = writeAttribute(1, CHILDREN_ATT, false);
|
||||
final DataOutputStream output = writeAttribute(1, ourChildrenAttr);
|
||||
try {
|
||||
DataInputOutputUtil.writeINT(output, count - 1);
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
@@ -834,7 +834,7 @@ public class FSRecords implements Forceable {
|
||||
try {
|
||||
r.lock();
|
||||
try {
|
||||
final DataInputStream input = readAttribute(id, CHILDREN_ATT);
|
||||
final DataInputStream input = readAttribute(id, ourChildrenAttr);
|
||||
if (input == null) return ArrayUtil.EMPTY_INT_ARRAY;
|
||||
|
||||
final int count = DataInputOutputUtil.readINT(input);
|
||||
@@ -879,7 +879,7 @@ public class FSRecords implements Forceable {
|
||||
try {
|
||||
r.lock();
|
||||
try {
|
||||
final DataInputStream input = readAttribute(parentId, CHILDREN_ATT);
|
||||
final DataInputStream input = readAttribute(parentId, ourChildrenAttr);
|
||||
if (input == null) return NameId.EMPTY_ARRAY;
|
||||
|
||||
int count = DataInputOutputUtil.readINT(input);
|
||||
@@ -906,7 +906,7 @@ public class FSRecords implements Forceable {
|
||||
try {
|
||||
r.lock();
|
||||
try {
|
||||
return findAttributePage(id, CHILDREN_ATT, false) != 0;
|
||||
return findAttributePage(id, ourChildrenAttr, false) != 0;
|
||||
} finally {
|
||||
r.unlock();
|
||||
}
|
||||
@@ -920,7 +920,7 @@ public class FSRecords implements Forceable {
|
||||
try {
|
||||
w.lock();
|
||||
DbConnection.markDirty();
|
||||
final DataOutputStream record = writeAttribute(id, CHILDREN_ATT, false);
|
||||
final DataOutputStream record = writeAttribute(id, ourChildrenAttr);
|
||||
DataInputOutputUtil.writeINT(record, children.length);
|
||||
for (int child : children) {
|
||||
if (child == id) {
|
||||
@@ -1241,8 +1241,8 @@ public class FSRecords implements Forceable {
|
||||
synchronized (att.getId()) {
|
||||
try {
|
||||
r.lock();
|
||||
DataInputStream stream = readAttribute(fileId, att.getId());
|
||||
if (stream != null) {
|
||||
DataInputStream stream = readAttribute(fileId, att);
|
||||
if (stream != null && att.isVersioned()) {
|
||||
try {
|
||||
int actualVersion = DataInputOutputUtil.readINT(stream);
|
||||
if (actualVersion != att.getVersion()) {
|
||||
@@ -1269,18 +1269,18 @@ public class FSRecords implements Forceable {
|
||||
|
||||
// should be called under r or w lock
|
||||
@Nullable
|
||||
private static DataInputStream readAttribute(int fileId, String attId) throws IOException {
|
||||
int page = findAttributePage(fileId, attId, false);
|
||||
private static DataInputStream readAttribute(int fileId, FileAttribute attribute) throws IOException {
|
||||
int page = findAttributePage(fileId, attribute, false);
|
||||
if (page == 0) return null;
|
||||
return getAttributesStorage().readStream(page);
|
||||
}
|
||||
|
||||
private static int findAttributePage(int fileId, @NotNull String attrId, boolean toWrite) throws IOException {
|
||||
private static int findAttributePage(int fileId, FileAttribute attr, boolean toWrite) throws IOException {
|
||||
checkFileIsValid(fileId);
|
||||
|
||||
Storage storage = getAttributesStorage();
|
||||
|
||||
int encodedAttrId = DbConnection.getAttributeId(attrId);
|
||||
int encodedAttrId = DbConnection.getAttributeId(attr.getId());
|
||||
int recordId = getAttributeRecordId(fileId);
|
||||
|
||||
if (recordId == 0) {
|
||||
@@ -1415,19 +1415,16 @@ public class FSRecords implements Forceable {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DataOutputStream writeAttribute(final int fileId, @NotNull String attId, boolean fixedSize) {
|
||||
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);
|
||||
DataOutputStream stream = new AttributeOutputStream(fileId, att);
|
||||
if (att.isVersioned()) {
|
||||
try {
|
||||
DataInputOutputUtil.writeINT(stream, att.getVersion());
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
@@ -1562,15 +1559,13 @@ public class FSRecords implements Forceable {
|
||||
}
|
||||
|
||||
private static class AttributeOutputStream extends DataOutputStream {
|
||||
private final String myAttributeId;
|
||||
private final FileAttribute myAttribute;
|
||||
private final int myFileId;
|
||||
private final boolean myFixedSize;
|
||||
|
||||
private AttributeOutputStream(final int fileId, @NotNull String attributeId, boolean fixedSize) {
|
||||
private AttributeOutputStream(final int fileId, @NotNull FileAttribute attribute) {
|
||||
super(new BufferExposingByteArrayOutputStream());
|
||||
myFileId = fileId;
|
||||
myFixedSize = fixedSize;
|
||||
myAttributeId = attributeId;
|
||||
myAttribute = attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1578,18 +1573,18 @@ public class FSRecords implements Forceable {
|
||||
super.close();
|
||||
|
||||
try {
|
||||
synchronized (myAttributeId) {
|
||||
synchronized (myAttribute.getId()) {
|
||||
final BufferExposingByteArrayOutputStream _out = (BufferExposingByteArrayOutputStream)out;
|
||||
final int page;
|
||||
try {
|
||||
w.lock();
|
||||
incModCount(myFileId);
|
||||
page = findAttributePage(myFileId, myAttributeId, true);
|
||||
page = findAttributePage(myFileId, myAttribute, true);
|
||||
}
|
||||
finally {
|
||||
w.unlock();
|
||||
}
|
||||
getAttributesStorage().writeBytes(page, new ByteSequence(_out.getInternalBuffer(), 0, _out.size()), myFixedSize);
|
||||
getAttributesStorage().writeBytes(page, new ByteSequence(_out.getInternalBuffer(), 0, _out.size()), myAttribute.isFixedSize());
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
|
||||
Reference in New Issue
Block a user