From f2765fe5ef84fdd7fbb6a3e645f93b30c5f0e0a3 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 31 May 2012 17:43:31 +0200 Subject: [PATCH] more responsive find usages: group usages outside EDT --- .../usages/impl/UsageNodeTreeBuilderTest.java | 8 +++++- .../com/intellij/usages/impl/GroupNode.java | 16 ++++++------ .../usages/impl/UsageNodeTreeBuilder.java | 7 ++--- .../intellij/usages/impl/UsageViewImpl.java | 26 +++++++++++-------- .../usages/impl/UsageViewManagerImpl.java | 6 +++-- .../impl/UsageViewTreeModelBuilder.java | 9 ++++++- 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java index 1b3d885fd5c7..1b08e40def90 100644 --- a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java +++ b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java @@ -22,6 +22,7 @@ import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.usages.*; import com.intellij.usages.rules.UsageFilteringRule; import com.intellij.usages.rules.UsageGroupingRule; +import com.intellij.util.Consumer; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -90,7 +91,12 @@ public class UsageNodeTreeBuilderTest extends LightPlatformTestCase { model.setRoot(rootNode); UsageNodeTreeBuilder usageNodeTreeBuilder = new UsageNodeTreeBuilder(UsageTarget.EMPTY_ARRAY, rules, UsageFilteringRule.EMPTY_ARRAY, rootNode); for (Usage usage : usages) { - usageNodeTreeBuilder.appendUsage(usage); + usageNodeTreeBuilder.appendUsage(usage, new Consumer() { + @Override + public void consume(Runnable runnable) { + runnable.run(); + } + }); UIUtil.dispatchAllInvocationEvents(); } diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java index fd8a33434717..19ac91ad7627 100644 --- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java @@ -23,7 +23,7 @@ import com.intellij.usages.UsageGroup; import com.intellij.usages.UsageView; import com.intellij.usages.UsageViewSettings; import com.intellij.usages.rules.MergeableUsage; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.Consumer; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,22 +62,22 @@ public class GroupNode extends Node implements Navigatable, Comparable edtQueue) { synchronized (lock) { GroupNode node = mySubgroupNodes.get(group); if (node == null) { final GroupNode node1 = node = new GroupNode(group, ruleIndex, getBuilder()); mySubgroupNodes.put(group, node); - addNode(node1); + addNode(node1, edtQueue); } return node; } } - void addNode(@NotNull final DefaultMutableTreeNode node) { + void addNode(@NotNull final DefaultMutableTreeNode node, @NotNull Consumer edtQueue) { if (!getBuilder().isDetachedMode()) { - UIUtil.invokeLaterIfNeeded(new Runnable() { + edtQueue.consume(new Runnable() { @Override public void run() { myTreeModel.insertNodeInto(node, GroupNode.this, getNodeInsertionIndex(node)); @@ -102,7 +102,7 @@ public class GroupNode extends Node implements Navigatable, Comparable edtQueue) { final UsageNode node; synchronized (lock) { if (UsageViewSettings.getInstance().isFilterDuplicatedLine()) { @@ -168,7 +168,7 @@ public class GroupNode extends Node implements Navigatable, Comparable edtQueue) { if (!isVisible(usage)) return null; GroupNode lastGroupNode = myRoot; @@ -83,10 +84,10 @@ class UsageNodeTreeBuilder { group = rule.groupUsage(usage); } if (group != null) { - lastGroupNode = lastGroupNode.addGroup(group, i); + lastGroupNode = lastGroupNode.addGroup(group, i, edtQueue); } } - return lastGroupNode.addUsage(usage); + return lastGroupNode.addUsage(usage, edtQueue); } } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index db8dafac57fb..c0219c6ced28 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -34,7 +34,7 @@ import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.*; import com.intellij.openapi.vfs.ReadonlyStatusHandler; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiDocumentManager; @@ -47,6 +47,7 @@ import com.intellij.usageView.UsageViewManager; import com.intellij.usages.*; import com.intellij.usages.rules.*; import com.intellij.util.Alarm; +import com.intellij.util.Consumer; import com.intellij.util.EditSourceOnDoubleClickHandler; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; @@ -237,10 +238,10 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } }); } - myTransferToEDTQueue = new TransferToEDTQueue("Insert usages", new Processor() { + myTransferToEDTQueue = new TransferToEDTQueue("Insert usages", new Processor() { @Override - public boolean process(Usage usage) { - appendUsage(usage); + public boolean process(Runnable runnable) { + runnable.run(); return true; } }, new Condition() { @@ -672,7 +673,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra if (usageCount > UsageLimitUtil.USAGES_LIMIT && tooManyUsages.get() == 0 && tooManyUsages.compareAndSet(0, 1)) { ((UsageViewManagerImpl)usageViewManager).showTooManyUsagesWarning(indicator, waitWhileUserClick, usageCountWithoutDefinition.get()); } - appendUsageLater(usage); + appendUsage(usage); } ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); return indicator == null || !indicator.isCanceled(); @@ -699,10 +700,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } } - private final TransferToEDTQueue myTransferToEDTQueue; - public void appendUsageLater(@NotNull Usage usage) { - myTransferToEDTQueue.offer(usage); - } + private final TransferToEDTQueue myTransferToEDTQueue; public void drainQueuedUsageNodes() { assert !ApplicationManager.getApplication().isDispatchThread() : Thread.currentThread(); UIUtil.invokeAndWaitIfNeeded(new Runnable() { @@ -718,6 +716,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra doAppendUsage(usage); } + @Nullable public UsageNode doAppendUsage(@NotNull Usage usage) { // invoke in ReadAction to be be sure that usages are not invalidated while the tree is being built ApplicationManager.getApplication().assertReadAccessAllowed(); @@ -725,7 +724,12 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra // because the view is built incrementally, the usage may be already invalid, so need to filter such cases return null; } - UsageNode node = myBuilder.appendUsage(usage); + UsageNode node = myBuilder.appendUsage(usage, new Consumer() { + @Override + public void consume(Runnable runnable) { + myTransferToEDTQueue.offer(runnable); + } + }); myUsageNodes.put(usage, node == null ? NULL_NODE : node); return node; } @@ -934,7 +938,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra final Set readOnlyUsages = getReadOnlyUsagesFiles(); return readOnlyUsages.isEmpty() || - !ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(VfsUtil.toVirtualFileArray(readOnlyUsages)).hasReadonlyFiles(); + !ReadonlyStatusHandler.getInstance(myProject).ensureFilesWritable(VfsUtilCore.toVirtualFileArray(readOnlyUsages)).hasReadonlyFiles(); } @NotNull diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java index 7c055d4e05dc..403812d40399 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewManagerImpl.java @@ -282,7 +282,7 @@ public class UsageViewManagerImpl extends UsageViewManager { openView(usageView); Usage firstUsage = myFirstUsage.get(); if (firstUsage != null) { - usageView.appendUsageLater(firstUsage); + usageView.appendUsage(firstUsage); } } else { @@ -308,8 +308,10 @@ public class UsageViewManagerImpl extends UsageViewManager { @Override public void run() { + //long start = System.currentTimeMillis(); searchUsages(); endSearchForUsages(); + //System.out.println("Usage search took " + (System.currentTimeMillis() - start)); } private void searchUsages() { @@ -342,7 +344,7 @@ public class UsageViewManagerImpl extends UsageViewManager { } UsageViewImpl usageView = getUsageView(); if (usageView != null) { - usageView.appendUsageLater(usage); + usageView.appendUsage(usage); } } return indicator == null || !indicator.isCanceled(); diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java index 8d2da9c0ce91..450e327cd69c 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeModelBuilder.java @@ -17,6 +17,8 @@ package com.intellij.usages.impl; import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageViewPresentation; +import com.intellij.util.Consumer; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import javax.swing.tree.DefaultMutableTreeNode; @@ -66,7 +68,12 @@ public class UsageViewTreeModelBuilder extends DefaultTreeModel { myTargetsNode.add(targetNode); myTargetNodes[i] = targetNode; } - myRootNode.addNode(myTargetsNode); + myRootNode.addNode(myTargetsNode, new Consumer() { + @Override + public void consume(Runnable runnable) { + UIUtil.invokeLaterIfNeeded(runnable); + } + }); } public UsageNode getFirstUsageNode() {