Skip to content

Commit

Permalink
Add incidentEdgeOrder() to the [Value]Graph interface
Browse files Browse the repository at this point in the history
RELNOTES=`graph`: Add `incidentEdgeOrder()` to the `[Value]Graph` interfaces

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=288714914
  • Loading branch information
nymanjens authored and netdpb committed Jan 9, 2020
1 parent 5214a10 commit cde576e
Show file tree
Hide file tree
Showing 42 changed files with 310 additions and 96 deletions.
Expand Up @@ -76,6 +76,10 @@ public abstract class AbstractGraphTest {
/** Creates and returns an instance of the graph to be tested. */
abstract Graph<Integer> createGraph();

abstract boolean allowsSelfLoops();

abstract ElementOrder<Integer> incidentEdgeOrder();

/**
* A proxy method that adds the node {@code n} to the graph being tested. In case of Immutable
* graph implementations, this method should replace {@link #graph} with a new graph that includes
Expand Down Expand Up @@ -224,6 +228,11 @@ public void nodes_noNodes() {
assertThat(graph.nodes()).isEmpty();
}

@Test
public void incidentEdgeOrder_matchesTheValueAtConstruction() {
assertThat(graph.incidentEdgeOrder()).isEqualTo(incidentEdgeOrder());
}

@Test
public void adjacentNodes_oneEdge() {
putEdge(N1, N2);
Expand Down
Expand Up @@ -30,10 +30,6 @@
*/
public abstract class AbstractStandardDirectedGraphTest extends AbstractGraphTest {

abstract boolean allowsSelfLoops();

abstract ElementOrder<Integer> incidentEdgeOrder();

@Override
@Test
public void nodes_checkReturnedSetMutability() {
Expand Down
Expand Up @@ -31,10 +31,6 @@
*/
public abstract class AbstractStandardUndirectedGraphTest extends AbstractGraphTest {

abstract boolean allowsSelfLoops();

abstract ElementOrder<Integer> incidentEdgeOrder();

@After
public void validateUndirectedEdges() {
for (Integer node : graph.nodes()) {
Expand Down
Expand Up @@ -50,6 +50,25 @@ public void copyOfImmutableValueGraph_optimized() {
assertThat(graph2).isSameInstanceAs(graph1);
}

@Test
public void incidentEdgeOrder_stable() {
ImmutableValueGraph<String, Integer> immutableValueGraph =
ImmutableValueGraph.copyOf(ValueGraphBuilder.directed().<String, Integer>build());

assertThat(immutableValueGraph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}

@Test
public void incidentEdgeOrder_fromUnorderedGraph_stable() {
ImmutableValueGraph<String, Integer> immutableValueGraph =
ImmutableValueGraph.copyOf(
ValueGraphBuilder.directed()
.incidentEdgeOrder(ElementOrder.unordered())
.<String, Integer>build());

assertThat(immutableValueGraph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}

@Test
public void immutableValueGraphBuilder_appliesGraphBuilderConfig() {
ImmutableValueGraph<String, Integer> emptyGraph =
Expand Down Expand Up @@ -138,4 +157,23 @@ public void immutableValueGraphBuilder_incidentEdges_preservesIncidentEdgesOrder
EndpointPair.ordered(2, 1), EndpointPair.ordered(2, 3), EndpointPair.ordered(1, 2))
.inOrder();
}

@Test
public void immutableValueGraphBuilder_incidentEdgeOrder_stable() {
ImmutableValueGraph<Integer, String> graph =
ValueGraphBuilder.directed().<Integer, String>immutable().build();

assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}

@Test
public void immutableValueGraphBuilder_fromUnorderedBuilder_incidentEdgeOrder_stable() {
ImmutableValueGraph<Integer, String> graph =
ValueGraphBuilder.directed()
.incidentEdgeOrder(ElementOrder.unordered())
.<Integer, String>immutable()
.build();

assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}
}
Expand Up @@ -27,25 +27,16 @@
@RunWith(Parameterized.class)
public final class StandardImmutableDirectedGraphTest extends AbstractStandardDirectedGraphTest {

@Parameters(name = "allowsSelfLoops={0}, incidentEdgeOrder={1}")
@Parameters(name = "allowsSelfLoops={0}")
public static Collection<Object[]> parameters() {
return Arrays.asList(
new Object[][] {
{false, ElementOrder.unordered()},
{true, ElementOrder.unordered()},
{false, ElementOrder.stable()},
{true, ElementOrder.stable()}
});
return Arrays.asList(new Object[][] {{false}, {true}});
}

private final boolean allowsSelfLoops;
private final ElementOrder<Integer> incidentEdgeOrder;
private ImmutableGraph.Builder<Integer> graphBuilder;

public StandardImmutableDirectedGraphTest(
boolean allowsSelfLoops, ElementOrder<Integer> incidentEdgeOrder) {
public StandardImmutableDirectedGraphTest(boolean allowsSelfLoops) {
this.allowsSelfLoops = allowsSelfLoops;
this.incidentEdgeOrder = incidentEdgeOrder;
}

@Override
Expand All @@ -55,16 +46,12 @@ boolean allowsSelfLoops() {

@Override
ElementOrder<Integer> incidentEdgeOrder() {
return incidentEdgeOrder;
return ElementOrder.stable();
}

@Override
public Graph<Integer> createGraph() {
graphBuilder =
GraphBuilder.directed()
.allowsSelfLoops(allowsSelfLoops())
.incidentEdgeOrder(incidentEdgeOrder)
.immutable();
graphBuilder = GraphBuilder.directed().allowsSelfLoops(allowsSelfLoops()).immutable();
return graphBuilder.build();
}

Expand Down
Expand Up @@ -86,6 +86,22 @@ public void immutableGraphBuilder_copiesGraphBuilder() {
assertThat(emptyGraph.nodeOrder()).isEqualTo(ElementOrder.<String>natural());
}

@Test
public void copyOf_incidentEdgeOrder() {
ImmutableGraph<Object> graph = ImmutableGraph.copyOf(GraphBuilder.undirected().build());

assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}

@Test
public void copyOf_fromUnorderedGraph_incidentEdgeOrder() {
ImmutableGraph<Object> graph =
ImmutableGraph.copyOf(
GraphBuilder.undirected().incidentEdgeOrder(ElementOrder.unordered()).build());

assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}

@Test
public void immutableGraphBuilder_addNode() {
ImmutableGraph<String> graph = GraphBuilder.directed().<String>immutable().addNode("A").build();
Expand Down
Expand Up @@ -28,25 +28,16 @@
public final class StandardImmutableUndirectedGraphTest
extends AbstractStandardUndirectedGraphTest {

@Parameters(name = "allowsSelfLoops={0}, incidentEdgeOrder={1}")
@Parameters(name = "allowsSelfLoops={0}")
public static Collection<Object[]> parameters() {
return Arrays.asList(
new Object[][] {
{false, ElementOrder.unordered()},
{true, ElementOrder.unordered()},
{false, ElementOrder.stable()},
{true, ElementOrder.stable()}
});
return Arrays.asList(new Object[][] {{false}, {true}});
}

private final boolean allowsSelfLoops;
private final ElementOrder<Integer> incidentEdgeOrder;
private ImmutableGraph.Builder<Integer> graphBuilder;

public StandardImmutableUndirectedGraphTest(
boolean allowsSelfLoops, ElementOrder<Integer> incidentEdgeOrder) {
public StandardImmutableUndirectedGraphTest(boolean allowsSelfLoops) {
this.allowsSelfLoops = allowsSelfLoops;
this.incidentEdgeOrder = incidentEdgeOrder;
}

@Override
Expand All @@ -56,16 +47,12 @@ boolean allowsSelfLoops() {

@Override
ElementOrder<Integer> incidentEdgeOrder() {
return incidentEdgeOrder;
return ElementOrder.stable();
}

@Override
public Graph<Integer> createGraph() {
graphBuilder =
GraphBuilder.undirected()
.allowsSelfLoops(allowsSelfLoops())
.incidentEdgeOrder(incidentEdgeOrder)
.immutable();
graphBuilder = GraphBuilder.undirected().allowsSelfLoops(allowsSelfLoops()).immutable();
return graphBuilder.build();
}

Expand Down
Expand Up @@ -51,6 +51,7 @@ public void validateGraphState() {
assertThat(graph.nodes()).isEqualTo(asGraph.nodes());
assertThat(graph.edges()).isEqualTo(asGraph.edges());
assertThat(graph.nodeOrder()).isEqualTo(asGraph.nodeOrder());
assertThat(graph.incidentEdgeOrder()).isEqualTo(asGraph.incidentEdgeOrder());
assertThat(graph.isDirected()).isEqualTo(asGraph.isDirected());
assertThat(graph.allowsSelfLoops()).isEqualTo(asGraph.allowsSelfLoops());

Expand Down Expand Up @@ -120,6 +121,18 @@ public void undirectedGraph() {
assertThat(toString).contains("valueD");
}

@Test
public void incidentEdgeOrder_unordered() {
graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.unordered()).build();
assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.unordered());
}

@Test
public void incidentEdgeOrder_stable() {
graph = ValueGraphBuilder.directed().incidentEdgeOrder(ElementOrder.stable()).build();
assertThat(graph.incidentEdgeOrder()).isEqualTo(ElementOrder.stable());
}

@Test
public void hasEdgeConnecting_directed_correct() {
graph = ValueGraphBuilder.directed().build();
Expand Down
Expand Up @@ -97,6 +97,11 @@ && nodes().contains(endpointPair.nodeU())
};
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return ElementOrder.unordered();
}

@Override
public Set<EndpointPair<N>> incidentEdges(N node) {
checkNotNull(node);
Expand Down
Expand Up @@ -106,6 +106,13 @@ public ElementOrder<N> nodeOrder() {
return AbstractNetwork.this.nodeOrder();
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
// TODO(b/142723300): Return AbstractNetwork.this.incidentEdgeOrder() once Network has that
// method.
return ElementOrder.unordered();
}

@Override
public boolean isDirected() {
return AbstractNetwork.this.isDirected();
Expand Down
Expand Up @@ -67,6 +67,11 @@ public ElementOrder<N> nodeOrder() {
return AbstractValueGraph.this.nodeOrder();
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return AbstractValueGraph.this.incidentEdgeOrder();
}

@Override
public Set<N> adjacentNodes(N node) {
return AbstractValueGraph.this.adjacentNodes(node);
Expand Down
7 changes: 7 additions & 0 deletions android/guava/src/com/google/common/graph/BaseGraph.java
Expand Up @@ -56,6 +56,13 @@ interface BaseGraph<N> extends SuccessorsFunction<N>, PredecessorsFunction<N> {
/** Returns the order of iteration for the elements of {@link #nodes()}. */
ElementOrder<N> nodeOrder();

/**
* Returns an {@link ElementOrder} that specifies the order of iteration for the elements of
* {@link #edges()}, {@link #adjacentNodes(Object)}, {@link #predecessors(Object)}, {@link
* #successors(Object)} and {@link #incidentEdges(Object)}.
*/
ElementOrder<N> incidentEdgeOrder();

//
// Element-level accessors
//
Expand Down
Expand Up @@ -49,6 +49,11 @@ final class ConfigurableMutableValueGraph<N, V> extends ConfigurableValueGraph<N
incidentEdgeOrder = builder.incidentEdgeOrder.cast();
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return incidentEdgeOrder;
}

@Override
@CanIgnoreReturnValue
public boolean addNode(N node) {
Expand Down
Expand Up @@ -57,6 +57,11 @@ public ElementOrder<N> nodeOrder() {
return delegate().nodeOrder();
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return delegate().incidentEdgeOrder();
}

@Override
public Set<N> adjacentNodes(N node) {
return delegate().adjacentNodes(node);
Expand Down
Expand Up @@ -59,6 +59,11 @@ public ElementOrder<N> nodeOrder() {
return delegate().nodeOrder();
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return delegate().incidentEdgeOrder();
}

@Override
public Set<N> adjacentNodes(N node) {
return delegate().adjacentNodes(node);
Expand Down
8 changes: 8 additions & 0 deletions android/guava/src/com/google/common/graph/Graph.java
Expand Up @@ -140,6 +140,14 @@ public interface Graph<N> extends BaseGraph<N> {
@Override
ElementOrder<N> nodeOrder();

/**
* Returns an {@link ElementOrder} that specifies the order of iteration for the elements of
* {@link #edges()}, {@link #adjacentNodes(Object)}, {@link #predecessors(Object)}, {@link
* #successors(Object)} and {@link #incidentEdges(Object)}.
*/
@Override
ElementOrder<N> incidentEdgeOrder();

//
// Element-level accessors
//
Expand Down
4 changes: 2 additions & 2 deletions android/guava/src/com/google/common/graph/GraphBuilder.java
Expand Up @@ -91,8 +91,8 @@ public static GraphBuilder<Object> undirected() {
public static <N> GraphBuilder<N> from(Graph<N> graph) {
return new GraphBuilder<N>(graph.isDirected())
.allowsSelfLoops(graph.allowsSelfLoops())
.nodeOrder(graph.nodeOrder());
// TODO(b/142723300): Add incidentEdgeOrder
.nodeOrder(graph.nodeOrder())
.incidentEdgeOrder(graph.incidentEdgeOrder());
}

/**
Expand Down
5 changes: 5 additions & 0 deletions android/guava/src/com/google/common/graph/ImmutableGraph.java
Expand Up @@ -72,6 +72,11 @@ public static <N> ImmutableGraph<N> copyOf(ImmutableGraph<N> graph) {
return checkNotNull(graph);
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return ElementOrder.stable();
}

private static <N> ImmutableMap<N, GraphConnections<N, Presence>> getNodeConnections(
Graph<N> graph) {
// ImmutableMap.Builder maintains the order of the elements as inserted, so the map will have
Expand Down
Expand Up @@ -66,6 +66,11 @@ public static <N, V> ImmutableValueGraph<N, V> copyOf(ImmutableValueGraph<N, V>
return checkNotNull(graph);
}

@Override
public ElementOrder<N> incidentEdgeOrder() {
return ElementOrder.stable();
}

@Override
public ImmutableGraph<N> asGraph() {
return new ImmutableGraph<N>(this); // safe because the view is effectively immutable
Expand Down
8 changes: 8 additions & 0 deletions android/guava/src/com/google/common/graph/ValueGraph.java
Expand Up @@ -150,6 +150,14 @@ public interface ValueGraph<N, V> extends BaseGraph<N> {
@Override
ElementOrder<N> nodeOrder();

/**
* Returns an {@link ElementOrder} that specifies the order of iteration for the elements of
* {@link #edges()}, {@link #adjacentNodes(Object)}, {@link #predecessors(Object)}, {@link
* #successors(Object)} and {@link #incidentEdges(Object)}.
*/
@Override
ElementOrder<N> incidentEdgeOrder();

//
// Element-level accessors
//
Expand Down

0 comments on commit cde576e

Please sign in to comment.