migrate IndexedFilesListener to async API

GitOrigin-RevId: fa8a7dbf64e56843354fdda9c150326d577e7326
This commit is contained in:
peter
2019-06-12 14:08:51 +03:00
committed by intellij-monorepo-bot
parent 3a58e13268
commit 7bbe5d2b80
4 changed files with 63 additions and 46 deletions
@@ -60,7 +60,9 @@ import com.intellij.util.indexing.*
import com.intellij.util.indexing.impl.MapIndexStorage
import com.intellij.util.indexing.impl.MapReduceIndex
import com.intellij.util.indexing.impl.UpdatableValueContainer
import com.intellij.util.io.*
import com.intellij.util.io.CaseInsensitiveEnumeratorStringDescriptor
import com.intellij.util.io.EnumeratorStringDescriptor
import com.intellij.util.io.PersistentHashMap
import com.intellij.util.ref.GCUtil
import com.intellij.util.ref.GCWatcher
import com.siyeh.ig.JavaOverridingMethodUtil
@@ -800,10 +802,7 @@ class IndexTest extends JavaCodeInsightFixtureTestCase {
void testIndexedFilesListener() throws Throwable {
def listener = new RecordingVfsListener()
ApplicationManager.getApplication().getMessageBus().connect(myFixture.getTestRootDisposable()).subscribe(
VirtualFileManager.VFS_CHANGES,
listener
)
VirtualFileManager.instance.addAsyncFileListener(listener, myFixture.testRootDisposable)
def fileName = "test.txt"
final VirtualFile testFile = myFixture.addFileToProject(fileName, "test").getVirtualFile()
@@ -912,7 +911,7 @@ class IndexTest extends JavaCodeInsightFixtureTestCase {
}
@CompileStatic
void "test Vfs Events Processing Performance"() {
void "test Vfs Event Processing Performance"() {
def filename = 'A.java'
myFixture.addFileToProject('foo/bar/' + filename, 'class A {}')
@@ -934,9 +933,9 @@ class IndexTest extends JavaCodeInsightFixtureTestCase {
eventList.add(new VFileCreateEvent(null, file.parent, filename, false, null, null, true, null))
}
IndexedFilesListener indexedFilesListener = ((FileBasedIndexImpl)FileBasedIndex.instance).changedFilesCollector
indexedFilesListener.before(eventList)
indexedFilesListener.after(eventList)
def applier = ((FileBasedIndexImpl)FileBasedIndex.instance).changedFilesCollector.prepareChange(eventList)
applier.beforeVfsChange()
applier.afterVfsChange()
files = FilenameIndex.getFilesByName(project, filename, GlobalSearchScope.moduleScope(module))
assert files?.length == 1
@@ -36,10 +36,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileWithId;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
@@ -262,7 +259,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
myChangedFilesCollector = new ChangedFilesCollector();
myConnection = connection;
connection.subscribe(VirtualFileManager.VFS_CHANGES, myChangedFilesCollector);
VirtualFileManager.getInstance().addAsyncFileListener(myChangedFilesCollector, this);
initComponent();
}
@@ -311,7 +308,7 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
// but it is more costly than current code, see IDEA-192192
//myChangedFilesCollector.invalidateIndicesRecursively(file, false);
//myChangedFilesCollector.buildIndicesForFileRecursively(file, false);
myChangedFilesCollector.invalidateIndicesRecursively(file, true);
myChangedFilesCollector.invalidateIndicesRecursively(file, true, myChangedFilesCollector.getEventMerger());
if (myInitialized) myChangedFilesCollector.ensureUpToDateAsync();
}
@@ -1939,14 +1936,26 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
}
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
if (memoryStorageCleaningNeeded(event)) {
cleanupMemoryStorage(false);
break;
@NotNull
public AsyncFileListener.ChangeApplier prepareChange(@NotNull List<? extends VFileEvent> events) {
boolean shouldCleanup = ContainerUtil.exists(events, this::memoryStorageCleaningNeeded);
ChangeApplier superApplier = super.prepareChange(events);
return new AsyncFileListener.ChangeApplier() {
@Override
public void beforeVfsChange() {
if (shouldCleanup) {
cleanupMemoryStorage(false);
}
superApplier.beforeVfsChange();
}
}
super.before(events);
@Override
public void afterVfsChange() {
superApplier.afterVfsChange();
if (myInitialized) ensureUpToDateAsync();
}
};
}
private boolean memoryStorageCleaningNeeded(VFileEvent event) {
@@ -1956,13 +1965,6 @@ public final class FileBasedIndexImpl extends FileBasedIndex implements Disposab
requestor == LocalHistory.VFS_EVENT_REQUESTOR;
}
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
super.after(events);
if (myInitialized) ensureUpToDateAsync();
}
boolean isScheduledForUpdate(VirtualFile file) {
return myFilesToUpdate.containsKey(Math.abs(getIdMaskingNonIdBasedFile(file)));
}
@@ -16,12 +16,9 @@
package com.intellij.util.indexing;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.*;
@@ -31,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.List;
public abstract class IndexedFilesListener implements BulkFileListener {
public abstract class IndexedFilesListener implements AsyncFileListener {
private final ManagingFS myManagingFS = ManagingFS.getInstance();
private final VfsEventsMerger myEventMerger = new VfsEventsMerger();
@Nullable private final VirtualFile myConfig;
@@ -60,21 +57,22 @@ public abstract class IndexedFilesListener implements BulkFileListener {
}
}
private boolean invalidateIndicesForFile(@NotNull VirtualFile file, boolean contentChange) {
private boolean invalidateIndicesForFile(@NotNull VirtualFile file, boolean contentChange, VfsEventsMerger eventMerger) {
if (isUnderConfigOrSystem(file)) {
return false;
}
myEventMerger.recordBeforeFileEvent(file, contentChange);
ProgressManager.checkCanceled();
eventMerger.recordBeforeFileEvent(file, contentChange);
return !file.isDirectory() || FileBasedIndexImpl.isMock(file) || myManagingFS.wereChildrenAccessed(file);
}
protected abstract void iterateIndexableFiles(@NotNull VirtualFile file, @NotNull ContentIterator iterator);
void invalidateIndicesRecursively(@NotNull final VirtualFile file, final boolean contentChange) {
void invalidateIndicesRecursively(@NotNull VirtualFile file, boolean contentChange, VfsEventsMerger eventMerger) {
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
return invalidateIndicesForFile(file, contentChange);
return invalidateIndicesForFile(file, contentChange, eventMerger);
}
@Override
@@ -85,13 +83,15 @@ public abstract class IndexedFilesListener implements BulkFileListener {
}
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
@NotNull
public ChangeApplier prepareChange(@NotNull List<? extends VFileEvent> events) {
VfsEventsMerger tempMerger = new VfsEventsMerger();
for (VFileEvent event : events) {
if (event instanceof VFileContentChangeEvent) {
invalidateIndicesRecursively(((VFileContentChangeEvent)event).getFile(), true);
invalidateIndicesRecursively(((VFileContentChangeEvent)event).getFile(), true, tempMerger);
}
else if (event instanceof VFileDeleteEvent) {
invalidateIndicesRecursively(((VFileDeleteEvent)event).getFile(), false);
invalidateIndicesRecursively(((VFileDeleteEvent)event).getFile(), false, tempMerger);
}
else if (event instanceof VFilePropertyChangeEvent) {
final VFilePropertyChangeEvent pce = (VFilePropertyChangeEvent)event;
@@ -100,16 +100,26 @@ public abstract class IndexedFilesListener implements BulkFileListener {
// indexes may depend on file name
// name change may lead to filetype change so the file might become not indexable
// in general case have to 'unindex' the file and index it again if needed after the name has been changed
invalidateIndicesRecursively(pce.getFile(), false);
invalidateIndicesRecursively(pce.getFile(), false, tempMerger);
} else if (propertyName.equals(VirtualFile.PROP_ENCODING)) {
invalidateIndicesRecursively(pce.getFile(), true);
invalidateIndicesRecursively(pce.getFile(), true, tempMerger);
}
}
}
return new ChangeApplier() {
@Override
public void beforeVfsChange() {
myEventMerger.applyMergedEvents(tempMerger);
}
@Override
public void afterVfsChange() {
processAfterEvents(events);
}
};
}
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
private void processAfterEvents(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
if (event instanceof VFileContentChangeEvent) {
buildIndicesForFileRecursively(((VFileContentChangeEvent)event).getFile(), true);
@@ -66,6 +66,12 @@ public class VfsEventsMerger {
}
}
public void applyMergedEvents(VfsEventsMerger merger) {
for(ChangeInfo info:merger.myChangeInfos.values()) {
updateChange(info.getFileId(), info.file, info.eventMask);
}
}
@FunctionalInterface
public interface VfsEventProcessor {
boolean process(@NotNull ChangeInfo changeInfo);