package uk.ac.rhul.cs.cl1.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import uk.ac.rhul.cs.cl1.TaskMonitor;
import uk.ac.rhul.cs.cl1.TaskMonitorSupport;
import uk.ac.rhul.cs.graph.Graph;
import uk.ac.rhul.cs.utils.UniqueIDGenerator;
/**
* Reads a graph specified by an edge list representation from an input stream
* @author ntamas
*/
public class EdgeListReader implements GraphReader, TaskMonitorSupport {
/**
* Task monitor that will be used by the reader to report its progress.
*/
private TaskMonitor taskMonitor;
/**
* Reads a graph specified by an edge list representation
* from the given reader object.
*
* @param reader the reader being used
*/
public Graph readGraph(Reader reader) throws IOException {
Graph result = new Graph();
UniqueIDGenerator<String> nodeGen = new UniqueIDGenerator<String>(result);
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
int node1, node2;
int startIndex, endIndex;
int numEdges = 0;
double weight;
if (taskMonitor != null)
{
taskMonitor.setPercentCompleted(-1);
taskMonitor.setStatus("Reading graph...");
}
while ((line = bufferedReader.readLine()) != null) {
if (line.length() == 0)
continue;
if (line.charAt(0) == '#' || line.charAt(0) == '%')
continue;
startIndex = nextNonWhitespace(line, 0);
if (startIndex == -1)
continue;
endIndex = nextWhitespace(line, startIndex);
if (endIndex == -1)
continue;
node1 = nodeGen.get(line.substring(startIndex, endIndex));
startIndex = nextNonWhitespace(line, endIndex);
if (startIndex == -1)
continue;
endIndex = nextWhitespace(line, startIndex);
if (endIndex == -1) {
node2 = nodeGen.get(line.substring(startIndex));
weight = 1.0;
} else {
node2 = nodeGen.get(line.substring(startIndex, endIndex));
startIndex = nextNonWhitespace(line, endIndex);
if (startIndex == -1) {
weight = 1.0;
} else {
weight = Double.parseDouble(line.substring(startIndex));
}
}
result.createEdge(node1, node2, weight);
numEdges++;
if (taskMonitor != null && numEdges % 100000 == 0) {
taskMonitor.setPercentCompleted(-1);
taskMonitor.setStatus(result.getNodeCount() + " node(s), " + numEdges + " edge(s)");
}
}
if (taskMonitor != null) {
taskMonitor.setPercentCompleted(100);
taskMonitor.setStatus(result.getNodeCount() + " node(s), " + numEdges + " edge(s)");
}
return result;
}
public void setTaskMonitor(TaskMonitor taskMonitor) {
this.taskMonitor = taskMonitor;
}
/**
* Given a string and a starting index, returns the next index where
* a space or Tab character occurs.
*
* @param string the string
* @param fromIndex the start index
* @return the smallest index no smaller than startIndex such that the char
* at the given index is a space or a Tab, or -1 if there are
* no whitespace characters after the given start index
*/
private int nextWhitespace(String string, int fromIndex) {
int i, n = string.length();
char ch;
for (i = fromIndex; i < n; i++) {
ch = string.charAt(i);
if (ch == ' ' || ch == '\t') {
return i;
}
}
return -1;
}
/**
* Given a string and a starting index, returns the next index where
* anything else than a space or Tab character occurs.
*
* @param string the string
* @param fromIndex the start index
* @return the smallest index no smaller than startIndex such that the char
* at the given index is not a space or a Tab, or -1 if there are
* no non-whitespace characters after the given start index
*/
private int nextNonWhitespace(String string, int fromIndex) {
int i, n = string.length();
char ch;
for (i = fromIndex; i < n; i++) {
ch = string.charAt(i);
if (ch != ' ' && ch != '\t') {
return i;
}
}
return -1;
}
}