/** * Auxiliary method for cycle detection. Performs a depth-first traversal with vertex markings to * detect a cycle. If a node with a temporary marking is found, then there is a cycle. Once all * children of a vertex have been traversed the parent node cannot be part of another cycle and is * thus permanently marked. * * @param jv current job vertex to check * @param temporarilyMarked set of temporarily marked nodes * @param permanentlyMarked set of permanently marked nodes * @return <code>true</code> if there is a cycle, <code>false</code> otherwise */ private boolean detectCycle( final AbstractJobVertex jv, final HashSet<JobVertexID> temporarilyMarked, final HashSet<JobVertexID> permanentlyMarked) { JobVertexID vertexID = jv.getID(); if (permanentlyMarked.contains(vertexID)) { return false; } else if (temporarilyMarked.contains(vertexID)) { return true; } else { temporarilyMarked.add(vertexID); for (int i = 0; i < jv.getNumberOfForwardConnections(); i++) { if (detectCycle( jv.getForwardConnection(i).getConnectedVertex(), temporarilyMarked, permanentlyMarked)) { return true; } } permanentlyMarked.add(vertexID); return false; } }
/** * Auxiliary method to collect all vertices which are reachable from the input vertices. * * @param jv the currently considered job vertex * @param collector a temporary list to store the vertices that have already been visisted */ private void collectVertices( final AbstractJobVertex jv, final HashSet<JobVertexID> visited, final List<AbstractJobVertex> collector) { visited.add(jv.getID()); collector.add(jv); for (int i = 0; i < jv.getNumberOfForwardConnections(); i++) { AbstractJobVertex vertex = jv.getForwardConnection(i).getConnectedVertex(); if (!visited.contains(vertex.getID())) { collectVertices(vertex, visited, collector); } } }