From 22eb2449c657908bd8f0a86e7aab2b6ea74d1e96 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 21 Oct 2013 15:20:51 +0200 Subject: [PATCH] avoid hard referencing of filecontent (including psi file in user data) in indexed stamp update runnable [r=Peter.Gromov] --- .../util/indexing/FileBasedIndexImpl.java | 78 +++++++++++-------- 1 file changed, 46 insertions(+), 32 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 2966cde06f73..27fd026874d0 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1771,7 +1771,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { fc.putUserData(IndexingDataKeys.PROJECT, project); } - private void updateSingleIndex(final ID indexId, @NotNull final VirtualFile file, @Nullable final FileContent currentFC) + private void updateSingleIndex(final ID indexId, @NotNull final VirtualFile file, @Nullable FileContent currentFC) throws StorageException { if (ourRebuildStatus.get(indexId).get() == REQUIRES_REBUILD) { return; // the index is scheduled for rebuild, no need to update @@ -1782,42 +1782,55 @@ public class FileBasedIndexImpl extends FileBasedIndex { final UpdatableIndex index = getIndex(indexId); assert index != null; + // important: no hard referencing currentFC to avoid OOME, the methods introduced for this purpose! final Computable update = index.update(inputId, currentFC); final FileType fileType = file.getFileType(); + scheduleUpdate(indexId, - new Computable() { - @Override - public Boolean compute() { - Boolean result; - final StorageGuard.Holder lock = setDataBufferingEnabled(false); - try { - result = update.compute(); - } - finally { - lock.leave(); - } - return result; - } - }, - new Runnable() { - @Override - public void run() { - if (file.isValid()) { - ID stubId = IndexInfrastructure.getStubId(indexId, fileType); - if (currentFC != null) { - IndexingStamp.update(file, stubId, getIndexCreationStamp(stubId, fileType)); - } - else { - // mark the file as unindexed - IndexingStamp.update(file, stubId, IndexInfrastructure.INVALID_STAMP); - } - if (myNotRequiringContentIndices.contains(indexId)) IndexingStamp.flushCache(file); - } - } - } + createUpdateComputableWithBufferingDisabled(update), + createIndexedStampUpdateRunnable(indexId, file, fileType, currentFC != null) ); } + private Runnable createIndexedStampUpdateRunnable(final ID indexId, + final VirtualFile file, + final FileType fileType, + final boolean hasContent) { + return new Runnable() { + @Override + public void run() { + if (file.isValid()) { + ID stubId = IndexInfrastructure.getStubId(indexId, fileType); + if (hasContent) { + IndexingStamp.update(file, stubId, getIndexCreationStamp(stubId, fileType)); + } + else { + // mark the file as unindexed + IndexingStamp.update(file, stubId, IndexInfrastructure.INVALID_STAMP); + } + if (myNotRequiringContentIndices.contains(indexId)) IndexingStamp.flushCache(file); + } + } + }; + } + + private Computable createUpdateComputableWithBufferingDisabled(final Computable update) { + return new Computable() { + @Override + public Boolean compute() { + Boolean result; + final StorageGuard.Holder lock = setDataBufferingEnabled(false); + try { + result = update.compute(); + } + finally { + lock.leave(); + } + return result; + } + }; + } + private void scheduleUpdate(ID indexId, final Computable update, final Runnable successRunnable) { if (myNotRequiringContentIndices.contains(indexId)) { myContentlessIndicesUpdateQueue.submit(update, successRunnable); @@ -2222,7 +2235,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { updateSemaphore = obtainForceUpdateSemaphore(); try { for (VirtualFile file : getAllFilesToUpdate()) { - if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.containsFileId(((VirtualFileWithId)file).getId())) { + if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.containsFileId( + ((VirtualFileWithId)file).getId())) { continue; }