[platform] splits a Graph into pair of complementary interfaces

This commit is contained in:
Roman Shevchenko
2016-11-18 20:38:00 +01:00
parent d8ac90d337
commit e05133c587
6 changed files with 92 additions and 18 deletions
@@ -23,10 +23,14 @@ import java.util.*;
* @author dsl
*/
public class CachingSemiGraph<Node> implements GraphGenerator.SemiGraph<Node> {
public static <T> InboundSemiGraph<T> cache(InboundSemiGraph<T> original) {
return new CachingSemiGraph<T>(original);
}
private final Set<Node> myNodes;
private final Map<Node, Set<Node>> myIn;
public CachingSemiGraph(GraphGenerator.SemiGraph<Node> original) {
private CachingSemiGraph(InboundSemiGraph<Node> original) {
myNodes = ContainerUtil.newLinkedHashSet(original.getNodes());
myIn = new LinkedHashMap<Node, Set<Node>>();
for (Node node : myNodes) {
@@ -36,10 +40,6 @@ public class CachingSemiGraph<Node> implements GraphGenerator.SemiGraph<Node> {
}
}
public static <T> CachingSemiGraph<T> create(GraphGenerator.SemiGraph<T> original) {
return new CachingSemiGraph<T>(original);
}
@Override
public Collection<Node> getNodes() {
return myNodes;
@@ -49,4 +49,14 @@ public class CachingSemiGraph<Node> implements GraphGenerator.SemiGraph<Node> {
public Iterator<Node> getIn(Node n) {
return myIn.get(n).iterator();
}
//<editor-fold desc="Deprecated stuff.">
public static <T> CachingSemiGraph<T> create(GraphGenerator.SemiGraph<T> original) {
return new CachingSemiGraph<T>((InboundSemiGraph<T>)original);
}
public CachingSemiGraph(GraphGenerator.SemiGraph<Node> original) {
this((InboundSemiGraph<Node>)original);
}
//</editor-fold>
}
@@ -30,7 +30,7 @@ import java.util.*;
* @author dsl, ven
*/
public class DFSTBuilder<Node> {
private final Graph<Node> myGraph;
private final OutboundSemiGraph<Node> myGraph;
private final TObjectIntHashMap<Node> myNodeToNNumber; // node -> node number in topological order [0..size). Independent nodes are in reversed loading order (loading order is the graph.getNodes() order)
private final Node[] myInvN; // node number in topological order [0..size) -> node
private Couple<Node> myBackEdge;
@@ -42,8 +42,12 @@ public class DFSTBuilder<Node> {
private final Node[] myInvT; // number in (enumerate all nodes scc by scc) order -> node
private final Node[] myAllNodes;
@SuppressWarnings("unchecked")
public DFSTBuilder(@NotNull Graph<Node> graph) {
this((OutboundSemiGraph<Node>)graph);
}
@SuppressWarnings("unchecked")
public DFSTBuilder(@NotNull OutboundSemiGraph<Node> graph) {
myAllNodes = (Node[])graph.getNodes().toArray();
myGraph = graph;
int size = graph.getNodes().size();
@@ -21,7 +21,7 @@ import java.util.Iterator;
/**
* @author dsl
*/
public interface Graph<Node> {
public interface Graph<Node> extends InboundSemiGraph<Node>, OutboundSemiGraph<Node> {
Collection<Node> getNodes();
Iterator<Node> getIn(Node n);
@@ -21,25 +21,19 @@ import java.util.*;
* @author dsl
*/
public class GraphGenerator<Node> implements Graph<Node> {
public interface SemiGraph<Node> {
Collection<Node> getNodes();
Iterator<Node> getIn(Node n);
public static <T> Graph<T> generate(InboundSemiGraph<T> graph) {
return new GraphGenerator<T>(graph);
}
private final SemiGraph<Node> myGraph;
private final InboundSemiGraph<Node> myGraph;
private final Map<Node, Set<Node>> myOuts;
public GraphGenerator(SemiGraph<Node> graph) {
private GraphGenerator(InboundSemiGraph<Node> graph) {
myGraph = graph;
myOuts = new LinkedHashMap<Node, Set<Node>>();
buildOuts();
}
public static <T> GraphGenerator<T> create(SemiGraph<T> graph) {
return new GraphGenerator<T>(graph);
}
private void buildOuts() {
Collection<Node> nodes = myGraph.getNodes();
for (Node node : nodes) {
@@ -73,4 +67,20 @@ public class GraphGenerator<Node> implements Graph<Node> {
public Iterator<Node> getOut(Node n) {
return myOuts.get(n).iterator();
}
//<editor-fold desc="Deprecated stuff.">
public interface SemiGraph<Node> extends InboundSemiGraph<Node> {
Collection<Node> getNodes();
Iterator<Node> getIn(Node n);
}
public GraphGenerator(SemiGraph<Node> graph) {
this((InboundSemiGraph<Node>)graph);
}
public static <T> GraphGenerator<T> create(SemiGraph<T> graph) {
return new GraphGenerator<T>((InboundSemiGraph<T>)graph);
}
//</editor-fold>
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2016 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.util.graph;
import java.util.Collection;
import java.util.Iterator;
public interface InboundSemiGraph<Node> {
Collection<Node> getNodes();
Iterator<Node> getIn(Node n);
}
@@ -0,0 +1,25 @@
/*
* Copyright 2000-2016 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.util.graph;
import java.util.Collection;
import java.util.Iterator;
public interface OutboundSemiGraph<Node> {
Collection<Node> getNodes();
Iterator<Node> getOut(Node n);
}