package graphs; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.Vector; import system.DataLocator; import system.Message; import system.Worker; import api.Vertex; import exceptions.DataNotFoundException; import exceptions.IllegalInputException; /** * Represents the physical partition of a graph in memory * * @author Manasa Chandrasekhar * @author Kowshik Prakasam * */ public class GraphPartition implements Serializable { /** * */ private static final long serialVersionUID = -7131394295735085039L; // transient---------- private transient Worker aWorker; private transient DataLocator aDataLocator; // -------------------- private List<Vertex> listOfVertices; private String partitionFile; private String vertexClassName; private int partitionID; public int getPartitionID() { return this.partitionID; } /** * Converts the partition into a String representation. Each line in the * string representation is obtained by calling the vertex's toString() * method */ @Override public String toString() { StringBuffer strBuf = new StringBuffer(); for (Vertex v : listOfVertices) { strBuf.append(v.toString()); strBuf.append("\n"); } return strBuf.toString(); } /** * * @param partitionID * A unique number to represent this partition * @param listOfVertices * List of vertices assigned to this partition */ public GraphPartition(int partitionID, List<Vertex> listOfVertices) { this.partitionID = partitionID; this.listOfVertices = listOfVertices; for (Vertex v : listOfVertices) { v.setGraphPartition(this); } } /** * * @return Returns the partiton file using which this partition was * initially populated. */ public String getPartitionFile() { return this.partitionFile; } public GraphPartition(int partitionID, String inputFile, String vertexClassName, Worker aWorker, DataLocator aDataLocator) throws IOException, IllegalInputException, InstantiationException, IllegalAccessException, ClassNotFoundException { this(inputFile, vertexClassName); this.aDataLocator = aDataLocator; this.aWorker = aWorker; this.partitionID = partitionID; this.listOfVertices = readFromFile(inputFile); } /** * * @param inputFile * File containing an adjacency list representation of the graph * @param vertexClassName * Name of the vertex class provided by the application * programmer * @throws IOException * @throws IllegalInputException * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ public GraphPartition(String inputFile, String vertexClassName) throws IOException, IllegalInputException, InstantiationException, IllegalAccessException, ClassNotFoundException { this.vertexClassName = vertexClassName; this.partitionFile = inputFile; } /** * Reads the physical partition (in adjacency list format) from file and * caches it. Each line in the file is a record in an adjacency list. * * @param inputFile File containing an adjacency list representation of the graph * @return A list of vertices representing the partition * @throws IOException * @throws IllegalInputException * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ public List<Vertex> readFromFile(String inputFile) throws IOException, IllegalInputException, InstantiationException, IllegalAccessException, ClassNotFoundException { BufferedReader buffReader = new BufferedReader( new FileReader(inputFile)); String line = null; List<Vertex> listOfVertices = new Vector<Vertex>(); while ((line = buffReader.readLine()) != null) { Vertex aNewVertex = (Vertex) (Class.forName(vertexClassName) .newInstance()); aNewVertex.initialize(line, this); String vtxSolnFile = aDataLocator.getVertexFile(aNewVertex .getVertexID()); aNewVertex.setSolutionFile(vtxSolnFile); listOfVertices.add(aNewVertex); } buffReader.close(); return listOfVertices; } /** * Serializes the graph to a partition file in adjacency list format * @param outputFile File where the output should be written * @throws IOException */ public void writeToFile(String outputFile) throws IOException { BufferedWriter buffWriter = new BufferedWriter(new FileWriter( outputFile)); for (Vertex v : listOfVertices) { String vertexStr = v.toString(); buffWriter.write(vertexStr + "\n"); } buffWriter.close(); } /* * Frees the cached partition. */ public void freePartition() { this.listOfVertices = null; } /** * Returns the list of vertices of this partition * @return */ public List<Vertex> getVertices() { return this.listOfVertices; } /** * Propagates a message to a workers * @param msg */ public void send(Message msg) { aWorker.send(msg); } /** * Returns the superstep number * @return */ public int getSuperStep() { return aWorker.getSuperStep(); } /** * Returns the total number of vertices in the input graph * @return */ public int getTotalNumVertices() { return aWorker.getNumVertices(); } /** * Writes solutions generaated by each vertex to its corresponding output file * @throws IOException */ public void writeSolutions() throws IOException { for (Vertex v : getVertices()) { v.writeSolution(); } } /** * * Saves the state of the partition to disk * * @throws IOException * @throws DataNotFoundException * */ public void saveState() throws IOException, DataNotFoundException { String chkPointFile = aDataLocator.getCheckpointFile(getSuperStep(), getPartitionID()); FileOutputStream fos = null; ObjectOutputStream out = null; fos = new FileOutputStream(chkPointFile); out = new ObjectOutputStream(fos); out.writeObject(this); fos.close(); out.close(); String chkPointFlag = aDataLocator.getCheckpointFlag(getSuperStep(), getPartitionID()); File chkPointFlagFile = new File(chkPointFlag); if (chkPointFlagFile.exists()) { chkPointFlagFile.delete(); } if (!chkPointFlagFile.createNewFile()) { String msg = "Unable to create location : " + chkPointFlagFile.getAbsolutePath(); throw new DataNotFoundException(msg); } } /** * Clears the vertex message queues */ public void clearVertexQueues() { for (int index = 0; index < listOfVertices.size(); index++) { Vertex v = listOfVertices.get(index); v.clearMessageQueue(); } } /** * @param Sets the worker thread that controls this partition */ public void setWorker(Worker aWorker) { this.aWorker = aWorker; } /** * @param Sets the DataLocator for this partition */ public void setDataLocator(DataLocator aDataLocator) { this.aDataLocator = aDataLocator; } /** * @return */ public List<Message> retrieveAllMsgs() { List<Message> allMsgs=new Vector<Message>(); for(Vertex v : this.listOfVertices){ allMsgs.addAll(v.getMessages()); v.clearMessageQueue(); } return allMsgs; } }