From 13b380716682691f911fe955aebf4c5f4b2cabc1 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 27 Oct 2015 16:01:00 +0300 Subject: [PATCH] IDEA-146849 IntelliJ hangs for 30+ seconds with large Android project after leaving and returning... --- .../com/intellij/roots/ModuleGraphTest.java | 54 +++++++++++++++++++ .../intellij/util/graph/GraphAlgorithms.java | 9 ++++ .../util/graph/impl/GraphAlgorithmsImpl.java | 12 +++++ 3 files changed, 75 insertions(+) create mode 100644 java/java-tests/testSrc/com/intellij/roots/ModuleGraphTest.java diff --git a/java/java-tests/testSrc/com/intellij/roots/ModuleGraphTest.java b/java/java-tests/testSrc/com/intellij/roots/ModuleGraphTest.java new file mode 100644 index 000000000000..c1aadc0092bc --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/roots/ModuleGraphTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.roots; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.roots.DependencyScope; +import com.intellij.openapi.roots.ModuleRootModificationUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.graph.Graph; +import com.intellij.util.graph.GraphAlgorithms; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author Dmitry Avdeev + */ +public class ModuleGraphTest extends ModuleRootManagerTestCase { + + public void testOuts() throws Exception { + + Module a = createModule("a"); + Module b = createModule("b"); + addDependency(myModule, a); + addDependency(a, b); + + Graph graph = ModuleManager.getInstance(getProject()).moduleGraph(); + List outs = ContainerUtil.collect(graph.getOut(a)); + assertEquals(1, outs.size()); + + Set set = new HashSet<>(); + GraphAlgorithms.getInstance().collectOutsRecursively(graph, b, set); + assertEquals(3, set.size()); + } + + protected void addDependency(Module module, Module a) { + ModuleRootModificationUtil.addDependency(module, a, DependencyScope.COMPILE, true); + } +} diff --git a/platform/platform-api/src/com/intellij/util/graph/GraphAlgorithms.java b/platform/platform-api/src/com/intellij/util/graph/GraphAlgorithms.java index 6ae9d4491844..b5cf7835d89b 100644 --- a/platform/platform-api/src/com/intellij/util/graph/GraphAlgorithms.java +++ b/platform/platform-api/src/com/intellij/util/graph/GraphAlgorithms.java @@ -54,4 +54,13 @@ public abstract class GraphAlgorithms { @NotNull public abstract Graph> computeSCCGraph(@NotNull Graph graph); + + /** + * Adds start node and all its outs to given set recursively. + * If start node is in set already, returns immediately. + * + * @param start node to start from + * @param set set to be populated + */ + public abstract void collectOutsRecursively(@NotNull Graph graph, Node start, Set set); } diff --git a/platform/platform-impl/src/com/intellij/util/graph/impl/GraphAlgorithmsImpl.java b/platform/platform-impl/src/com/intellij/util/graph/impl/GraphAlgorithmsImpl.java index 7fe41a92f864..9beb9a49db57 100644 --- a/platform/platform-impl/src/com/intellij/util/graph/impl/GraphAlgorithmsImpl.java +++ b/platform/platform-impl/src/com/intellij/util/graph/impl/GraphAlgorithmsImpl.java @@ -111,6 +111,18 @@ public class GraphAlgorithmsImpl extends GraphAlgorithms { })); } + @Override + public void collectOutsRecursively(@NotNull Graph graph, Node start, Set set) { + if (!set.add(start)) { + return; + } + Iterator iterator = graph.getOut(start); + while (iterator.hasNext()) { + Node node = iterator.next(); + collectOutsRecursively(graph, node, set); + } + } + @NotNull @Override public Collection> computeStronglyConnectedComponents(@NotNull Graph graph) {