Skip to content

Commit

Permalink
close #125 : new module hipster-extensions containing implementations…
Browse files Browse the repository at this point in the history
… of HipsterGraph using guava tables
  • Loading branch information
gonzalezsieira committed Apr 28, 2015
1 parent 3d8ad09 commit 5d02b4f
Show file tree
Hide file tree
Showing 6 changed files with 406 additions and 0 deletions.
43 changes: 43 additions & 0 deletions hipster-extensions/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hipster-pom</artifactId>
<groupId>es.usc.citius.hipster</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>hipster-extensions</artifactId>

<properties>
<hipster.root.dir>${project.basedir}/..</hipster.root.dir>
</properties>

<dependencies>
<dependency>
<groupId>es.usc.citius.hipster</groupId>
<artifactId>hipster-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>es.usc.citius.hipster</groupId>
<artifactId>hipster-third-party-graphs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- Using Guava annotations require this dependency-->
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.0</version>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2014 CITIUS <http://citius.usc.es>, University of Santiago de Compostela.
*
* 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 es.usc.citius.hipster.extensions.graph;

import com.google.common.base.Preconditions;
import es.usc.citius.hipster.graph.GraphEdge;
import es.usc.citius.hipster.graph.HipsterDirectedGraph;

/**
* Implementation of a HipsterDirectedGraph using a Guava Hash Table.
*
* @author Pablo Rodríguez Mier <<a href="mailto:[email protected]">[email protected]</a>>
*/
public class HashBasedHipsterDirectedGraph<V,E> extends HashBasedHipsterGraph<V,E> implements HipsterDirectedGraph<V,E> {

@Override
public GraphEdge<V,E> connect(V v1, V v2, E value){
Preconditions.checkArgument(v1 != null && v2 != null, "Vertices cannot be null");
GraphEdge<V,E> edge = new GraphEdge<V, E>(v1, v2, value, true);
graphTable.put(v1, v2, edge);
disconnected.remove(v1);
disconnected.remove(v2);
return edge;
}

@Override
public Iterable<GraphEdge<V, E>> outgoingEdgesOf(V vertex) {
return graphTable.row(vertex).values();
}

@Override
public Iterable<GraphEdge<V, E>> incomingEdgesOf(V vertex) {
return graphTable.column(vertex).values();
}

public static <V,E> HashBasedHipsterDirectedGraph<V, E> create() {
return new HashBasedHipsterDirectedGraph<V, E>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright 2014 CITIUS <http://citius.usc.es>, University of Santiago de Compostela.
*
* 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 es.usc.citius.hipster.extensions.graph;

import com.google.common.base.Preconditions;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Sets;
import es.usc.citius.hipster.graph.GraphEdge;
import es.usc.citius.hipster.graph.HipsterGraph;

import java.util.HashSet;
import java.util.Set;

/**
* Implementation of a HipsterGraph using a Guava Hash Table.
*
* @author Pablo Rodríguez Mier <<a href="mailto:[email protected]">[email protected]</a>>
*/
public class HashBasedHipsterGraph<V,E> implements HipsterGraph<V,E> {
protected HashBasedTable<V,V,GraphEdge<V,E>> graphTable = HashBasedTable.create();
// keep extra info for all those disconnected vertices
protected Set<V> disconnected = new HashSet<V>();

public void add(V v){
if (!graphTable.containsColumn(v) && !graphTable.containsRow(v)){
disconnected.add(v);
}
}

private <T> boolean greaterThan(int size, Iterable<T> iterable){
int elems = 0;
for(T t : iterable){
elems++;
if (elems > size){
return true;
}
}
return false;
}

public void remove(V v){
// Get vertices connected with this one
for(GraphEdge<V,E> edge : edgesOf(v)){
V connectedVertex = edge.getVertex1().equals(v) ? edge.getVertex2() : edge.getVertex1();
// Is this vertex connected with a different vertex?
if (!greaterThan(1, edgesOf(connectedVertex))){
disconnected.add(connectedVertex);
}
}
if (graphTable.containsRow(v)){
graphTable.row(v).clear();
}
if (graphTable.containsColumn(v)){
graphTable.column(v).clear();
}
// Check for disconnected vertices
disconnected.remove(v); // v no longer exists

}

public void remove(V v, GraphEdge<V,E> edge){
// Try to remove vertex from row/columns
Preconditions.checkArgument(edge.getVertex1().equals(v) || edge.getVertex2().equals(v), "Edge is not connected with the vertex");
V opposite = edge.getVertex1().equals(v) ? edge.getVertex2() : edge.getVertex1();
graphTable.row(v).remove(opposite);
}

public GraphEdge<V,E> connect(V v1, V v2, E value){
Preconditions.checkArgument(v1 != null && v2 != null, "Vertices cannot be null");
GraphEdge<V,E> edge = new GraphEdge<V, E>(v1, v2, value);
graphTable.put(v1, v2, edge);
graphTable.put(v2, v1, edge);
disconnected.remove(v1);
disconnected.remove(v2);
return edge;
}

@Override
public Iterable<GraphEdge<V, E>> edges() {
return graphTable.values();
}

@Override
public Iterable<V> vertices() {
return Sets.union(Sets.union(graphTable.rowKeySet(), graphTable.columnKeySet()), disconnected);
}

@Override
public Iterable<GraphEdge<V, E>> edgesOf(V vertex) {
return Sets.union(Sets.newHashSet(graphTable.row(vertex).values()), Sets.newHashSet(graphTable.column(vertex).values()));
}

public static <V,E> HashBasedHipsterGraph<V, E> create() {
return new HashBasedHipsterGraph<V, E>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2014 CITIUS <http://citius.usc.es>, University of Santiago de Compostela.
*
* 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 es.usc.citius.hipster.extensions.graph;

import com.google.common.collect.Sets;
import es.usc.citius.hipster.graph.GraphEdge;
import org.junit.Before;
import org.junit.Test;

import java.util.HashSet;
import java.util.Set;

import static org.junit.Assert.assertEquals;


public class HashBasedHipsterDirectedGraphTest extends HashBasedHipsterGraphTest {
private HashBasedHipsterDirectedGraph<String, Double> directedGraph;

@Before
@Override
public void setUp() {
directedGraph = HashBasedHipsterDirectedGraph.create();
directedGraph.connect("A", "B", 4d);
directedGraph.connect("A", "C", 2d);
directedGraph.connect("B", "C", 5d);
directedGraph.connect("B", "D", 10d);
directedGraph.connect("C", "E", 3d);
directedGraph.connect("D", "F", 11d);
directedGraph.connect("E", "D", 4d);
graph = directedGraph;
}

@Test
public void testConnect() throws Exception {
directedGraph.connect("F", "G", 1d);
assertEquals("F", directedGraph.incomingEdgesOf("G").iterator().next().getVertex1());
}

@Test
public void testOutgoingEdgesOf() throws Exception {
Set<GraphEdge<String, Double>> expected = new HashSet<GraphEdge<String, Double>>();
expected.add(new GraphEdge<String, Double>("B", "C", 5d, true));
expected.add(new GraphEdge<String, Double>("B", "D", 10d, true));
assertEquals(expected, Sets.newHashSet(directedGraph.outgoingEdgesOf("B")));
}

@Test
public void testIncomingEdgesOf() throws Exception {
Set<GraphEdge<String, Double>> expected = new HashSet<GraphEdge<String, Double>>();
expected.add(new GraphEdge<String, Double>("B", "C", 5d, true));
expected.add(new GraphEdge<String, Double>("A", "C", 2d, true));
assertEquals(expected, Sets.newHashSet(directedGraph.incomingEdgesOf("C")));
}

@Test
@Override
public void testEdges() throws Exception {
Set<GraphEdge<String, Double>> expected = new HashSet<GraphEdge<String, Double>>();
expected.add(new GraphEdge<String, Double>("A", "B", 4d, true));
expected.add(new GraphEdge<String, Double>("A", "C", 2d, true));
expected.add(new GraphEdge<String, Double>("B", "C", 5d, true));
expected.add(new GraphEdge<String, Double>("B", "D", 10d, true));
expected.add(new GraphEdge<String, Double>("C", "E", 3d, true));
expected.add(new GraphEdge<String, Double>("D", "F", 11d, true));
expected.add(new GraphEdge<String, Double>("E", "D", 4d, true));
assertEquals(expected, Sets.newHashSet(graph.edges()));
}

@Test
@Override
public void testEdgesOf() throws Exception {
Set<GraphEdge<String,Double>> expected = new HashSet<GraphEdge<String, Double>>();
expected.add(new GraphEdge<String, Double>("B", "D", 10d, true));
expected.add(new GraphEdge<String, Double>("A", "B", 4d, true));
expected.add(new GraphEdge<String, Double>("B", "C", 5d, true));
assertEquals(expected, graph.edgesOf("B"));
}
}
Loading

0 comments on commit 5d02b4f

Please sign in to comment.