perf(ReadAction): use nonBlocking and runReadActionInSmartMode

This commit is contained in:
林万程
2024-01-21 16:18:47 +08:00
parent fadd45ddd3
commit 3e34fa8ac9
5 changed files with 78 additions and 64 deletions

View File

@@ -87,11 +87,16 @@ public class LineEnd extends EditorLinePainter {
if (doc == null) {
return null;
}
return lineExtText(info, info.appSettings.lineEndPrefix + doc);
}
@NotNull
public static LineExtensionInfo lineExtText(@NotNull LineInfo info, String text) {
@NotNull TextAttributes textAttr = info.file.getFileType().equals(JsonFileType.INSTANCE)
|| info.file.getFileType().equals(Json5FileType.INSTANCE)
? info.appSettings.lineEndJsonTextAttr
: info.appSettings.lineEndTextAttr;
return new LineExtensionInfo(info.appSettings.lineEndPrefix + doc, textAttr);
return new LineExtensionInfo(text, textAttr);
}
public static void textWithDoc(@NotNull FileInfo fileInfo, int startLine, int endLine,

View File

@@ -9,6 +9,7 @@ import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import io.github.linwancen.plugin.show.bean.FileInfo;
import io.github.linwancen.plugin.show.settings.ShowBundle;
@@ -53,27 +54,28 @@ public class LineEndCopy extends DumbAwareAction {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(false);
ApplicationManager.getApplication().runReadAction(() -> {
int startLine = 0;
int endLine = info.document.getLineCount() - 1;
// if select
@Nullable Editor editor = event.getData(CommonDataKeys.EDITOR);
if (editor != null) {
@NotNull Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
int start = primaryCaret.getSelectionStart();
int end = primaryCaret.getSelectionEnd();
try {
startLine = info.document.getLineNumber(start);
endLine = info.document.getLineNumber(end);
} catch (Exception e) {
return;
}
}
LineEnd.textWithDoc(info, startLine, endLine, indicator, s -> {
@NotNull StringSelection content = new StringSelection(s);
CopyPasteManager.getInstance().setContents(content);
});
});
DumbService.getInstance(project).runReadActionInSmartMode(() ->
ApplicationManager.getApplication().runReadAction(() -> {
int startLine = 0;
int endLine = info.document.getLineCount() - 1;
// if select
@Nullable Editor editor = event.getData(CommonDataKeys.EDITOR);
if (editor != null) {
@NotNull Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
int start = primaryCaret.getSelectionStart();
int end = primaryCaret.getSelectionEnd();
try {
startLine = info.document.getLineNumber(start);
endLine = info.document.getLineNumber(end);
} catch (Exception e) {
return;
}
}
LineEnd.textWithDoc(info, startLine, endLine, indicator, s -> {
@NotNull StringSelection content = new StringSelection(s);
CopyPasteManager.getInstance().setContents(content);
});
}));
}
}.queue();
}

View File

