diff --git a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java index cc315b646281..1c0231b97b11 100644 --- a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java +++ b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputBaseIndex.java @@ -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 { if (!IndexInfrastructure.getIndexRootDir(indexId).exists()) { rewriteIndex.set(true); } - final File storageFile = IndexInfrastructure.getStorageFile(indexId); + final File storageFile = getStorageFile(indexId); final MapIndexStorage indexStorage = new MapIndexStorage(storageFile, myKeyDescriptor, myValueExternalizer, 1024); index = new MapReduceIndex(indexId, getIndexer(), indexStorage); index.setInputIdToDataKeysIndex(new Factory>>() { @Override public PersistentHashMap> create() { - Exception failCause = null; - for (int attempts = 0; attempts < 2; attempts++) { - try { - return FileBasedIndexImpl.createIdToDataKeysIndex(indexId, myKeyDescriptor, new MemoryIndexStorage(indexStorage)); - } - catch (IOException e) { - failCause = e; - FileUtil.delete(IndexInfrastructure.getInputIndexStorageFile(getIndexId())); - rewriteIndex.set(true); - } + try { + return IOUtil.openCleanOrResetBroken( + new ThrowableComputable>, IOException>() { + @Override + public PersistentHashMap> compute() throws IOException { + return FileBasedIndexImpl.createIdToDataKeysIndex(indexId, myKeyDescriptor, new MemoryIndexStorage(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 { protected final ID generateIndexId(final String indexName) { return CompilerOutputIndexUtil.generateIndexId(indexName, myProject); } - - protected final ID generateIndexId(final Class aClass) { - final String className = StringUtil.getShortName(aClass); - return generateIndexId(StringUtil.trimEnd(className, "Index")); - } } diff --git a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java index 3c23306b8b53..fed4c02502b0 100644 --- a/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java +++ b/java/java-impl/src/com/intellij/compilerOutputIndex/api/indexer/CompilerOutputIndexer.java @@ -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(storageFile, new EnumeratorStringDescriptor(), 2048); - } - catch (IOException e) { - if (i == 1) throw new RuntimeException(e); - IOUtil.deleteAllFilesStartingWith(storageFile); - } + + try { + myFileEnumerator = IOUtil.openCleanOrResetBroken(new ThrowableComputable, IOException>() { + @Override + public PersistentEnumeratorDelegate compute() throws IOException { + return new PersistentEnumeratorDelegate(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(IndexInfrastructure.getStorageFile(getFileTimestampsIndexId()), - new EnumeratorStringDescriptor(), new DataExternalizer() { + final File storageFile = IndexInfrastructure.getStorageFile(getFileTimestampsIndexId()); + try { + myFileTimestampsIndex = IOUtil.openCleanOrResetBroken( + new ThrowableComputable, IOException>() { @Override - public void save(final DataOutput out, final Long value) throws IOException { - out.writeLong(value); - } + public PersistentHashMap compute() throws IOException { + return new PersistentHashMap(storageFile, + new EnumeratorStringDescriptor(), new DataExternalizer() { + @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) { diff --git a/platform/util/src/com/intellij/util/io/IOUtil.java b/platform/util/src/com/intellij/util/io/IOUtil.java index 89496e5dac7f..c10f04a78dba 100644 --- a/platform/util/src/com/intellij/util/io/IOUtil.java +++ b/platform/util/src/com/intellij/util/io/IOUtil.java @@ -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 openCleanOrResetBroken(@NotNull ThrowableComputable factoryComputable, final File file) throws IOException { + return openCleanOrResetBroken(factoryComputable, new Runnable() { + @Override + public void run() { + deleteAllFilesStartingWith(file); + } + }); + } + + public static T openCleanOrResetBroken(@NotNull ThrowableComputable 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; + } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java index dd1e26f55302..9a933d3bbfd7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndex.java @@ -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> createPersistentMap(File f) throws IOException { - return new PersistentHashMap>(f, new EnumeratorStringDescriptor(), new SetDescriptor()); + private PersistentHashMap> createPersistentMap(final File f) throws IOException { + return IOUtil.openCleanOrResetBroken(new ThrowableComputable>, IOException>() { + @Override + public PersistentHashMap> compute() throws IOException { + return new PersistentHashMap>(f, new EnumeratorStringDescriptor(), new SetDescriptor()); + } + }, f); } public void close(boolean releaseIndexContext) throws MavenIndexException {