From e59db2dcbbcd910392fb98954b6ebbbf7095a0b0 Mon Sep 17 00:00:00 2001 From: Ruslan Cheremin Date: Tue, 10 Dec 2024 17:45:54 +0100 Subject: [PATCH] [vfs][cleanup] drop long-unused `PersistentFSRecordsOverLockFreePagedStorage` implementation - last used >1year ago GitOrigin-RevId: 6bdbda9dcf57e2c3903314a3cd2b7c2b3dd45783 --- ...tentFSRecordsOverLockFreePagedStorage.java | 879 ------------------ .../PersistentFSRecordsStorageFactory.kt | 40 +- .../PersistentFSStoragesBenchmarks.java | 64 -- ...dsStorageOverLockFreePagedStorageTest.java | 128 --- .../persistent/VFSInitializationTest.java | 12 +- 5 files changed, 4 insertions(+), 1119 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsOverLockFreePagedStorage.java delete mode 100644 platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageOverLockFreePagedStorageTest.java diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsOverLockFreePagedStorage.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsOverLockFreePagedStorage.java deleted file mode 100644 index e87d31cf4f36..000000000000 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsOverLockFreePagedStorage.java +++ /dev/null @@ -1,879 +0,0 @@ -// 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.openapi.vfs.newvfs.persistent; - -import com.intellij.util.io.PagedFileStorageWithRWLockedPageContent; -import com.intellij.util.io.pagecache.Page; -import com.intellij.util.io.pagecache.PageUnsafe; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.VisibleForTesting; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.ByteBuffer; -import java.util.concurrent.atomic.AtomicInteger; - -import static com.intellij.openapi.vfs.newvfs.persistent.PersistentFSHeaders.*; - -/** - * Implementation uses new {@link PagedFileStorageWithRWLockedPageContent} - */ -@ApiStatus.Internal -public final class PersistentFSRecordsOverLockFreePagedStorage implements PersistentFSRecordsStorage, IPersistentFSRecordsStorage { - - - /* ================ FILE HEADER FIELDS LAYOUT ======================================================= */ - - public static final int HEADER_SIZE = PersistentFSHeaders.HEADER_SIZE; - - /* ================ RECORD FIELDS LAYOUT =========================================================== */ - - private static final int PARENT_REF_OFFSET = 0; - private static final int PARENT_REF_SIZE = Integer.BYTES; - private static final int NAME_REF_OFFSET = PARENT_REF_OFFSET + PARENT_REF_SIZE; - private static final int NAME_REF_SIZE = Integer.BYTES; - private static final int FLAGS_OFFSET = NAME_REF_OFFSET + NAME_REF_SIZE; - private static final int FLAGS_SIZE = Integer.BYTES; - private static final int ATTR_REF_OFFSET = FLAGS_OFFSET + FLAGS_SIZE; - private static final int ATTR_REF_SIZE = Integer.BYTES; - private static final int CONTENT_REF_OFFSET = ATTR_REF_OFFSET + ATTR_REF_SIZE; - private static final int CONTENT_REF_SIZE = Integer.BYTES; - private static final int MOD_COUNT_OFFSET = CONTENT_REF_OFFSET + CONTENT_REF_SIZE; - private static final int MOD_COUNT_SIZE = Integer.BYTES; - //RC: moved timestamp 1 field down so both LONG fields are 8-byte aligned (for atomic accesses alignment is important) - private static final int TIMESTAMP_OFFSET = MOD_COUNT_OFFSET + MOD_COUNT_SIZE; - private static final int TIMESTAMP_SIZE = Long.BYTES; - private static final int LENGTH_OFFSET = TIMESTAMP_OFFSET + TIMESTAMP_SIZE; - private static final int LENGTH_SIZE = Long.BYTES; - - public static final int RECORD_SIZE_IN_BYTES = LENGTH_OFFSET + LENGTH_SIZE; - - /* ================ RECORD FIELDS LAYOUT end ======================================== */ - - private final @NotNull PagedFileStorageWithRWLockedPageContent storage; - - /** How many records were allocated already. allocatedRecordsCount-1 == last record id */ - private final AtomicInteger allocatedRecordsCount = new AtomicInteger(0); - - /** - * Incremented on each update of anything in the storage -- header, record. Hence be seen as 'version' - * of storage content -- not storage format version, but current storage content. - * Stored in {@link PersistentFSHeaders#HEADER_GLOBAL_MOD_COUNT_OFFSET} header field. - * If a record is updated -> current value of globalModCount is 'stamped' into a record MOD_COUNT field. - */ - private final AtomicInteger globalModCount = new AtomicInteger(0); - - //cached for faster access: - private final transient int pageSize; - private final transient int recordsPerPage; - - private final transient HeaderAccessor headerAccessor = new HeaderAccessor(this); - - private final boolean wasClosedProperly; - - public PersistentFSRecordsOverLockFreePagedStorage(final @NotNull PagedFileStorageWithRWLockedPageContent storage) throws IOException { - this.storage = storage; - - pageSize = storage.getPageSize(); - recordsPerPage = pageSize / RECORD_SIZE_IN_BYTES; - - final int recordsCountInStorage = loadRecordsCount(storage.length()); - allocatedRecordsCount.set(recordsCountInStorage); - - globalModCount.set(getIntHeaderField(HEADER_GLOBAL_MOD_COUNT_OFFSET)); - - int connectionStatus = getIntHeaderField(HEADER_CONNECTION_STATUS_OFFSET); - wasClosedProperly = (connectionStatus == SAFELY_CLOSED_STAMP); - setIntHeaderField(HEADER_CONNECTION_STATUS_OFFSET, IN_USE_STAMP); - force();//CONNECTION_STATUS change makes file dirty, but it is unexpected to have freshly opened storage dirty => flush it - //MAYBE RC: flushing on storage open is also not good for (startup) performance. Instead, we could update the position in - // a page with raw update, without notifying storage of changes, which tricks storage think it is !dirty. - // Normally this calls for a bug, but in this particular case flushing connection status change has no sense until - // some _other_, actual change(s) happened -- i.e. if connection status change is the _only_ change happened, it is - // perfectly fine to lose it, i.e. not store it on .force()/.close() -- we must store connection status only if - // some other change(s) happened. - } - - @VisibleForTesting - int loadRecordsCount(final long storageSizeBytes) throws IOException { - if (storageSizeBytes == 0) { - return 0; - } - final long fullPagesOccupied = storageSizeBytes / pageSize; - if (fullPagesOccupied == 0) { - final long fullRecordsOnHeaderPage = (storageSizeBytes - HEADER_SIZE) / RECORD_SIZE_IN_BYTES; - final long recordExcess = (storageSizeBytes - HEADER_SIZE) % RECORD_SIZE_IN_BYTES; - if (recordExcess > 0) { - throw new IOException( - this.storage + " is corrupted: " + - "(" + storageSizeBytes + "b on a header page) = (" + fullRecordsOnHeaderPage + " whole records)" + - " + (" + recordExcess + "b excess)" + - " -> storage is likely truncated, or was created with pageSize != current(" + pageSize + "b)" - ); - } - - return (int)fullRecordsOnHeaderPage; - } - else { - final long lastPageOccupiedBytes = storageSizeBytes % pageSize; - - final long fullRecordsOnLastPage = lastPageOccupiedBytes / RECORD_SIZE_IN_BYTES; - final long recordExcess = lastPageOccupiedBytes % RECORD_SIZE_IN_BYTES; - if (recordExcess > 0) { - throw new IOException( - this.storage + " is corrupted: " + - "(" + lastPageOccupiedBytes + "b on last page) = (" + fullRecordsOnLastPage + " whole records)" + - " + (" + recordExcess + "b excess)" + - " -> storage is likely truncated, or was created with pageSize != current(" + pageSize + "b)" - ); - } - - return (int)( - (pageSize - HEADER_SIZE) / RECORD_SIZE_IN_BYTES //header page has fewer records! - + (fullPagesOccupied - 1) * recordsPerPage - + fullRecordsOnLastPage); - } - } - - @Override - public int recordsCount() { - return allocatedRecordsCount.get(); - } - - @Override - public int maxAllocatedID() { - return allocatedRecordsCount.get(); - } - - @Override - public boolean isValidFileId(int recordId) { - final int allocatedSoFar = allocatedRecordsCount.get(); - return FSRecords.NULL_FILE_ID < recordId && recordId <= allocatedSoFar; - } - - @Override - public R readRecord(final int recordId, - final @NotNull RecordReader reader) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */false)) { - page.lockPageForRead(); - try { - final RecordAccessor recordAccessor = new RecordAccessor(recordId, recordOffsetOnPage, page, allocatedRecordsCount); - return reader.readRecord(recordAccessor); - } - finally { - page.unlockPageForRead(); - } - } - } - - @Override - public int updateRecord(final int recordId, - final @NotNull RecordUpdater updater) throws IOException { - final int trueRecordId = (recordId <= NULL_ID) ? - allocateRecord() : - recordId; - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */true)) { - page.lockPageForWrite(); - try { - //RC: hope EscapeAnalysis removes the allocation here: - final RecordAccessor recordAccessor = new RecordAccessor(recordId, recordOffsetOnPage, page, allocatedRecordsCount); - final boolean updated = updater.updateRecord(recordAccessor); - if (updated) { - incrementRecordVersion(recordAccessor.pageBuffer, recordOffsetOnPage); - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - return trueRecordId; - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public R readHeader(final @NotNull HeaderReader reader) throws IOException { - try (final Page page = storage.pageByOffset(0, /*forWrite: */false)) { - page.lockPageForRead(); - try { - return reader.readHeader(headerAccessor); - } - finally { - page.unlockPageForRead(); - } - } - } - - @Override - public void updateHeader(final @NotNull HeaderUpdater updater) throws IOException { - try (final Page page = storage.pageByOffset(0, /*forWrite: */true)) { - page.lockPageForWrite(); - try { - if (updater.updateHeader(headerAccessor)) { - globalModCount.incrementAndGet(); - } - } - finally { - page.unlockPageForWrite(); - } - } - } - - - private static final class RecordAccessor implements RecordForUpdate { - private final int recordId; - private final int recordOffsetInPage; - private final Page recordPage; - private final transient ByteBuffer pageBuffer; - private final AtomicInteger allocatedRecordsCount; - - private RecordAccessor(int recordId, - int recordOffsetInPage, - PageUnsafe recordPage, - AtomicInteger allocatedRecordsCount) { - this.recordId = recordId; - this.recordOffsetInPage = recordOffsetInPage; - this.recordPage = recordPage; - pageBuffer = recordPage.rawPageBuffer(); - this.allocatedRecordsCount = allocatedRecordsCount; - } - - @Override - public int recordId() { - return recordId; - } - - @Override - public int getAttributeRecordId() { - return pageBuffer.getInt(recordOffsetInPage + ATTR_REF_OFFSET); - } - - @Override - public int getParent() { - return pageBuffer.getInt(recordOffsetInPage + PARENT_REF_OFFSET); - } - - @Override - public int getNameId() { - return pageBuffer.getInt(recordOffsetInPage + NAME_REF_OFFSET); - } - - @Override - public long getLength() { - return pageBuffer.getLong(recordOffsetInPage + LENGTH_OFFSET); - } - - @Override - public long getTimestamp() { - return pageBuffer.getLong(recordOffsetInPage + TIMESTAMP_OFFSET); - } - - @Override - public int getModCount() { - return pageBuffer.getInt(recordOffsetInPage + MOD_COUNT_OFFSET); - } - - @Override - public int getContentRecordId() { - return pageBuffer.getInt(recordOffsetInPage + CONTENT_REF_OFFSET); - } - - @Override - public @PersistentFS.Attributes int getFlags() { - return pageBuffer.getInt(recordOffsetInPage + FLAGS_OFFSET); - } - - @Override - public void setAttributeRecordId(final int attributeRecordId) { - checkValidIdField(recordId, attributeRecordId, "attributeRecordId"); - pageBuffer.putInt(recordOffsetInPage + ATTR_REF_OFFSET, attributeRecordId); - } - - @Override - public void setParent(final int parentId) { - checkParentIdIsValid(parentId); - pageBuffer.putInt(recordOffsetInPage + PARENT_REF_OFFSET, parentId); - } - - @Override - public void setNameId(final int nameId) { - pageBuffer.putInt(recordOffsetInPage + NAME_REF_OFFSET, nameId); - } - - @Override - public boolean setFlags(final @PersistentFS.Attributes int flags) { - final int fieldOffsetInPage = recordOffsetInPage + FLAGS_OFFSET; - if (pageBuffer.getInt(fieldOffsetInPage) != flags) { - pageBuffer.putInt(fieldOffsetInPage, flags); - return true; - } - return false; - } - - @Override - public boolean setLength(final long length) { - final int fieldOffsetInPage = recordOffsetInPage + LENGTH_OFFSET; - if (pageBuffer.getLong(fieldOffsetInPage) != length) { - pageBuffer.putLong(fieldOffsetInPage, length); - return true; - } - return false; - } - - @Override - public boolean setTimestamp(final long timestamp) { - final int fieldOffsetInPage = recordOffsetInPage + TIMESTAMP_OFFSET; - if (pageBuffer.getLong(fieldOffsetInPage) != timestamp) { - pageBuffer.putLong(fieldOffsetInPage, timestamp); - return true; - } - return false; - } - - @Override - public boolean setContentRecordId(final int contentRecordId) { - checkValidIdField(recordId, contentRecordId, "contentRecordId"); - final int fieldOffsetInPage = recordOffsetInPage + CONTENT_REF_OFFSET; - if (pageBuffer.getInt(fieldOffsetInPage) != contentRecordId) { - pageBuffer.putInt(fieldOffsetInPage, contentRecordId); - return true; - } - return false; - } - - private void checkParentIdIsValid(final int parentId) throws IndexOutOfBoundsException { - final int recordsAllocatedSoFar = allocatedRecordsCount.get(); - if (!(NULL_ID <= parentId && parentId <= recordsAllocatedSoFar)) { - throw new IndexOutOfBoundsException( - "parentId(=" + parentId + ") is outside of allocated IDs range [0, " + recordsAllocatedSoFar + "]"); - } - } - } - - private static final class HeaderAccessor implements HeaderForUpdate { - private final @NotNull PersistentFSRecordsOverLockFreePagedStorage records; - - private HeaderAccessor(final @NotNull PersistentFSRecordsOverLockFreePagedStorage records) { this.records = records; } - - @Override - public long getTimestamp() throws IOException { - return records.getTimestamp(); - } - - @Override - public int getVersion() throws IOException { - return records.getVersion(); - } - - @Override - public int getGlobalModCount() { - return records.getGlobalModCount(); - } - - @Override - public void setVersion(final int version) throws IOException { - records.setVersion(version); - } - } - - - // ==== records operations: ================================================================ // - - - @Override - public int allocateRecord() { - int recordId = allocatedRecordsCount.incrementAndGet(); - try { - //Not only assigns new record modCount, but also ensures storage file is actually _extended_ to fit a new record. - // We calculate allocated records via file size on load, so must extend the file size to include a new record, - // otherwise newly allocated record can be lost - markRecordAsModified(recordId); - } - catch (IOException e) { - throw new UncheckedIOException("Can't ensure room for recordId=" + recordId, e); - } - return recordId; - } - - // 'one field at a time' operations - - @Override - public void setAttributeRecordId(final int recordId, - final int attributeRecordId) throws IOException { - checkValidIdField(recordId, attributeRecordId, "attributeRecordId"); - setIntField(recordId, ATTR_REF_OFFSET, attributeRecordId); - } - - @Override - public int getAttributeRecordId(final int recordId) throws IOException { - return getIntField(recordId, ATTR_REF_OFFSET); - } - - @Override - public int getParent(final int recordId) throws IOException { - return getIntField(recordId, PARENT_REF_OFFSET); - } - - @Override - public void setParent(final int recordId, - final int parentId) throws IOException { - checkParentIdIsValid(parentId); - setIntField(recordId, PARENT_REF_OFFSET, parentId); - } - - @Override - public int getNameId(final int recordId) throws IOException { - return getIntField(recordId, NAME_REF_OFFSET); - } - - @Override - public int updateNameId(final int recordId, - final int nameId) throws IOException { - PersistentFSConnection.ensureIdIsValid(nameId); - return setIntField(recordId, NAME_REF_OFFSET, nameId); - } - - @Override - public boolean setFlags(final int recordId, - final @PersistentFS.Attributes int newFlags) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - final int storedFlags = pageBuffer.getInt(recordOffsetOnPage + FLAGS_OFFSET); - final boolean reallyChanged = storedFlags != newFlags; - if (reallyChanged) { - pageBuffer.putInt(recordOffsetOnPage + FLAGS_OFFSET, newFlags); - incrementRecordVersion(pageBuffer, recordOffsetOnPage); - - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - return reallyChanged; - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public @PersistentFS.Attributes int getFlags(final int recordId) throws IOException { - return getIntField(recordId, FLAGS_OFFSET); - } - - @Override - public long getLength(final int recordId) throws IOException { - return getLongField(recordId, LENGTH_OFFSET); - } - - @Override - public boolean setLength(final int recordId, - final long newLength) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - final long storedLength = pageBuffer.getLong(recordOffsetOnPage + LENGTH_OFFSET); - final boolean reallyChanged = storedLength != newLength; - if (reallyChanged) { - pageBuffer.putLong(recordOffsetOnPage + LENGTH_OFFSET, newLength); - incrementRecordVersion(pageBuffer, recordOffsetOnPage); - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - return reallyChanged; - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public long getTimestamp(final int recordId) throws IOException { - return getLongField(recordId, TIMESTAMP_OFFSET); - } - - @Override - public boolean setTimestamp(final int recordId, - final long newTimestamp) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - final long storedTimestamp = pageBuffer.getLong(recordOffsetOnPage + TIMESTAMP_OFFSET); - final boolean reallyChanged = storedTimestamp != newTimestamp; - if (reallyChanged) { - pageBuffer.putLong(recordOffsetOnPage + TIMESTAMP_OFFSET, newTimestamp); - incrementRecordVersion(pageBuffer, recordOffsetOnPage); - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - return reallyChanged; - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public int getModCount(final int recordId) throws IOException { - return getIntField(recordId, MOD_COUNT_OFFSET); - } - - @Override - public void markRecordAsModified(final int recordId) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - incrementRecordVersion(page.rawPageBuffer(), recordOffsetOnPage); - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public int getContentRecordId(final int recordId) throws IOException { - return getIntField(recordId, CONTENT_REF_OFFSET); - } - - @Override - public boolean setContentRecordId(final int recordId, - final int newContentRef) throws IOException { - checkValidIdField(recordId, newContentRef, "contentRecordId"); - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - final int storedContentRefId = pageBuffer.getInt(recordOffsetOnPage + CONTENT_REF_OFFSET); - final boolean reallyChanged = storedContentRefId != newContentRef; - if (reallyChanged) { - pageBuffer.putInt(recordOffsetOnPage + CONTENT_REF_OFFSET, newContentRef); - incrementRecordVersion(pageBuffer, recordOffsetOnPage); - - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - return reallyChanged; - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public void cleanRecord(final int recordId) throws IOException { - checkRecordIdIsValid(recordId); - - //fill record with zeroes, by 4 bytes at once: - assert RECORD_SIZE_IN_BYTES % Integer.BYTES == 0 : "RECORD_SIZE_IN_BYTES(=" + RECORD_SIZE_IN_BYTES + ") is expected to be 32-aligned"; - final int recordSizeInInts = RECORD_SIZE_IN_BYTES / Integer.BYTES; - - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - for (int wordNo = 0; wordNo < recordSizeInInts; wordNo++) { - final int offsetOfWord = recordOffsetOnPage + wordNo * Integer.BYTES; - pageBuffer.putInt(offsetOfWord, 0); - } - - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - finally { - page.unlockPageForWrite(); - } - } - } - - @Override - public boolean processAllRecords(final @NotNull PersistentFSRecordsStorage.FsRecordProcessor processor) throws IOException { - final int recordsCount = allocatedRecordsCount.get(); - for (int recordId = MIN_VALID_ID; recordId <= recordsCount; recordId++) { - processor.process( - recordId, - getNameId(recordId), - getFlags(recordId), - getParent(recordId), - getAttributeRecordId(recordId), - getContentRecordId(recordId), - /* corrupted = */ false - ); - } - return true; - } - - - // ============== storage 'global' properties accessors: ============================= // - - @Override - public long getTimestamp() throws IOException { - return getLongHeaderField(HEADER_TIMESTAMP_OFFSET); - } - - @Override - public boolean wasClosedProperly() throws IOException { - return wasClosedProperly; - } - - @Override - public int getErrorsAccumulated() throws IOException { - return getIntHeaderField(HEADER_ERRORS_ACCUMULATED_OFFSET); - } - - @Override - public void setErrorsAccumulated(int errors) throws IOException { - setIntHeaderField(HEADER_ERRORS_ACCUMULATED_OFFSET, errors); - globalModCount.incrementAndGet(); - } - - @Override - public void setVersion(final int version) throws IOException { - setIntHeaderField(HEADER_VERSION_OFFSET, version); - setLongHeaderField(HEADER_TIMESTAMP_OFFSET, System.currentTimeMillis()); - globalModCount.incrementAndGet(); - } - - @Override - public int getVersion() throws IOException { - return getIntHeaderField(HEADER_VERSION_OFFSET); - } - - @Override - public int getGlobalModCount() { - return globalModCount.get(); - } - - - public long actualDataLength() { - final int recordsCount = allocatedRecordsCount.get() + 1; - return recordOffsetInFileUnchecked(recordsCount); - } - - @Override - public boolean isDirty() { - return storage.isDirty(); - } - - @Override - public void force() throws IOException { - if (storage.isDirty()) { - setIntHeaderField(HEADER_GLOBAL_MOD_COUNT_OFFSET, globalModCount.get()); - storage.force(); - } - } - - @Override - public void close() throws IOException { - if (!storage.isClosed()) { - setIntHeaderField(HEADER_CONNECTION_STATUS_OFFSET, SAFELY_CLOSED_STAMP); - - force(); - storage.close(); - } - } - - @Override - public void closeAndClean() throws IOException { - close(); - try { - storage.closeAndRemoveAllFiles(); - } - catch (InterruptedException e) { - throw new IOException(e); - } - } - - // =============== implementation: addressing ========================================================= // - - /** Without recordId bounds checking */ - @VisibleForTesting - long recordOffsetInFileUnchecked(final int recordId) { - //recordId is 1-based, but 0-based is more convenient for the following: - final int recordNo = recordId - 1; - - final int recordsOnHeaderPage = (pageSize - HEADER_SIZE) / RECORD_SIZE_IN_BYTES; - if (recordNo < recordsOnHeaderPage) { - return HEADER_SIZE + recordNo * (long)RECORD_SIZE_IN_BYTES; - } - - //as-if there were no header: - final int fullPages = recordNo / recordsPerPage; - final int recordsOnLastPage = recordNo % recordsPerPage; - - //header on the first page "push out" few records: - final int recordsExcessBecauseOfHeader = recordsPerPage - recordsOnHeaderPage; - - //so the last page could turn into +1 page: - final int recordsReallyOnLastPage = recordsOnLastPage + recordsExcessBecauseOfHeader; - return (long)(fullPages + recordsReallyOnLastPage / recordsPerPage) * pageSize - + (long)(recordsReallyOnLastPage % recordsPerPage) * RECORD_SIZE_IN_BYTES; - } - - private long recordOffsetInFile(final int recordId) throws IndexOutOfBoundsException { - checkRecordIdIsValid(recordId); - return recordOffsetInFileUnchecked(recordId); - } - - private void checkRecordIdIsValid(final int recordId) throws IndexOutOfBoundsException { - if (!isValidFileId(recordId)) { - final int recordsAllocatedSoFar = allocatedRecordsCount.get(); - throw new IndexOutOfBoundsException( - "recordId(=" + recordId + ") is outside of allocated IDs range (0, " + recordsAllocatedSoFar + "]"); - } - } - - private void checkParentIdIsValid(int parentId) throws IndexOutOfBoundsException { - final int recordsAllocatedSoFar = allocatedRecordsCount.get(); - if (!(NULL_ID <= parentId && parentId <= recordsAllocatedSoFar)) { - throw new IndexOutOfBoundsException( - "parentId(=" + parentId + ") is outside of allocated IDs range [0, " + recordsAllocatedSoFar + "]"); - } - } - - private static void checkValidIdField(int recordId, - int idFieldValue, - @NotNull String fieldName) { - if (idFieldValue < NULL_ID) { - throw new IllegalArgumentException("file[id: " + recordId + "]." + fieldName + "(=" + idFieldValue + ") must be >=0"); - } - } - - // =============== implementation: record field access ================================================ // - - //each access method acquires a page & acquires appropriate kind of page lock: - - private void setLongField(final int recordId, - final int fieldRelativeOffset, - final long fieldValue) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - pageBuffer.putLong(recordOffsetOnPage + fieldRelativeOffset, fieldValue); - incrementRecordVersion(pageBuffer, recordOffsetOnPage); - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - } - finally { - page.unlockPageForWrite(); - } - } - } - - private long getLongField(final int recordId, - final int fieldRelativeOffset) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ false)) { - page.lockPageForRead(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - return pageBuffer.getLong(recordOffsetOnPage + fieldRelativeOffset); - } - finally { - page.unlockPageForRead(); - } - } - } - - private int setIntField(final int recordId, - final int fieldRelativeOffset, - final int fieldValue) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ true)) { - page.lockPageForWrite(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - int previousValue = pageBuffer.getInt(recordOffsetOnPage + fieldRelativeOffset); - pageBuffer.putInt(recordOffsetOnPage + fieldRelativeOffset, fieldValue); - incrementRecordVersion(pageBuffer, recordOffsetOnPage); - page.regionModified(recordOffsetOnPage, RECORD_SIZE_IN_BYTES); - return previousValue; - } - finally { - page.unlockPageForWrite(); - } - } - } - - private int getIntField(final int recordId, - final int fieldRelativeOffset) throws IOException { - final long recordOffsetInFile = recordOffsetInFile(recordId); - final int recordOffsetOnPage = storage.toOffsetInPage(recordOffsetInFile); - try (final PageUnsafe page = (PageUnsafe)storage.pageByOffset(recordOffsetInFile, /*forWrite: */ false)) { - page.lockPageForRead(); - try { - final ByteBuffer pageBuffer = page.rawPageBuffer(); - return pageBuffer.getInt(recordOffsetOnPage + fieldRelativeOffset); - } - finally { - page.unlockPageForRead(); - } - } - } - - private void incrementRecordVersion(final @NotNull ByteBuffer pageBuffer, - final int recordOffsetOnPage) { - pageBuffer.putInt(recordOffsetOnPage + MOD_COUNT_OFFSET, globalModCount.incrementAndGet()); - } - - //============ header fields access: ============================================================ // - - private void setLongHeaderField(final @HeaderOffset int headerRelativeOffsetBytes, - final long headerValue) throws IOException { - checkHeaderOffset(headerRelativeOffsetBytes); - try (final Page page = storage.pageByOffset(headerRelativeOffsetBytes, /*forWrite: */ true)) { - page.putLong(headerRelativeOffsetBytes, headerValue); - } - } - - private long getLongHeaderField(final @HeaderOffset int headerRelativeOffsetBytes) throws IOException { - checkHeaderOffset(headerRelativeOffsetBytes); - try (final Page page = storage.pageByOffset(headerRelativeOffsetBytes, /*forWrite: */ false)) { - return page.getLong(headerRelativeOffsetBytes); - } - } - - private void setIntHeaderField(final @HeaderOffset int headerRelativeOffsetBytes, - final int headerValue) throws IOException { - checkHeaderOffset(headerRelativeOffsetBytes); - try (final Page page = storage.pageByOffset(headerRelativeOffsetBytes, /*forWrite: */ true)) { - page.putInt(headerRelativeOffsetBytes, headerValue); - } - } - - - private int getIntHeaderField(final @HeaderOffset int headerRelativeOffsetBytes) throws IOException { - checkHeaderOffset(headerRelativeOffsetBytes); - try (final Page page = storage.pageByOffset(headerRelativeOffsetBytes, /*forWrite: */ false)) { - return page.getInt(headerRelativeOffsetBytes); - } - } - - private static void checkHeaderOffset(final int headerRelativeOffset) { - if (!(0 <= headerRelativeOffset && headerRelativeOffset < HEADER_SIZE)) { - throw new IndexOutOfBoundsException( - "headerFieldOffset(=" + headerRelativeOffset + ") is outside of header [0, " + HEADER_SIZE + ") "); - } - } -} diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageFactory.kt b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageFactory.kt index 92361ef81ced..faecce663ef4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageFactory.kt +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageFactory.kt @@ -4,8 +4,7 @@ package com.intellij.openapi.vfs.newvfs.persistent import com.intellij.platform.util.io.storages.StorageFactory import com.intellij.platform.util.io.storages.mmapped.MMappedFileStorageFactory import com.intellij.util.SystemProperties -import com.intellij.util.io.* -import com.intellij.util.io.pagecache.impl.PageContentLockingStrategy +import com.intellij.util.io.StorageAlreadyInUseException import org.jetbrains.annotations.ApiStatus.Internal import org.jetbrains.annotations.VisibleForTesting import java.io.IOException @@ -83,44 +82,10 @@ abstract class PersistentFSRecordsStorageFactory(val id: Int) : StorageFactory