@@ -1,8 +1,8 @@
package io.github.linwancen.plugin.show.cache;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.editor.LineExtensionInfo;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
@@ -36,7 +36,7 @@ public class LineEndCacheUtils {
@NotNull LineInfo oldInfo = lineCache.info;
lineCache.info = info;
lineCache.show = true;
checkScheduleAndInit();
checkScheduleAndInit(info.project);
@Nullable List<LineExtensionInfo> list = lineCache.map.get(info.text);
// load from other line
if (list == null && info.lineCount != oldInfo.lineCount) {
@@ -65,8 +65,11 @@ public class LineEndCacheUtils {
private static volatile boolean isRun = false;
private static void checkScheduleAndInit() {
private static void checkScheduleAndInit(Project project) {
if (!isRun) {
if (DumbService.isDumb(project)) {
return;
}
synchronized (LineEndCacheUtils.class) {
if (!isRun) {
isRun = true;
@@ -89,22 +92,15 @@ public class LineEndCacheUtils {
cache.remove(project);
return;
}
if (DumbService.isDumb(project)) {
return;
}
fileMap.forEach((file, lineMap) -> lineMap.forEach((lineNumber, lineCache) -> {
@NotNull LineInfo info = lineCache.info;
@Nullable List<LineExtensionInfo> list = lineCache.map.get(info.text);
if (!(lineCache.needUpdate() || list == null)) {
return;
}
Application application = ApplicationManager.getApplication();
if (application == null) {
return;
}
application.runReadAction(() -> {
ReadAction.nonBlocking(() -> {
try {
if (project.isDisposed()) {
if (project.isDisposed() || DumbService.isDumb(project)) {
return;
}
@Nullable LineExtensionInfo lineExt = LineEnd.lineExt(info);
@@ -123,16 +119,18 @@ public class LineEndCacheUtils {
if (list != null) {
list.add(lineExt);
} else {
ArrayList<LineExtensionInfo> lineExtList = new ArrayList<>();
ArrayList<LineExtensionInfo> lineExtList = new ArrayList<>(1);
lineExtList.add(lineExt);
lineCache.map.put(info.text, lineExtList);
}
}
lineCache.updated();
} catch (ProcessCanceledException ignore) {
// ignore
} catch (Exception e) {
LOG.info("LineEndCacheUtils lineMap.forEach catch Throwable but log to record.", e);
}
});
}).inSmartMode(project).executeSynchronously();
}));
} catch (Exception e) {
LOG.info("LineEndCacheUtils cache.forEach catch Throwable but log to record.", e);

View File

@@ -1,6 +1,7 @@
package io.github.linwancen.plugin.show.cache;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
@@ -27,7 +28,7 @@ public class TreeCacheUtils {
.computeIfAbsent(project, a -> new ConcurrentHashMap<>())
.computeIfAbsent(node, a -> new TreeCache());
treeCache.needUpdate = true;
checkScheduleAndInit();
checkScheduleAndInit(project);
return treeCache.doc;
} catch (ProcessCanceledException e) {
return null;
@@ -39,8 +40,11 @@ public class TreeCacheUtils {
private static volatile boolean isRun = false;
private static void checkScheduleAndInit() {
private static void checkScheduleAndInit(Project project) {
if (!isRun) {
if (DumbService.isDumb(project)) {
return;
}
synchronized (TreeCacheUtils.class) {
if (!isRun) {
isRun = true;
@@ -63,19 +67,21 @@ public class TreeCacheUtils {
cache.remove(project);
return;
}
if (DumbService.isDumb(project)) {
return;
}
nodeCache.forEach((node, treeCache) -> {
if (treeCache.needUpdate) {
treeCache.needUpdate = false;
DumbService.getInstance(project).runReadActionInSmartMode(() -> {
ReadAction.nonBlocking(() -> {
try {
if (project.isDisposed() || DumbService.isDumb(project)) {
return;
}
treeCache.doc = Tree.treeDoc(node, project);
treeCache.needUpdate = false;
} catch (ProcessCanceledException ignore) {
// ignore
} catch (Exception e) {
LOG.info("TreeCacheUtils nodeCache.forEach catch Throwable but log to record.", e);
}
});
}).inSmartMode(project).executeSynchronously();
}
});
} catch (Exception e) {

View File

@@ -4,6 +4,7 @@ import com.intellij.ide.projectView.ProjectView;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.FilenameIndex;
@@ -127,25 +128,27 @@ public class ConfCache {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(false);
ApplicationManager.getApplication().runReadAction(() -> {
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project, TsvLoader.EXT);
@NotNull StringBuilder sb = new StringBuilder();
double i = 0;
for (@NotNull VirtualFile file : files) {
indicator.setText(file.getName());
load(file);
i++;
indicator.setFraction(i / files.size());
sb.append(file.getName()).append("\n");
}
if (files.isEmpty()) {
return;
}
if (!project.isDisposed()) {
ProjectView.getInstance(project).refresh();
}
LOG.info("Ext doc conf load all complete {} files\n{}", files.size(), sb);
});
DumbService.getInstance(project).runReadActionInSmartMode(() ->
ApplicationManager.getApplication().runReadAction(() -> {
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project,
TsvLoader.EXT);
@NotNull StringBuilder sb = new StringBuilder();
double i = 0;
for (@NotNull VirtualFile file : files) {
indicator.setText(file.getName());
load(file);
i++;
indicator.setFraction(i / files.size());
sb.append(file.getName()).append("\n");
}
if (files.isEmpty()) {
return;
}
if (!project.isDisposed()) {
ProjectView.getInstance(project).refresh();
}
LOG.info("Ext doc conf load all complete {} files\n{}", files.size(), sb);
}));
}
}.queue();
}