Skip to content

Commit

Permalink
Merge pull request #191 from ProgrammingLife2017/caching
Browse files Browse the repository at this point in the history
Caching improved
  • Loading branch information
mvanmeerten authored Jun 2, 2017
2 parents 03d083a + 94c3dbb commit 44d24d9
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ private Set<Segment> drawDFS(Segment origin, Segment node,
drawnNodes.add(node);

int childCount = 0;
for (Segment child : this.getGraph().getChildren(node)) {
for (int child : this.getGraph().getChildren(node)) {
XYCoordinate newOffset = offset.add(HORIZONTAL_OFFSET)
.add(node.getWidthCoordinate())
.setY(INITIAL_OFFSET.getY() + (int) (CHILD_OFFSET * childCount * node.getHeight()));
this.drawDFS(node, child, newOffset, maxDepth - 1, drawnNodes);
this.drawDFS(node, new Segment(this.graph, child), newOffset, maxDepth - 1, drawnNodes);
childCount++;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package programminglife.gui.controller;

import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
Expand Down Expand Up @@ -134,6 +136,7 @@ public void update(Observable o, Object arg) {
this.setGraph(graph);
} else if (arg instanceof Exception) {
Exception e = (Exception) arg;
e.printStackTrace();
Alerts.error(e.getMessage());
}
} else if (o instanceof FileProgressCounter) {
Expand All @@ -153,6 +156,7 @@ public void update(Observable o, Object arg) {
public void setGraph(GenomeGraph graph) {
this.graphController.setGraph(graph);
disableGraphUIElements(graph == null);
Platform.runLater(() -> ProgrammingLife.getStage().setTitle(graph.getID()));

if (graph != null) {
Console.println("[%s] Graph was set to %s.", Thread.currentThread().getName(), graph.getID());
Expand Down
123 changes: 86 additions & 37 deletions src/main/java/programminglife/model/GenomeGraph.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package programminglife.model;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.NotImplementedException;
import org.jetbrains.annotations.NotNull;
import programminglife.model.exception.NodeExistsException;
import programminglife.parser.Cache;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
* Created by marti_000 on 25-4-2017.
Expand All @@ -16,10 +16,6 @@ public class GenomeGraph implements Graph {
private String id;
private Cache cache;

// TODO cache graph structure
private Map<Integer, Set<Integer>> children;
private Map<Integer, Set<Integer>> parents;

// TODO cache genomes
private Map<String, Genome> genomes;

Expand All @@ -28,19 +24,7 @@ public class GenomeGraph implements Graph {
* @param id id of the graph
*/
public GenomeGraph(String id) {
this(id, new HashMap<>(), new HashMap<>());
}

/**
* The constructor for a GenomeGraph.
* @param id String.
* @param children {@link Set} which contains the children.
* @param parents {@link Set} which contains the parents.
*/
public GenomeGraph(String id, Map<Integer, Set<Integer>> children, Map<Integer, Set<Integer>> parents) {
this.id = id;
this.children = children;
this.parents = parents;
this.genomes = new HashMap<>();
this.cache = new Cache(id);
}
Expand All @@ -55,11 +39,11 @@ public String getID() {

@Override
public void addNode(Node node) {
this.addNode(node, new HashSet<>(), new HashSet<>());
this.addNode(node, new int[0], new int[0]);
}

@Override
public void addNode(Node node, Set<Node> children, Set<Node> parents) {
public void addNode(Node node, int[] children, int[] parents) {
if (this.contains(node)) {
throw new NodeExistsException(String.format("%s already exists in graph %s",
node.toString(), this.getID()));
Expand All @@ -70,48 +54,46 @@ public void addNode(Node node, Set<Node> children, Set<Node> parents) {

@Override
public void replaceNode(Node node) {
this.replaceNode(node, new HashSet<>(), new HashSet<>());
this.replaceNode(node, new int[0], new int[0]);
}

@Override
public void replaceNode(Node node, Set<Node> children, Set<Node> parents) {
this.children.put(node.getIdentifier(), children.stream().map(c ->
c.getIdentifier()).collect(Collectors.toSet()));
this.parents.put(node.getIdentifier(), parents.stream().map(p ->
p.getIdentifier()).collect(Collectors.toSet()));
public void replaceNode(Node node, int[] children, int[] parents) {
this.cache.getChildrenAdjacencyMap().put(node.getIdentifier(), children);
this.cache.getParentsAdjacencyMap().put(node.getIdentifier(), parents);
}

/**
* Get the number of nodes in the {@link GenomeGraph}.
* @return the number of nodes
*/
public int size() {
assert (children.size() == parents.size());
return this.children.size();
assert (this.cache.getChildrenAdjacencyMap().size() == this.cache.getParentsAdjacencyMap().size());
return this.cache.getChildrenAdjacencyMap().size();
}

@Override
public Set<Segment> getChildren(Node node) {
public int[] getChildren(Node node) {
return this.getChildren(node.getIdentifier());
}

@Override
public Set<Segment> getChildren(int nodeID) {
return this.children.get(nodeID).stream().map(id -> new Segment(this, id)).collect(Collectors.toSet());
public int[] getChildren(int nodeID) {
return this.cache.getChildrenAdjacencyMap().get(nodeID);
}

@Override
public Set<Segment> getParents(Node node) {
public int[] getParents(Node node) {
return this.getParents(node.getIdentifier());
}

@Override
public Set<Segment> getParents(int nodeID) {
return this.parents.get(nodeID).stream().map(id -> new Segment(this, id)).collect(Collectors.toSet());
public int[] getParents(int nodeID) {
return this.cache.getParentsAdjacencyMap().get(nodeID);
}

@Override
public Set<Genome> getGenomes(Node node) {
public int[] getGenomes(Node node) {
throw new NotImplementedException("GenomeGraph#getGenomes(Node) is not yet implemented");
}

Expand All @@ -122,7 +104,7 @@ public boolean contains(Node node) {

@Override
public boolean contains(int nodeID) {
return this.children.containsKey(nodeID);
return this.cache.getChildrenAdjacencyMap().containsKey(nodeID);
}

@Override
Expand All @@ -137,7 +119,26 @@ public void addEdge(Node source, Node destination) {
* @param child Node of the child to be added.
*/
private void addChild(Node node, Node child) {
this.children.get(node.getIdentifier()).add(child.getIdentifier());
if (this.cache.getCurrentParentID() == -1) {
this.cache.setCurrentParentID(node.getIdentifier());
}

if (node.getIdentifier() == this.cache.getCurrentParentID()) {
// if same parent as previous link || if first link of graph,
// just add the child
this.cache.getCurrentParentChildren().add(child.getIdentifier());
} else {
// write previous list to cache
int[] oldChildren = this.getChildren(this.cache.getCurrentParentID());
int[] allChildren = this.append(oldChildren, this.cache.getCurrentParentChildren());
this.cache.getChildrenAdjacencyMap().put(this.cache.getCurrentParentID(), allChildren);

// reset node id
this.cache.setCurrentParentID(node.getIdentifier());
// reset children list
this.cache.setCurrentParentChildren(new LinkedList<>());
this.cache.getCurrentParentChildren().add(child.getIdentifier());
}
}

/**
Expand All @@ -146,7 +147,11 @@ private void addChild(Node node, Node child) {
* @param parent Node of the parent to be added.
*/
private void addParent(Node node, Node parent) {
this.parents.get(node.getIdentifier()).add(parent.getIdentifier());
int[] oldParents = this.getParents(node.getIdentifier());
//TODO find a way to do this more efficient
int[] newParents = Arrays.copyOf(oldParents, oldParents.length + 1);
newParents[newParents.length - 1] = parent.getIdentifier();
this.cache.getParentsAdjacencyMap().put(node.getIdentifier(), newParents);
}

/**
Expand Down Expand Up @@ -230,6 +235,22 @@ public int getSequenceLength(int nodeID) {
return this.cache.getSequenceLength(nodeID);
}

/**
* Get the number of lines in the GFA file.
* @return # of lines
*/
public int getNumberOfLines() {
return this.cache.getNumberOfLines();
}

/**
* Set the number of lines in the GFA file.
* @param numberOfLines # of lines
*/
public void setNumberOfLines(int numberOfLines) {
this.cache.setNumberOfLines(numberOfLines);
}

/**
* Roll back the latest changes to the cache.
* @throws IOException when something strange happens during deletion
Expand Down Expand Up @@ -263,4 +284,32 @@ public void close() throws IOException {
this.cache = null;
}
}

/**
* Append an {@link List<Integer>} to a int[].
* @param oldArray the int[] to go first
* @param newList the {@link List<Integer>} to be appended
* @return a int[] consisting of all elements
*/
private int[] append(int[] oldArray, List<Integer> newList) {
int[] newArray;
if (oldArray == null) {
newArray = oldArray;
} else {
newArray = ArrayUtils.addAll(oldArray, newList.stream().mapToInt(i -> i).toArray());
}

return newArray;
}

/**
* Cache the group of edges from the last parent.
*
* Necessary because these are skipped during parsing.
*/
public void cacheLastEdges() {
int[] oldChildren = this.getChildren(this.cache.getCurrentParentID());
int[] allChildren = this.append(oldChildren, this.cache.getCurrentParentChildren());
this.cache.getChildrenAdjacencyMap().put(this.cache.getCurrentParentID(), allChildren);
}
}
34 changes: 16 additions & 18 deletions src/main/java/programminglife/model/Graph.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package programminglife.model;

import java.util.Set;

/**
* Interface for the graph.
*/
Expand All @@ -21,10 +19,10 @@ public interface Graph {
/**
* Add a node to the graph.
* @param node Node.
* @param children {@link Set} which contains the children.
* @param parents {@link Set} which contains the parents.
* @param children int[] which contains the children.
* @param parents int[] which contains the parents.
*/
void addNode(Node node, Set<Node> children, Set<Node> parents);
void addNode(Node node, int[] children, int[] parents);

/**
* Replaces a node.
Expand All @@ -35,10 +33,10 @@ public interface Graph {
/**
* Replaces a node.
* @param node Node.
* @param children {@link Set} of the children.
* @param parents {@link Set} of the parents.
* @param children int[] of the children.
* @param parents int[] of the parents.
*/
void replaceNode(Node node, Set<Node> children, Set<Node> parents);
void replaceNode(Node node, int[] children, int[] parents);

/**
* Gives the size of a graph.
Expand All @@ -49,37 +47,37 @@ public interface Graph {
/**
* getter for the Children of a node.
* @param node the {@link Node} to get the children from.
* @return {@link Set} of the children.
* @return int[] of the children.
*/
Set<Segment> getChildren(Node node);
int[] getChildren(Node node);

/**
* getter for the Children of a node.
* @param nodeID the node ID to get children from
* @return {@link Set} of the children.
* @return int[] of the children.
*/
Set<Segment> getChildren(int nodeID);
int[] getChildren(int nodeID);

/**
* getter for the Parents of a node.
* @param node Node.
* @return {@link Set} of the parents.
* @return int[] of the parents.
*/
Set<Segment> getParents(Node node);
int[] getParents(Node node);

/**
* getter for the Parents of a node.
* @param nodeID int.
* @return {@link Set} of the parents.
* @return int[] of the parents.
*/
Set<Segment> getParents(int nodeID);
int[] getParents(int nodeID);

/**
* getter for the Genomes of a node.
* @param node Node.
* @return {@link Set}.
* @return int[].
*/
Set<Genome> getGenomes(Node node);
int[] getGenomes(Node node);

/**
* Checks to see if the graph contains a certain node.
Expand Down
Loading

0 comments on commit 44d24d9

Please sign in to comment.