can't create PersistentFSRecordsOverLockFreePagedStorage if FilePageCacheLockFree is disabled") - } - - val pagedStorage = PagedFileStorageWithRWLockedPageContent( - storagePath, - PERSISTENT_FS_STORAGE_CONTEXT_RW, - pageSize, - IOUtil.useNativeByteOrderForByteBuffers(), - PageContentLockingStrategy.LOCK_PER_PAGE - ) - return IOUtil.wrapSafely( - pagedStorage) { - PersistentFSRecordsOverLockFreePagedStorage(it) - } - } - } - /** For testing/benchmarking: serves as a reference point. Not a prod-level implementation! */ data class InMemory(val maxRecordsCount: Int = (1 shl 24)) : PersistentFSRecordsStorageFactory(id = 2) { @Suppress("TestOnlyProblems") - override fun open(storagePath: Path) = PersistentFSRecordsOverInMemoryStorage(storagePath, maxRecordsCount) + override fun open(storagePath: Path): PersistentFSRecordsOverInMemoryStorage = PersistentFSRecordsOverInMemoryStorage(storagePath, maxRecordsCount) } companion object { @@ -146,7 +111,6 @@ abstract class PersistentFSRecordsStorageFactory(val id: Int) : StorageFactory

OverLockFreeFileCache() "IN_MEMORY" -> InMemory() else -> OverMMappedFile() } diff --git a/platform/platform-tests/benchmarks/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSStoragesBenchmarks.java b/platform/platform-tests/benchmarks/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSStoragesBenchmarks.java index 6060fbef9484..356fa358359a 100644 --- a/platform/platform-tests/benchmarks/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSStoragesBenchmarks.java +++ b/platform/platform-tests/benchmarks/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSStoragesBenchmarks.java @@ -2,10 +2,7 @@ package com.intellij.openapi.vfs.newvfs.persistent; import com.intellij.openapi.util.IntRef; -import com.intellij.util.io.PagedFileStorageWithRWLockedPageContent; -import com.intellij.util.io.StorageLockContext; import com.intellij.platform.util.io.storages.mmapped.MMappedFileStorageFactory; -import com.intellij.util.io.pagecache.impl.PageContentLockingStrategy; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; @@ -43,8 +40,6 @@ public class PersistentFSStoragesBenchmarks { //@Param public static final int RECORDS_COUNT = 1 << 22; - public static final StorageLockContext CONTEXT = new StorageLockContext(true, true, true); - private static final Unsafe UNSAFE; private static final long BYTE_BUFFER_ADDRESS_FIELD_OFFSET; @@ -203,33 +198,6 @@ public class PersistentFSStoragesBenchmarks { } } - @State(Scope.Benchmark) - public static class FSRecordsOverLockFreeFPCState { - - private PersistentFSRecordsOverLockFreePagedStorage storage; - - @Setup - public void setup(FileState fileState) throws IOException { - final int pageSize = 1 << 20; - storage = new PersistentFSRecordsOverLockFreePagedStorage( - new PagedFileStorageWithRWLockedPageContent( - fileState.file, - CONTEXT, - pageSize, - PageContentLockingStrategy.LOCK_PER_PAGE - ) - ); - for (int i = 0; i < RECORDS_COUNT; i++) { - storage.allocateRecord(); - } - } - - @TearDown - public void close() throws IOException { - storage.close(); - } - } - @State(Scope.Benchmark) public static class FSRecordsOverMMappedFileState { @@ -472,14 +440,6 @@ public class PersistentFSStoragesBenchmarks { return fsRecords_randomReadByField(it, storage); } - @Benchmark - public int FSRecords_OverNewFPC_RandomReadByField(final RecordIterationState it, - final FSRecordsOverLockFreeFPCState state) throws IOException { - final PersistentFSRecordsStorage storage = state.storage; - - return fsRecords_randomReadByField(it, storage); - } - @Benchmark public int FSRecords_MemoryMapped_RandomReadByRecord(final RecordIterationState it, final FSRecordsOverMMappedFileState state) throws IOException { @@ -488,14 +448,6 @@ public class PersistentFSStoragesBenchmarks { return fsRecords_RandomReadByRecord(it, storage); } - @Benchmark - public int FSRecords_OverNewFPC_RandomReadByRecord(final RecordIterationState it, - final FSRecordsOverLockFreeFPCState state) throws IOException { - final IPersistentFSRecordsStorage storage = state.storage; - - return fsRecords_RandomReadByRecord(it, storage); - } - private static int fsRecords_randomReadByField(final RecordIterationState it, final PersistentFSRecordsStorage storage) throws IOException { final int recordId = it.nextRandomRecordIndex(); @@ -667,14 +619,6 @@ public class PersistentFSStoragesBenchmarks { fsRecords_randomWriteByField(it, storage); } - @Benchmark - public void FSRecords_OverNewFPC_RandomWriteByField(final RecordIterationState it, - final FSRecordsOverLockFreeFPCState state) throws IOException { - final PersistentFSRecordsStorage storage = state.storage; - - fsRecords_randomWriteByField(it, storage); - } - @Benchmark public void FSRecords_MemoryMapped_RandomWriteByRecord(final RecordIterationState it, final FSRecordsOverMMappedFileState state) throws IOException { @@ -683,14 +627,6 @@ public class PersistentFSStoragesBenchmarks { fsRecords_randomWriteByRecord(it, storage); } - @Benchmark - public void FSRecords_OverNewFPC_RandomWriteByRecord(final RecordIterationState it, - final FSRecordsOverLockFreeFPCState state) throws IOException { - final IPersistentFSRecordsStorage storage = state.storage; - - fsRecords_randomWriteByRecord(it, storage); - } - private static void fsRecords_randomWriteByField(final RecordIterationState it, final PersistentFSRecordsStorage storage) throws IOException { final int recordId = it.nextRandomRecordIndex(); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageOverLockFreePagedStorageTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageOverLockFreePagedStorageTest.java deleted file mode 100644 index ca8c2f3196cc..000000000000 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSRecordsStorageOverLockFreePagedStorageTest.java +++ /dev/null @@ -1,128 +0,0 @@ -// 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.openapi.vfs.newvfs.persistent; - - -import com.intellij.util.io.PageCacheUtils; -import org.jetbrains.annotations.NotNull; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.concurrent.ThreadLocalRandom; - -import static com.intellij.openapi.vfs.newvfs.persistent.PersistentFSRecordsOverLockFreePagedStorage.NULL_ID; -import static com.intellij.openapi.vfs.newvfs.persistent.PersistentFSRecordsOverLockFreePagedStorage.RECORD_SIZE_IN_BYTES; -import static org.junit.Assert.*; -import static org.junit.Assume.assumeTrue; - -@RunWith(Parameterized.class) -public class PersistentFSRecordsStorageOverLockFreePagedStorageTest - extends PersistentFSRecordsStorageTestBase { - - @Parameterized.Parameters(name = "{index}: {0}") - public static UpdateAPIMethod[] METHODS_TO_TEST() { - return new UpdateAPIMethod[]{ - DEFAULT_API_UPDATE_METHOD, - MODERN_API_UPDATE_METHOD - }; - } - - public static final int MAX_RECORDS_TO_INSERT = 1 << 22; - - private static final int PAGE_SIZE = PageCacheUtils.DEFAULT_PAGE_SIZE; - - - public PersistentFSRecordsStorageOverLockFreePagedStorageTest(final UpdateAPIMethod updateMethodToTest) { super(MAX_RECORDS_TO_INSERT, updateMethodToTest); } - - @BeforeClass - public static void beforeClass() throws Exception { - assumeTrue( - "LockFree FilePageCache must be enabled: see PageCacheUtils.LOCK_FREE_PAGE_CACHE_ENABLED", - PageCacheUtils.LOCK_FREE_PAGE_CACHE_ENABLED - ); - } - - @NotNull - @Override - protected PersistentFSRecordsOverLockFreePagedStorage openStorage(final Path storagePath) throws IOException { - return new PersistentFSRecordsStorageFactory.OverLockFreeFileCache().open(storagePath); - } - - @Test - public void recordAreAlwaysAlignedFullyOnSinglePage() { - final int enoughRecords = (PAGE_SIZE / RECORD_SIZE_IN_BYTES) * 16; - - for (int recordId = 0; recordId < enoughRecords; recordId++) { - final long recordOffsetInFile = storage.recordOffsetInFileUnchecked(recordId); - final long recordEndOffsetInFile = recordOffsetInFile + RECORD_SIZE_IN_BYTES - 1; - assertEquals( - "Record(#" + recordId + ", offset: " + recordOffsetInFile + ") must start and end on a same page", - recordOffsetInFile / PAGE_SIZE, - recordEndOffsetInFile / PAGE_SIZE - ); - } - } - - @Test - public void recordOffsetCalculatedByStorageIsConsistentWithPlainCalculation() { - final int enoughRecords = (PAGE_SIZE / RECORD_SIZE_IN_BYTES) * 16; - - long expectedRecordOffsetInFile = PersistentFSRecordsOverLockFreePagedStorage.HEADER_SIZE; - for (int recordId = NULL_ID + 1; recordId < enoughRecords; recordId++) { - - final long recordOffsetInFile = storage.recordOffsetInFileUnchecked(recordId); - assertEquals("recordOffset(recordId:" + recordId + ") must be " + expectedRecordOffsetInFile, - expectedRecordOffsetInFile, - recordOffsetInFile - ); - - expectedRecordOffsetInFile += RECORD_SIZE_IN_BYTES; - if (PAGE_SIZE - (expectedRecordOffsetInFile % PAGE_SIZE) < RECORD_SIZE_IN_BYTES) { - expectedRecordOffsetInFile = (expectedRecordOffsetInFile / PAGE_SIZE + 1) * PAGE_SIZE; - } - } - } - - @Test - public void loadRecordsCount_IsConsistentWith_recordOffsetInFile() throws IOException { - final int enoughRecords = (PAGE_SIZE / RECORD_SIZE_IN_BYTES) * 16; - - for (int recordId = NULL_ID + 1; recordId < enoughRecords; recordId++) { - final long recordOffsetInFile = storage.recordOffsetInFileUnchecked(recordId); - final int calculatedRecordNo = storage.loadRecordsCount(recordOffsetInFile); - final int expectedRecordNo = recordId - 1; - assertEquals("storage(" + recordOffsetInFile + "b) must contain " + expectedRecordNo + " records", - expectedRecordNo, - calculatedRecordNo - ); - } - } - - @Test - public void loadRecordsCount_ThrowsIOException_IfUnEvenNumberOfRecordsFound() throws IOException { - //RC: method is very slow, so use 1 random excess for each record, instead of iterating through - // each excess: [1..RECORD_SIZE_IN_BYTES) on each record - final int enoughRecords = (PAGE_SIZE / RECORD_SIZE_IN_BYTES) * 16; - - for (int recordId = NULL_ID + 1; recordId < enoughRecords; recordId++) { - final long recordOffsetInFile = storage.recordOffsetInFileUnchecked(recordId); - final int excessBytes = ThreadLocalRandom.current().nextInt(1, RECORD_SIZE_IN_BYTES); - final long storageSizeWithExcess = recordOffsetInFile + excessBytes; - try { - storage.loadRecordsCount(storageSizeWithExcess); - fail(recordOffsetInFile + "b + " + excessBytes + "b: excess contains non-integer records " + - "-> must throw 'corrupted' exception"); - } - catch (IOException e) { - final String message = e.getMessage(); - assertTrue( - "Exception [" + message + "] must contain 'is corrupted' message", - message.contains("is corrupted") - ); - } - } - } -} \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/VFSInitializationTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/VFSInitializationTest.java index c98de65f19ab..299f5d8f2daa 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/VFSInitializationTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/newvfs/persistent/VFSInitializationTest.java @@ -3,13 +3,11 @@ package com.intellij.openapi.vfs.newvfs.persistent; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.newvfs.FileAttribute; -import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSRecordsStorageFactory.OverLockFreeFileCache; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSRecordsStorageFactory.OverMMappedFile; import com.intellij.openapi.vfs.newvfs.persistent.recovery.VFSInitializationResult; import com.intellij.openapi.vfs.newvfs.persistent.recovery.VFSRecoverer; import com.intellij.platform.util.io.storages.StorageTestingUtils; import com.intellij.testFramework.TemporaryDirectory; -import com.intellij.util.io.PageCacheUtils; import org.jetbrains.annotations.NotNull; import org.junit.After; import org.junit.Rule; @@ -198,10 +196,7 @@ public class VFSInitializationTest { //skip IN_MEMORY impl, since it is not really persistent - //skip OVER_LOCK_FREE_FILE_CACHE impl if !LOCK_FREE_PAGE_CACHE_ENABLED (fails otherwise) - List allStorageKinds = PageCacheUtils.LOCK_FREE_PAGE_CACHE_ENABLED ? - List.of(new OverLockFreeFileCache(), new OverMMappedFile()) : - List.of(new OverMMappedFile()); + List allStorageKinds = List.of(new OverMMappedFile()); List filesNotLeadingToVFSRebuild = new ArrayList<>(); for (PersistentFSRecordsStorageFactory storageKind : allStorageKinds) { @@ -272,10 +267,7 @@ public class VFSInitializationTest { @Test public void VFS_isRebuilt_OnlyIf_ImplementationVersionChanged() throws Exception { //skip IN_MEMORY impl, since it is not really persistent - //skip OVER_LOCK_FREE_FILE_CACHE impl if !LOCK_FREE_PAGE_CACHE_ENABLED (will fail) - final List allKinds = PageCacheUtils.LOCK_FREE_PAGE_CACHE_ENABLED ? - List.of(new OverLockFreeFileCache(), new OverMMappedFile()) : - List.of(new OverMMappedFile()); + final List allKinds = List.of(new OverMMappedFile()); //check all combinations (from->to) of implementations: for (PersistentFSRecordsStorageFactory kindBefore : allKinds) {