mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
api for (re)creating PHM that rewrites it if it is broken (IDEA-115334)
This commit is contained in:
+22
-18
@@ -5,10 +5,11 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.indexing.*;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.IOUtil;
|
||||
import com.intellij.util.io.KeyDescriptor;
|
||||
import com.intellij.util.io.PersistentHashMap;
|
||||
import org.jetbrains.asm4.tree.ClassNode;
|
||||
@@ -51,24 +52,32 @@ public abstract class CompilerOutputBaseIndex<K, V> {
|
||||
if (!IndexInfrastructure.getIndexRootDir(indexId).exists()) {
|
||||
rewriteIndex.set(true);
|
||||
}
|
||||
final File storageFile = IndexInfrastructure.getStorageFile(indexId);
|
||||
final File storageFile = getStorageFile(indexId);
|
||||
final MapIndexStorage<K, V> indexStorage = new MapIndexStorage<K, V>(storageFile, myKeyDescriptor, myValueExternalizer, 1024);
|
||||
index = new MapReduceIndex<K, V, ClassNode>(indexId, getIndexer(), indexStorage);
|
||||
index.setInputIdToDataKeysIndex(new Factory<PersistentHashMap<Integer, Collection<K>>>() {
|
||||
@Override
|
||||
public PersistentHashMap<Integer, Collection<K>> create() {
|
||||
Exception failCause = null;
|
||||
for (int attempts = 0; attempts < 2; attempts++) {
|
||||
try {
|
||||
return FileBasedIndexImpl.createIdToDataKeysIndex(indexId, myKeyDescriptor, new MemoryIndexStorage<K, V>(indexStorage));
|
||||
}
|
||||
catch (IOException e) {
|
||||
failCause = e;
|
||||
FileUtil.delete(IndexInfrastructure.getInputIndexStorageFile(getIndexId()));
|
||||
rewriteIndex.set(true);
|
||||
}
|
||||
try {
|
||||
return IOUtil.openCleanOrResetBroken(
|
||||
new ThrowableComputable<PersistentHashMap<Integer, Collection<K>>, IOException>() {
|
||||
@Override
|
||||
public PersistentHashMap<Integer, Collection<K>> compute() throws IOException {
|
||||
return FileBasedIndexImpl.createIdToDataKeysIndex(indexId, myKeyDescriptor, new MemoryIndexStorage<K, V>(indexStorage));
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
FileUtil.delete(getInputIndexStorageFile(getIndexId()));
|
||||
rewriteIndex.set(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("couldn't create index", e);
|
||||
}
|
||||
throw new RuntimeException("couldn't create index", failCause);
|
||||
}
|
||||
});
|
||||
final File versionFile = getVersionFile(indexId);
|
||||
@@ -144,9 +153,4 @@ public abstract class CompilerOutputBaseIndex<K, V> {
|
||||
protected final ID<K, V> generateIndexId(final String indexName) {
|
||||
return CompilerOutputIndexUtil.generateIndexId(indexName, myProject);
|
||||
}
|
||||
|
||||
protected final ID<K, V> generateIndexId(final Class aClass) {
|
||||
final String className = StringUtil.getShortName(aClass);
|
||||
return generateIndexId(StringUtil.trimEnd(className, "Index"));
|
||||
}
|
||||
}
|
||||
|
||||
+38
-28
@@ -12,6 +12,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.registry.RegistryValue;
|
||||
import com.intellij.openapi.util.registry.RegistryValueListener;
|
||||
@@ -153,16 +154,19 @@ public class CompilerOutputIndexer extends AbstractProjectComponent {
|
||||
private void doEnable() {
|
||||
if (myInitialized.compareAndSet(false, true)) {
|
||||
initTimestampIndex();
|
||||
File storageFile =
|
||||
final File storageFile =
|
||||
IndexInfrastructure.getStorageFile(CompilerOutputIndexUtil.generateIndexId("compilerOutputIndexFileId.enum", myProject));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
try {
|
||||
myFileEnumerator = new PersistentEnumeratorDelegate<String>(storageFile, new EnumeratorStringDescriptor(), 2048);
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (i == 1) throw new RuntimeException(e);
|
||||
IOUtil.deleteAllFilesStartingWith(storageFile);
|
||||
}
|
||||
|
||||
try {
|
||||
myFileEnumerator = IOUtil.openCleanOrResetBroken(new ThrowableComputable<PersistentEnumeratorDelegate<String>, IOException>() {
|
||||
@Override
|
||||
public PersistentEnumeratorDelegate<String> compute() throws IOException {
|
||||
return new PersistentEnumeratorDelegate<String>(storageFile, new EnumeratorStringDescriptor(), 2048);
|
||||
}
|
||||
}, storageFile);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
CompilerManager.getInstance(myProject).addCompilationStatusListener(new CompilationStatusAdapter() {
|
||||
@Override
|
||||
@@ -184,29 +188,35 @@ public class CompilerOutputIndexer extends AbstractProjectComponent {
|
||||
}
|
||||
|
||||
private void initTimestampIndex() {
|
||||
for (int attempts = 0; attempts < 2; attempts++) {
|
||||
try {
|
||||
myFileTimestampsIndex = new PersistentHashMap<String, Long>(IndexInfrastructure.getStorageFile(getFileTimestampsIndexId()),
|
||||
new EnumeratorStringDescriptor(), new DataExternalizer<Long>() {
|
||||
final File storageFile = IndexInfrastructure.getStorageFile(getFileTimestampsIndexId());
|
||||
try {
|
||||
myFileTimestampsIndex = IOUtil.openCleanOrResetBroken(
|
||||
new ThrowableComputable<PersistentHashMap<String, Long>, IOException>() {
|
||||
@Override
|
||||
public void save(final DataOutput out, final Long value) throws IOException {
|
||||
out.writeLong(value);
|
||||
}
|
||||
public PersistentHashMap<String, Long> compute() throws IOException {
|
||||
return new PersistentHashMap<String, Long>(storageFile,
|
||||
new EnumeratorStringDescriptor(), new DataExternalizer<Long>() {
|
||||
@Override
|
||||
public void save(final DataOutput out, final Long value) throws IOException {
|
||||
out.writeLong(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long read(final DataInput in) throws IOException {
|
||||
return in.readLong();
|
||||
@Override
|
||||
public Long read(final DataInput in) throws IOException {
|
||||
return in.readLong();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (IOException e) {
|
||||
FileUtil.delete(IndexInfrastructure.getIndexRootDir(getFileTimestampsIndexId()));
|
||||
}
|
||||
if (myFileTimestampsIndex != null) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
FileUtil.delete(IndexInfrastructure.getIndexRootDir(getFileTimestampsIndexId()));
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Timestamps index not initialized", ex);
|
||||
}
|
||||
throw new RuntimeException("Timestamps index not initialized");
|
||||
}
|
||||
|
||||
public void reindex(final FileVisitorService visitorService, final @NotNull ProgressIndicator indicator) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.util.io;
|
||||
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.util.SystemProperties;
|
||||
@@ -184,4 +185,26 @@ public class IOUtil {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T openCleanOrResetBroken(@NotNull ThrowableComputable<T, IOException> factoryComputable, final File file) throws IOException {
|
||||
return openCleanOrResetBroken(factoryComputable, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
deleteAllFilesStartingWith(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> T openCleanOrResetBroken(@NotNull ThrowableComputable<T, IOException> factoryComputable, Runnable cleanupCallback) throws IOException {
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
try {
|
||||
return factoryComputable.compute();
|
||||
} catch (IOException ex) {
|
||||
if (i == 1) throw ex;
|
||||
cleanupCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.idea.maven.indices;
|
||||
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.io.*;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -617,8 +618,13 @@ public class MavenIndex {
|
||||
}
|
||||
}
|
||||
|
||||
private PersistentHashMap<String, Set<String>> createPersistentMap(File f) throws IOException {
|
||||
return new PersistentHashMap<String, Set<String>>(f, new EnumeratorStringDescriptor(), new SetDescriptor());
|
||||
private PersistentHashMap<String, Set<String>> createPersistentMap(final File f) throws IOException {
|
||||
return IOUtil.openCleanOrResetBroken(new ThrowableComputable<PersistentHashMap<String, Set<String>>, IOException>() {
|
||||
@Override
|
||||
public PersistentHashMap<String, Set<String>> compute() throws IOException {
|
||||
return new PersistentHashMap<String, Set<String>>(f, new EnumeratorStringDescriptor(), new SetDescriptor());
|
||||
}
|
||||
}, f);
|
||||
}
|
||||
|
||||
public void close(boolean releaseIndexContext) throws MavenIndexException {
|
||||
|
||||
Reference in New Issue
Block a user