From dfc7476ca09ce42dea48565a9a6403f8736af476 Mon Sep 17 00:00:00 2001 From: Sergey Patrikeev Date: Mon, 4 May 2020 19:25:53 +0300 Subject: [PATCH] Indexes: explicitly handle exception of DataIndexer.map happening on file index update, propagate this exception and do not invalidate the whole index. GitOrigin-RevId: 5d86c113916c6a20a280949206992aaca14824f1 --- .../util/indexing/FileBasedIndexImpl.java | 50 +++++++++---------- .../util/indexing/impl/MapReduceIndex.java | 28 ++++++++--- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index 23b3761d10b2..6b9d2ee251da 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -49,6 +49,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.gist.GistManager; import com.intellij.util.indexing.caches.CachedFileContent; import com.intellij.util.indexing.diagnostic.FileIndexingStatistics; +import com.intellij.util.indexing.impl.MapReduceIndex; import com.intellij.util.indexing.memory.InMemoryIndexStorage; import com.intellij.util.indexing.snapshot.IndexedHashesSupport; import com.intellij.util.indexing.snapshot.SnapshotInputMappings; @@ -806,8 +807,12 @@ public final class FileBasedIndexImpl extends FileBasedIndexEx { if (e instanceof ProcessCanceledException) return null; if (e instanceof IndexOutOfBoundsException) return e; // something wrong with direct byte buffer Throwable cause = e.getCause(); - if (cause instanceof StorageException || cause instanceof IOException || - cause instanceof IllegalArgumentException) return cause; + if (cause instanceof StorageException + || cause instanceof IOException + || cause instanceof IllegalArgumentException + ) { + return cause; + } return null; } @@ -1279,18 +1284,26 @@ public final class FileBasedIndexImpl extends FileBasedIndexEx { assert index != null; markFileIndexed(file); - boolean updateCalculated = false; try { - // important: no hard referencing currentFC to avoid OOME, the methods introduced for this purpose! - // important: update is called out of try since possible indexer extension is HANDLED as single file fail / restart indexing policy - final Computable update = () -> index.update(inputId, currentFC); - updateCalculated = true; - - runIndexUpdate(indexId, update, currentFC, inputId); + if (myStorageBufferingHandler.runUpdate(false, () -> index.update(inputId, currentFC))) { + ConcurrencyUtil.withLock(myReadLock, () -> { + if (currentFC != null) { + index.setIndexedStateForFile(inputId, currentFC); + } + else { + index.resetIndexedStateForFile(inputId); + } + }); + } + } + catch (MapReduceIndex.MapInputException e) { + // If exception has happened on input mapping (DataIndexer.map), + // it is handled as indexer exception and does not lead to index rebuild. + throw e; } catch (RuntimeException exception) { Throwable causeToRebuildIndex = getCauseToRebuildIndex(exception); - if (causeToRebuildIndex != null && (updateCalculated || causeToRebuildIndex instanceof IOException)) { + if (causeToRebuildIndex != null) { requestRebuild(indexId, exception); return false; } @@ -1353,23 +1366,6 @@ public final class FileBasedIndexImpl extends FileBasedIndexEx { } } - private void runIndexUpdate(@NotNull ID indexId, - @NotNull Computable update, - @Nullable IndexedFile file, - int inputId) { - if (myStorageBufferingHandler.runUpdate(false, update)) { - ConcurrencyUtil.withLock(myReadLock, () -> { - UpdatableIndex index = getIndex(indexId); - if (file != null) { - index.setIndexedStateForFile(inputId, file); - } - else { - index.resetIndexedStateForFile(inputId); - } - }); - } - } - boolean needsFileContentLoading(@NotNull ID indexId) { return !myRegisteredIndexes.isNotRequiringContentIndex(indexId); } diff --git a/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java b/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java index 8d9ff4e94ff8..c344d7f7409c 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java +++ b/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java @@ -219,14 +219,24 @@ public abstract class MapReduceIndex implements InvertedIndex< @Override public final boolean update(int inputId, @Nullable Input content) { - final InputData data = mapInput(inputId, content); - final UpdateData updateData = new UpdateData<>(inputId, - data.getKeyValues(), - () -> getKeysDiffBuilder(inputId), myIndexId, - () -> updateForwardIndex(inputId, data)); + final InputData data; + try { + data = mapInput(inputId, content); + } + catch (ProcessCanceledException e) { + throw e; + } + catch (Exception e) { + throw new MapInputException("Failed to map data for input " + inputId, e); + } try { - updateWithMap(updateData); + updateWithMap(new UpdateData<>( + inputId, + data.getKeyValues(), + () -> getKeysDiffBuilder(inputId), + myIndexId, () -> updateForwardIndex(inputId, data)) + ); } catch (StorageException | ProcessCanceledException ex) { String message = "An exception during updateWithMap(). Index " + myIndexId.getName() + " will be rebuilt."; @@ -242,6 +252,12 @@ public abstract class MapReduceIndex implements InvertedIndex< return true; } + public static final class MapInputException extends RuntimeException { + public MapInputException(String message, Throwable cause) { + super(message, cause); + } + } + protected void updateForwardIndex(int inputId, @NotNull InputData data) throws IOException { if (myForwardIndex != null) { if (myUseIntForwardIndex) {