1
1
package programminglife .model ;
2
2
3
+ import org .apache .commons .lang3 .ArrayUtils ;
3
4
import org .apache .commons .lang3 .NotImplementedException ;
4
5
import org .jetbrains .annotations .NotNull ;
5
6
import programminglife .model .exception .NodeExistsException ;
6
7
import programminglife .parser .Cache ;
7
8
8
9
import java .io .IOException ;
9
10
import java .util .*;
10
- import java .util .stream .Collectors ;
11
11
12
12
/**
13
13
* Created by marti_000 on 25-4-2017.
@@ -16,10 +16,6 @@ public class GenomeGraph implements Graph {
16
16
private String id ;
17
17
private Cache cache ;
18
18
19
- // TODO cache graph structure
20
- private Map <Integer , Set <Integer >> children ;
21
- private Map <Integer , Set <Integer >> parents ;
22
-
23
19
// TODO cache genomes
24
20
private Map <String , Genome > genomes ;
25
21
@@ -28,19 +24,7 @@ public class GenomeGraph implements Graph {
28
24
* @param id id of the graph
29
25
*/
30
26
public GenomeGraph (String id ) {
31
- this (id , new HashMap <>(), new HashMap <>());
32
- }
33
-
34
- /**
35
- * The constructor for a GenomeGraph.
36
- * @param id String.
37
- * @param children {@link Set} which contains the children.
38
- * @param parents {@link Set} which contains the parents.
39
- */
40
- public GenomeGraph (String id , Map <Integer , Set <Integer >> children , Map <Integer , Set <Integer >> parents ) {
41
27
this .id = id ;
42
- this .children = children ;
43
- this .parents = parents ;
44
28
this .genomes = new HashMap <>();
45
29
this .cache = new Cache (id );
46
30
}
@@ -55,11 +39,11 @@ public String getID() {
55
39
56
40
@ Override
57
41
public void addNode (Node node ) {
58
- this .addNode (node , new HashSet <>() , new HashSet <>() );
42
+ this .addNode (node , new int [ 0 ] , new int [ 0 ] );
59
43
}
60
44
61
45
@ Override
62
- public void addNode (Node node , Set < Node > children , Set < Node > parents ) {
46
+ public void addNode (Node node , int [] children , int [] parents ) {
63
47
if (this .contains (node )) {
64
48
throw new NodeExistsException (String .format ("%s already exists in graph %s" ,
65
49
node .toString (), this .getID ()));
@@ -70,48 +54,46 @@ public void addNode(Node node, Set<Node> children, Set<Node> parents) {
70
54
71
55
@ Override
72
56
public void replaceNode (Node node ) {
73
- this .replaceNode (node , new HashSet <>() , new HashSet <>() );
57
+ this .replaceNode (node , new int [ 0 ] , new int [ 0 ] );
74
58
}
75
59
76
60
@ Override
77
- public void replaceNode (Node node , Set <Node > children , Set <Node > parents ) {
78
- this .children .put (node .getIdentifier (), children .stream ().map (c ->
79
- c .getIdentifier ()).collect (Collectors .toSet ()));
80
- this .parents .put (node .getIdentifier (), parents .stream ().map (p ->
81
- p .getIdentifier ()).collect (Collectors .toSet ()));
61
+ public void replaceNode (Node node , int [] children , int [] parents ) {
62
+ this .cache .getChildrenAdjacencyMap ().put (node .getIdentifier (), children );
63
+ this .cache .getParentsAdjacencyMap ().put (node .getIdentifier (), parents );
82
64
}
83
65
84
66
/**
85
67
* Get the number of nodes in the {@link GenomeGraph}.
86
68
* @return the number of nodes
87
69
*/
88
70
public int size () {
89
- assert (children . size () == parents .size ());
90
- return this .children .size ();
71
+ assert (this . cache . getChildrenAdjacencyMap (). size () == this . cache . getParentsAdjacencyMap () .size ());
72
+ return this .cache . getChildrenAdjacencyMap () .size ();
91
73
}
92
74
93
75
@ Override
94
- public Set < Segment > getChildren (Node node ) {
76
+ public int [] getChildren (Node node ) {
95
77
return this .getChildren (node .getIdentifier ());
96
78
}
97
79
98
80
@ Override
99
- public Set < Segment > getChildren (int nodeID ) {
100
- return this .children . get ( nodeID ). stream (). map ( id -> new Segment ( this , id )). collect ( Collectors . toSet () );
81
+ public int [] getChildren (int nodeID ) {
82
+ return this .cache . getChildrenAdjacencyMap (). get ( nodeID );
101
83
}
102
84
103
85
@ Override
104
- public Set < Segment > getParents (Node node ) {
86
+ public int [] getParents (Node node ) {
105
87
return this .getParents (node .getIdentifier ());
106
88
}
107
89
108
90
@ Override
109
- public Set < Segment > getParents (int nodeID ) {
110
- return this .parents . get ( nodeID ). stream (). map ( id -> new Segment ( this , id )). collect ( Collectors . toSet () );
91
+ public int [] getParents (int nodeID ) {
92
+ return this .cache . getParentsAdjacencyMap (). get ( nodeID );
111
93
}
112
94
113
95
@ Override
114
- public Set < Genome > getGenomes (Node node ) {
96
+ public int [] getGenomes (Node node ) {
115
97
throw new NotImplementedException ("GenomeGraph#getGenomes(Node) is not yet implemented" );
116
98
}
117
99
@@ -122,7 +104,7 @@ public boolean contains(Node node) {
122
104
123
105
@ Override
124
106
public boolean contains (int nodeID ) {
125
- return this .children .containsKey (nodeID );
107
+ return this .cache . getChildrenAdjacencyMap () .containsKey (nodeID );
126
108
}
127
109
128
110
@ Override
@@ -137,7 +119,26 @@ public void addEdge(Node source, Node destination) {
137
119
* @param child Node of the child to be added.
138
120
*/
139
121
private void addChild (Node node , Node child ) {
140
- this .children .get (node .getIdentifier ()).add (child .getIdentifier ());
122
+ if (this .cache .getCurrentParentID () == -1 ) {
123
+ this .cache .setCurrentParentID (node .getIdentifier ());
124
+ }
125
+
126
+ if (node .getIdentifier () == this .cache .getCurrentParentID ()) {
127
+ // if same parent as previous link || if first link of graph,
128
+ // just add the child
129
+ this .cache .getCurrentParentChildren ().add (child .getIdentifier ());
130
+ } else {
131
+ // write previous list to cache
132
+ int [] oldChildren = this .getChildren (this .cache .getCurrentParentID ());
133
+ int [] allChildren = this .append (oldChildren , this .cache .getCurrentParentChildren ());
134
+ this .cache .getChildrenAdjacencyMap ().put (this .cache .getCurrentParentID (), allChildren );
135
+
136
+ // reset node id
137
+ this .cache .setCurrentParentID (node .getIdentifier ());
138
+ // reset children list
139
+ this .cache .setCurrentParentChildren (new LinkedList <>());
140
+ this .cache .getCurrentParentChildren ().add (child .getIdentifier ());
141
+ }
141
142
}
142
143
143
144
/**
@@ -146,7 +147,11 @@ private void addChild(Node node, Node child) {
146
147
* @param parent Node of the parent to be added.
147
148
*/
148
149
private void addParent (Node node , Node parent ) {
149
- this .parents .get (node .getIdentifier ()).add (parent .getIdentifier ());
150
+ int [] oldParents = this .getParents (node .getIdentifier ());
151
+ //TODO find a way to do this more efficient
152
+ int [] newParents = Arrays .copyOf (oldParents , oldParents .length + 1 );
153
+ newParents [newParents .length - 1 ] = parent .getIdentifier ();
154
+ this .cache .getParentsAdjacencyMap ().put (node .getIdentifier (), newParents );
150
155
}
151
156
152
157
/**
@@ -230,6 +235,22 @@ public int getSequenceLength(int nodeID) {
230
235
return this .cache .getSequenceLength (nodeID );
231
236
}
232
237
238
+ /**
239
+ * Get the number of lines in the GFA file.
240
+ * @return # of lines
241
+ */
242
+ public int getNumberOfLines () {
243
+ return this .cache .getNumberOfLines ();
244
+ }
245
+
246
+ /**
247
+ * Set the number of lines in the GFA file.
248
+ * @param numberOfLines # of lines
249
+ */
250
+ public void setNumberOfLines (int numberOfLines ) {
251
+ this .cache .setNumberOfLines (numberOfLines );
252
+ }
253
+
233
254
/**
234
255
* Roll back the latest changes to the cache.
235
256
* @throws IOException when something strange happens during deletion
@@ -263,4 +284,32 @@ public void close() throws IOException {
263
284
this .cache = null ;
264
285
}
265
286
}
287
+
288
+ /**
289
+ * Append an {@link List<Integer>} to a int[].
290
+ * @param oldArray the int[] to go first
291
+ * @param newList the {@link List<Integer>} to be appended
292
+ * @return a int[] consisting of all elements
293
+ */
294
+ private int [] append (int [] oldArray , List <Integer > newList ) {
295
+ int [] newArray ;
296
+ if (oldArray == null ) {
297
+ newArray = oldArray ;
298
+ } else {
299
+ newArray = ArrayUtils .addAll (oldArray , newList .stream ().mapToInt (i -> i ).toArray ());
300
+ }
301
+
302
+ return newArray ;
303
+ }
304
+
305
+ /**
306
+ * Cache the group of edges from the last parent.
307
+ *
308
+ * Necessary because these are skipped during parsing.
309
+ */
310
+ public void cacheLastEdges () {
311
+ int [] oldChildren = this .getChildren (this .cache .getCurrentParentID ());
312
+ int [] allChildren = this .append (oldChildren , this .cache .getCurrentParentChildren ());
313
+ this .cache .getChildrenAdjacencyMap ().put (this .cache .getCurrentParentID (), allChildren );
314
+ }
266
315
}
0 commit comments