[vfs] cleanup & refactoring

+ changed method names, added javadoc

GitOrigin-RevId: 1277e85187b2fb8a6fdeccff8ed786806ba4d6db
This commit is contained in:
Ruslan Cheremin
2024-06-29 13:41:27 +02:00
committed by intellij-monorepo-bot
parent bd2766f742
commit 4c3b919103
5 changed files with 45 additions and 36 deletions

View File

@@ -1337,9 +1337,14 @@ public final class FSRecordsImpl implements Closeable {
} }
} }
int storeUnlinkedContent(@NotNull ByteArraySequence content) { /**
* Stores content and return contentRecordId, by which content could be later retrieved.
* If the same content (bytes) was already stored -- method could return id of already existing record, without allocating
* & storing new record.
*/
int writeContentRecord(@NotNull ByteArraySequence content) {
try { try {
return contentAccessor.allocateContentRecordAndStore(content); return contentAccessor.writeContentRecord(content);
} }
catch (IOException e) { catch (IOException e) {
throw handleError(e); throw handleError(e);

View File

@@ -43,13 +43,18 @@ public final class PersistentFSContentAccessor {
PersistentFSConnection.ensureIdIsValid(fileId); PersistentFSConnection.ensureIdIsValid(fileId);
PersistentFSRecordsStorage records = connection.getRecords(); PersistentFSRecordsStorage records = connection.getRecords();
int contentRecordId = allocateContentRecordAndStore(content); int contentRecordId = writeContentRecord(content);
records.setContentRecordId(fileId, contentRecordId); records.setContentRecordId(fileId, contentRecordId);
} }
int allocateContentRecordAndStore(@NotNull ByteArraySequence content) throws IOException { /**
* Stores content and return contentRecordId, by which content could be later retrieved.
* If the same content (bytes) was already stored -- method could return id of already existing record, without allocating
* & storing new record.
*/
int writeContentRecord(@NotNull ByteArraySequence content) throws IOException {
return connection.getContents().storeRecord(content); return connection.getContents().storeRecord(content);
} }

View File

@@ -488,7 +488,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
@Override @Override
public int storeUnlinkedContent(byte @NotNull [] bytes) { public int storeUnlinkedContent(byte @NotNull [] bytes) {
return vfsPeer.storeUnlinkedContent(new ByteArraySequence(bytes)); return vfsPeer.writeContentRecord(new ByteArraySequence(bytes));
} }
@SuppressWarnings("removal") @SuppressWarnings("removal")
@@ -828,15 +828,7 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
byte[] content = fs.contentsToByteArray(file); byte[] content = fs.contentsToByteArray(file);
if (mayCacheContent && shouldCache(content.length)) { if (mayCacheContent && shouldCache(content.length)) {
//VFS content storage is append-only, hence storing could be done outside the lock: updateContentForFile(fileId, new ByteArraySequence(content));
int newContentRecordId = vfsPeer.storeUnlinkedContent(new ByteArraySequence(content));
myInputLock.writeLock().lock();
try {
updateContentId(fileId, newContentRecordId, content.length);
}
finally {
myInputLock.writeLock().unlock();
}
} }
else { else {
myInputLock.writeLock().lock(); myInputLock.writeLock().lock();
@@ -992,25 +984,26 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
if (byteLength == fileLength) { if (byteLength == fileLength) {
ByteArraySequence newContent = new ByteArraySequence(bytes, 0, byteLength); ByteArraySequence newContent = new ByteArraySequence(bytes, 0, byteLength);
int newContentId = vfsPeer.storeUnlinkedContent(newContent); updateContentForFile(fileId, newContent);
myInputLock.writeLock().lock();
try {
updateContentId(fileId, newContentId, byteLength);
}
finally {
myInputLock.writeLock().unlock();
}
} }
else { else {
doCleanPersistedContent(fileId);
}
}
private void updateContentForFile(int fileId,
@NotNull ByteArraySequence newContent) throws IOException {
//VFS content storage is append-only, hence storing could be done outside the lock:
int newContentId = vfsPeer.writeContentRecord(newContent);
myInputLock.writeLock().lock(); myInputLock.writeLock().lock();
try { try {
doCleanPersistedContent(fileId); updateContentId(fileId, newContentId, newContent.length());
} }
finally { finally {
myInputLock.writeLock().unlock(); myInputLock.writeLock().unlock();
} }
} }
}
/** Method is obsolete, migrate to {@link #contentHashIfStored(VirtualFile)} instance method */ /** Method is obsolete, migrate to {@link #contentHashIfStored(VirtualFile)} instance method */
@TestOnly @TestOnly
@@ -2386,9 +2379,11 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
private void setFlag(int id, @Attributes int mask, boolean value) { private void setFlag(int id, @Attributes int mask, boolean value) {
int oldFlags = vfsPeer.getFlags(id); int oldFlags = vfsPeer.getFlags(id);
int flags = value ? oldFlags | mask : oldFlags & ~mask; int flags = value ? oldFlags | mask
: oldFlags & ~mask;
if (oldFlags != flags) { if (oldFlags != flags) {
//noinspection MagicConstant
vfsPeer.setFlags(id, flags); vfsPeer.setFlags(id, flags);
} }
} }
@@ -2458,9 +2453,13 @@ public final class PersistentFSImpl extends PersistentFS implements Disposable {
} }
private void doCleanPersistedContent(int id) { private void doCleanPersistedContent(int id) {
//TODO set in single call: setFlag(id, MUST_RELOAD_CONTENT | MUST_RELOAD_LENGTH, true); myInputLock.writeLock().lock();
setFlag(id, Flags.MUST_RELOAD_CONTENT, true); try {
setFlag(id, Flags.MUST_RELOAD_LENGTH, true); setFlag(id, Flags.MUST_RELOAD_CONTENT | Flags.MUST_RELOAD_LENGTH, true);
}
finally {
myInputLock.writeLock().unlock();
}
} }
@Override @Override

View File

@@ -393,7 +393,7 @@ object VfsRecoveryUtils {
when (val nextContent = snapshot.getContent(lastRecoveredContentId + 1)) { when (val nextContent = snapshot.getContent(lastRecoveredContentId + 1)) {
is NotAvailable -> break is NotAvailable -> break
is Ready -> { is Ready -> {
val result = newFsRecords.contentAccessor().allocateContentRecordAndStore(ByteArraySequence(nextContent.value)) val result = newFsRecords.contentAccessor().writeContentRecord(ByteArraySequence(nextContent.value))
check(result == lastRecoveredContentId + 1) { "assumption failed: got $result, expected ${lastRecoveredContentId + 1}" } check(result == lastRecoveredContentId + 1) { "assumption failed: got $result, expected ${lastRecoveredContentId + 1}" }
lastRecoveredContentId++ lastRecoveredContentId++
} }

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.util.io.storage; package com.intellij.util.io.storage;
import com.intellij.openapi.Forceable; import com.intellij.openapi.Forceable;
@@ -25,7 +25,7 @@ public interface VFSContentStorage extends CleanableStorage, Closeable, Forceabl
/** /**
* Stores bytes and return contentRecordId, by which content could be later retrieved. * Stores bytes and return contentRecordId, by which content could be later retrieved.
* If the same bytes was already stored -- method could return id of already existing record, without allocating * If the same content (bytes) was already stored -- method could return id of already existing record, without allocating
* & storing new record. * & storing new record.
*/ */
int storeRecord(@NotNull ByteArraySequence bytes) throws IOException; int storeRecord(@NotNull ByteArraySequence bytes) throws IOException;