mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Revert "index: do not copy prebuilt indexes; attempt #2 WEB-45822"
This reverts commit a676a327 GitOrigin-RevId: 750251d21e6b6f4b0d3a4c0c5737d68ac4347d16
This commit is contained in:
committed by
intellij-monorepo-bot
parent
28781682ba
commit
f7d00e0193
@@ -6,6 +6,7 @@ import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.psi.stubs.FileContentHashing
|
||||
import com.intellij.psi.stubs.HashCodeDescriptor
|
||||
@@ -15,6 +16,7 @@ import com.intellij.util.indexing.FileContent
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.File
|
||||
import java.io.FileFilter
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.withLock
|
||||
@@ -46,10 +48,15 @@ abstract class PrebuiltIndexProvider<Value>: Disposable {
|
||||
internal fun init() {
|
||||
myOpenCloseLock.writeLock().withLock {
|
||||
if (USE_PREBUILT_INDEX) {
|
||||
val indexesRoot = findPrebuiltIndicesRoot()
|
||||
var indexesRoot = findPrebuiltIndicesRoot()
|
||||
try {
|
||||
if (indexesRoot != null && indexesRoot.exists()) {
|
||||
// we should copy prebuilt indexes to a writable folder
|
||||
indexesRoot = copyPrebuiltIndicesToIndexRoot(indexesRoot)
|
||||
// otherwise we can get access denied error, because persistent hash map opens file for read and write
|
||||
|
||||
myPrebuiltIndexStorage = openIndexStorage(indexesRoot)
|
||||
|
||||
LOG.info("Using prebuilt $indexName from " + myPrebuiltIndexStorage?.baseFile?.toAbsolutePath())
|
||||
}
|
||||
else {
|
||||
@@ -103,6 +110,15 @@ abstract class PrebuiltIndexProvider<Value>: Disposable {
|
||||
|
||||
protected abstract fun getIndexRoot(): File
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun copyPrebuiltIndicesToIndexRoot(prebuiltIndicesRoot: File): File {
|
||||
val indexRoot = getIndexRoot()
|
||||
|
||||
FileUtil.copyDir(prebuiltIndicesRoot, indexRoot, FileFilter { f -> f.name.startsWith(indexName) })
|
||||
|
||||
return indexRoot
|
||||
}
|
||||
|
||||
private fun findPrebuiltIndicesRoot(): File? {
|
||||
val path: String? = System.getProperty(PrebuiltStubsProviderBase.PREBUILT_INDICES_PATH_PROPERTY)
|
||||
if (path != null && File(path).exists()) {
|
||||
|
||||
@@ -106,7 +106,7 @@ abstract class PrebuiltStubsProviderBase : PrebuiltIndexProvider<SerializedStubT
|
||||
}
|
||||
else {
|
||||
mySerializationManager = SerializationManagerImpl(File(indexesRoot, "$indexName.names").toPath(), true)
|
||||
Disposer.register(ApplicationManager.getApplication(), mySerializationManager)
|
||||
Disposer.register(ApplicationManager.getApplication(), mySerializationManager!!)
|
||||
return super.openIndexStorage(indexesRoot)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,104 +160,91 @@ public class PersistentHashMap<Key, Value> implements AppendablePersistentMap<Ke
|
||||
@NotNull PersistentHashMapValueStorage.CreationTimeOptions options) throws IOException {
|
||||
// it's important to initialize it as early as possible
|
||||
myIsReadOnly = isReadOnly();
|
||||
Boolean oldThreadLocalReadOnlyStatus = null;
|
||||
if (myIsReadOnly) {
|
||||
options = options.setReadOnly();
|
||||
oldThreadLocalReadOnlyStatus = PersistentHashMapValueStorage.CreationTimeOptions.READONLY.get();
|
||||
PersistentHashMapValueStorage.CreationTimeOptions.READONLY.set(Boolean.TRUE);
|
||||
}
|
||||
if (myIsReadOnly) options = options.setReadOnly();
|
||||
|
||||
myEnumerator = PersistentEnumeratorDelegate.createDefaultEnumerator(checkDataFiles(file),
|
||||
keyDescriptor,
|
||||
initialSize,
|
||||
lockContext,
|
||||
modifyVersionDependingOnOptions(version, options));
|
||||
|
||||
myStorageFile = file;
|
||||
myKeyDescriptor = keyDescriptor;
|
||||
|
||||
final PersistentEnumeratorBase.@NotNull RecordBufferHandler<PersistentEnumeratorBase<?>> recordHandler = myEnumerator.getRecordHandler();
|
||||
myParentValueRefOffset = recordHandler.getRecordBuffer(myEnumerator).length;
|
||||
myIntMapping = valueExternalizer instanceof IntInlineKeyDescriptor && wantNonNegativeIntegralValues();
|
||||
myDirectlyStoreLongFileOffsetMode = keyDescriptor instanceof InlineKeyDescriptor && myEnumerator instanceof PersistentBTreeEnumerator;
|
||||
|
||||
myRecordBuffer = ThreadLocal
|
||||
.withInitial(() -> myDirectlyStoreLongFileOffsetMode ? ArrayUtilRt.EMPTY_BYTE_ARRAY : new byte[myParentValueRefOffset + 8]);
|
||||
mySmallRecordBuffer = ThreadLocal
|
||||
.withInitial(() -> myDirectlyStoreLongFileOffsetMode ? ArrayUtilRt.EMPTY_BYTE_ARRAY : new byte[myParentValueRefOffset + 4]);
|
||||
|
||||
myEnumerator.setRecordHandler(new PersistentEnumeratorBase.RecordBufferHandler<PersistentEnumeratorBase<?>>() {
|
||||
@Override
|
||||
int recordWriteOffset(PersistentEnumeratorBase<?> enumerator, byte[] buf) {
|
||||
return recordHandler.recordWriteOffset(enumerator, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
byte @NotNull [] getRecordBuffer(PersistentEnumeratorBase<?> enumerator) {
|
||||
return myIntAddressForNewRecord ? mySmallRecordBuffer.get() : myRecordBuffer.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
void setupRecord(PersistentEnumeratorBase enumerator, int hashCode, int dataOffset, byte @NotNull [] buf) {
|
||||
recordHandler.setupRecord(enumerator, hashCode, dataOffset, buf);
|
||||
for (int i = myParentValueRefOffset; i < buf.length; i++) {
|
||||
buf[i] = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myEnumerator.setMarkCleanCallback(
|
||||
new Flushable() {
|
||||
@Override
|
||||
public void flush() {
|
||||
myEnumerator.putMetaData(myLiveAndGarbageKeysCounter);
|
||||
myEnumerator.putMetaData2(myLargeIndexWatermarkId | ((long)myReadCompactionGarbageSize << 32));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (myDoTrace) LOG.info("Opened " + file);
|
||||
try {
|
||||
myEnumerator = PersistentEnumeratorDelegate.createDefaultEnumerator(checkDataFiles(file),
|
||||
keyDescriptor,
|
||||
initialSize,
|
||||
lockContext,
|
||||
modifyVersionDependingOnOptions(version, options));
|
||||
myValueExternalizer = valueExternalizer;
|
||||
myValueStorage = myIntMapping ? null : new PersistentHashMapValueStorage(getDataFile(file), options);
|
||||
myAppendCache = myIntMapping ? null : createAppendCache(keyDescriptor);
|
||||
myAppendCacheFlusher = myIntMapping ? null : LowMemoryWatcher.register(this::dropMemoryCaches);
|
||||
myLiveAndGarbageKeysCounter = myEnumerator.getMetaData();
|
||||
long data2 = myEnumerator.getMetaData2();
|
||||
myLargeIndexWatermarkId = (int)(data2 & DEAD_KEY_NUMBER_MASK);
|
||||
myReadCompactionGarbageSize = (int)(data2 >>> 32);
|
||||
myCanReEnumerate = myEnumerator.canReEnumerate();
|
||||
|
||||
myStorageFile = file;
|
||||
myKeyDescriptor = keyDescriptor;
|
||||
|
||||
final PersistentEnumeratorBase.@NotNull RecordBufferHandler<PersistentEnumeratorBase<?>> recordHandler =
|
||||
myEnumerator.getRecordHandler();
|
||||
myParentValueRefOffset = recordHandler.getRecordBuffer(myEnumerator).length;
|
||||
myIntMapping = valueExternalizer instanceof IntInlineKeyDescriptor && wantNonNegativeIntegralValues();
|
||||
myDirectlyStoreLongFileOffsetMode = keyDescriptor instanceof InlineKeyDescriptor && myEnumerator instanceof PersistentBTreeEnumerator;
|
||||
|
||||
myRecordBuffer = ThreadLocal
|
||||
.withInitial(() -> myDirectlyStoreLongFileOffsetMode ? ArrayUtilRt.EMPTY_BYTE_ARRAY : new byte[myParentValueRefOffset + 8]);
|
||||
mySmallRecordBuffer = ThreadLocal
|
||||
.withInitial(() -> myDirectlyStoreLongFileOffsetMode ? ArrayUtilRt.EMPTY_BYTE_ARRAY : new byte[myParentValueRefOffset + 4]);
|
||||
|
||||
myEnumerator.setRecordHandler(new PersistentEnumeratorBase.RecordBufferHandler<PersistentEnumeratorBase<?>>() {
|
||||
@Override
|
||||
int recordWriteOffset(PersistentEnumeratorBase<?> enumerator, byte[] buf) {
|
||||
return recordHandler.recordWriteOffset(enumerator, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
byte @NotNull [] getRecordBuffer(PersistentEnumeratorBase<?> enumerator) {
|
||||
return myIntAddressForNewRecord ? mySmallRecordBuffer.get() : myRecordBuffer.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
void setupRecord(PersistentEnumeratorBase enumerator, int hashCode, int dataOffset, byte @NotNull [] buf) {
|
||||
recordHandler.setupRecord(enumerator, hashCode, dataOffset, buf);
|
||||
for (int i = myParentValueRefOffset; i < buf.length; i++) {
|
||||
buf[i] = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myEnumerator.setMarkCleanCallback(
|
||||
new Flushable() {
|
||||
@Override
|
||||
public void flush() {
|
||||
myEnumerator.putMetaData(myLiveAndGarbageKeysCounter);
|
||||
myEnumerator.putMetaData2(myLargeIndexWatermarkId | ((long)myReadCompactionGarbageSize << 32));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (myDoTrace) LOG.info("Opened " + file);
|
||||
try {
|
||||
myValueExternalizer = valueExternalizer;
|
||||
myValueStorage = myIntMapping ? null : new PersistentHashMapValueStorage(getDataFile(file), options);
|
||||
myAppendCache = myIntMapping ? null : createAppendCache(keyDescriptor);
|
||||
myAppendCacheFlusher = myIntMapping ? null : LowMemoryWatcher.register(this::dropMemoryCaches);
|
||||
myLiveAndGarbageKeysCounter = myEnumerator.getMetaData();
|
||||
long data2 = myEnumerator.getMetaData2();
|
||||
myLargeIndexWatermarkId = (int)(data2 & DEAD_KEY_NUMBER_MASK);
|
||||
myReadCompactionGarbageSize = (int)(data2 >>> 32);
|
||||
myCanReEnumerate = myEnumerator.canReEnumerate();
|
||||
|
||||
if (!options.isReadOnly() && makesSenseToCompact()) {
|
||||
compact();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
try {
|
||||
// attempt to close already opened resources
|
||||
close();
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
}
|
||||
throw e; // rethrow
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
try {
|
||||
// attempt to close already opened resources
|
||||
close();
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
}
|
||||
throw new PersistentEnumerator.CorruptedException(file);
|
||||
if (!options.isReadOnly() && makesSenseToCompact()) {
|
||||
compact();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (myIsReadOnly) {
|
||||
PersistentHashMapValueStorage.CreationTimeOptions.READONLY.set(oldThreadLocalReadOnlyStatus);
|
||||
catch (IOException e) {
|
||||
try {
|
||||
// attempt to close already opened resources
|
||||
close();
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
}
|
||||
throw e; // rethrow
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
try {
|
||||
// attempt to close already opened resources
|
||||
close();
|
||||
}
|
||||
catch (Throwable ignored) {
|
||||
}
|
||||
throw new PersistentEnumerator.CorruptedException(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ public class ReadWriteDirectBufferWrapper extends DirectBufferWrapper {
|
||||
|
||||
static class FileContext implements AutoCloseable {
|
||||
private final FileChannel myFile;
|
||||
private final boolean myReadOnly;
|
||||
|
||||
FileContext(Path path, boolean readOnly) throws IOException {
|
||||
myFile = FileUtilRt.doIOOperation(new FileUtilRt.RepeatableIOOperation<FileChannel, IOException>() {
|
||||
@@ -52,7 +53,7 @@ public class ReadWriteDirectBufferWrapper extends DirectBufferWrapper {
|
||||
@Override
|
||||
public FileChannel execute(boolean finalAttempt) throws IOException {
|
||||
try {
|
||||
Set<StandardOpenOption> options = readOnly
|
||||
Set<StandardOpenOption> options = myReadOnly
|
||||
? EnumSet.of(StandardOpenOption.READ)
|
||||
: EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
|
||||
return unInterruptible(FileChannel.open(path, options));
|
||||
@@ -73,6 +74,7 @@ public class ReadWriteDirectBufferWrapper extends DirectBufferWrapper {
|
||||
}
|
||||
}
|
||||
});
|
||||
myReadOnly = readOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user