From e11240d0ce913443605a4a89c806ff745f10450b Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 9 Dec 2010 21:02:02 +0300 Subject: [PATCH] sparse graph dfs building optimization --- .../openapi/extensions/LoadingOrder.java | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/platform/extensions/src/com/intellij/openapi/extensions/LoadingOrder.java b/platform/extensions/src/com/intellij/openapi/extensions/LoadingOrder.java index fb23ea896a56..629c98c6cf17 100644 --- a/platform/extensions/src/com/intellij/openapi/extensions/LoadingOrder.java +++ b/platform/extensions/src/com/intellij/openapi/extensions/LoadingOrder.java @@ -20,7 +20,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.graph.CachingSemiGraph; import com.intellij.util.graph.DFSTBuilder; import com.intellij.util.graph.GraphGenerator; -import gnu.trove.THashMap; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -56,8 +55,8 @@ public class LoadingOrder { @NonNls private final String myName; // for debug only private final boolean myFirst; private final boolean myLast; - private final Set myBefore = new HashSet(); - private final Set myAfter = new HashSet(); + private final Set myBefore = new HashSet(2); + private final Set myAfter = new HashSet(2); private LoadingOrder() { myName = "ANY"; @@ -118,16 +117,20 @@ public class LoadingOrder { } public static void sort(final Orderable[] orderables) { + // our graph is pretty sparse so do benefit from the fact final Map map = new HashMap(); - for (final Orderable orderable : orderables) { - final String id = orderable.getOrderId(); - if (StringUtil.isNotEmpty(id)) { - map.put(id, orderable); - } - } + final HashMap cachedMap = new HashMap(orderables.length); + final HashSet first = new HashSet(1); + final HashSet hasBefore = new HashSet(orderables.length); - final Map cachedMap = new THashMap(); - for(Orderable o:orderables) cachedMap.put(o, o.getOrder()); + for(Orderable o:orderables) { + final String id = o.getOrderId(); + if (StringUtil.isNotEmpty(id)) map.put(id, o); + LoadingOrder order = o.getOrder(); + cachedMap.put(o, order); + if (order.myFirst) first.add(o); + if (order.myBefore.size() != 0) hasBefore.add(o); + } DFSTBuilder builder = new DFSTBuilder(new GraphGenerator(new CachingSemiGraph(new GraphGenerator.SemiGraph() { public Collection getNodes() { @@ -148,14 +151,30 @@ public class LoadingOrder { } String id = n.getOrderId(); - for (final Orderable orderable : orderables) { - final LoadingOrder hisOrder = cachedMap.get(orderable); - if (StringUtil.isNotEmpty(id) && hisOrder.myBefore.contains(id) || - order.myLast && !hisOrder.myLast || - hisOrder.myFirst && !order.myFirst) { + if (StringUtil.isNotEmpty(id)) { + for (final Orderable orderable : hasBefore) { + final LoadingOrder hisOrder = cachedMap.get(orderable); + if (hisOrder.myBefore.contains(id)) { + predecessors.add(orderable); + } + } + } + + if (order.myLast) { + for (final Orderable orderable : orderables) { + final LoadingOrder hisOrder = cachedMap.get(orderable); + if (!hisOrder.myLast) { + predecessors.add(orderable); + } + } + } + + if (!order.myFirst) { + for(Orderable orderable:first) { predecessors.add(orderable); } } + return predecessors.iterator(); } })));