View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package com.github.dexecutor.core.graph;
19  
20  import java.io.IOException;
21  import java.io.Writer;
22  import java.util.ArrayList;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Queue;
26  import java.util.Set;
27  
28  import com.github.dexecutor.core.graph.Node;
29  
30  /**
31   * A Traversar which does level order traversal of the given graph
32   * 
33   * @author Nadeem Mohammad
34   *
35   * @param <T> Type of Node/Task ID
36   * @param <R> Type of Node/Task result
37   */
38  public class LevelOrderTraversar<T extends Comparable<T>, R> implements Traversar<T, R> {
39  	
40  	private List<Node<T, R>> processed = new ArrayList<Node<T, R>>();
41  	
42  	public void traverse(final Dag<T, R> graph, final Writer writer) {
43  		List<List<List<Node<T, R>>>> levelOrderOfGraphs = traverseLevelOrder(graph);
44  		int i = 0;
45  		for (List<List<Node<T, R>>> levelOrderOfGraph : levelOrderOfGraphs) {
46  			try {
47  				writer.write("Path #" + (i++) + "\n");
48  				printGraph(levelOrderOfGraph, writer);
49  				writer.write("\n");
50  			} catch (IOException e) {
51  				e.printStackTrace();
52  			}
53  		}
54  	}
55  
56  	private List<List<List<Node<T, R>>>> traverseLevelOrder(final Dag<T, R> graph) {
57  		List<List<List<Node<T, R>>>> result = new ArrayList<List<List<Node<T, R>>>>();
58  		Set<Node<T, R>> initialNodes = graph.getInitialNodes();
59  		for (Node<T, R> iNode : initialNodes) {
60  			List<List<Node<T, R>>> iresult = new ArrayList<List<Node<T, R>>>();
61  			doTraverse(iresult, iNode);
62  			result.add(iresult);
63  		}
64  		return result;
65  	}
66  
67  	private void doTraverse(final List<List<Node<T, R>>> result, final Node<T, R> iNode) {
68  		Queue<Node<T, R>> queue = new LinkedList<Node<T, R>>();
69  		queue.offer(iNode);
70  		while (!queue.isEmpty()) {
71  			List<Node<T, R>> level = new ArrayList<Node<T, R>>();
72  			int size = queue.size();
73  			for (int i = 0; i < size; i++) {
74  				Node<T, R> node = queue.poll();
75  				if (!this.processed.contains(node)) {
76  					if (!level.contains(node)) {
77  						level.add(node);
78  					}
79  					this.processed.add(node);
80  					for (Node<T, R> ogn : node.getOutGoingNodes()) {
81  						if (ogn != null && !this.processed.contains(ogn)) {
82  							queue.offer(ogn);
83  						}
84  					}
85  				}
86  				
87  			}
88  			result.add(level);
89  		}
90  	}
91  
92  	private void printGraph(final List<List<Node<T, R>>> list, final Writer writer) {
93  		for (List<Node<T, R>> nodes : list) {
94  			try {
95  				for (Node<T, R> node : nodes) {
96  					writer.write(node + "" + node.getInComingNodes() + " ");
97  				}
98  				writer.write("\n");
99  			} catch (IOException e) {
100 				e.printStackTrace();
101 			}
102 		}
103 	}
104 }