Make the Scheduling codes can handle back edges in combined flag transition diagram...
[IRC.git] / Robust / src / Analysis / Scheduling / ScheduleNode.java
1 package Analysis.Scheduling;
2
3 import Analysis.TaskStateAnalysis.*;
4 import IR.*;
5 import java.util.*;
6
7 import Util.GraphNode;
8
9 /** This class holds flag transition diagram(s) can be put on one core.
10  */
11 public class ScheduleNode extends GraphNode implements Cloneable{
12     
13     private int uid;
14     private static int nodeID=0;
15
16     private int coreNum;
17     private Vector tasks;
18     private Hashtable<ClassDescriptor, Vector<ScheduleNode>> targetSNodes; 
19     private boolean sorted = false;
20     
21     private boolean clone = false;
22
23     private Vector<ClassNode> classNodes;
24     Vector<ScheduleEdge> scheduleEdges;
25
26     /** Class constructor
27      *  @param cd ClassDescriptor
28      *  @param fStates
29      */
30     public ScheduleNode() {
31         this.uid=ScheduleNode.nodeID++;
32         this.coreNum = -1;
33     }
34     
35     public ScheduleNode(ClassNode cn) {
36         this.uid=ScheduleNode.nodeID++;
37         this.coreNum = -1;
38         this.classNodes = new Vector<ClassNode>();
39         this.scheduleEdges = new Vector<ScheduleEdge>();
40         this.classNodes.add(cn);
41         this.addEdge(cn.getEdgeVector());
42     }
43    
44     public int getuid() {
45         return uid;
46     }
47     
48     public int getCoreNum() {
49         return this.coreNum;
50     }
51     
52     public void setCoreNum(int coreNum) {
53         this.coreNum = coreNum;
54     }
55     
56     public void addTargetSNode(ClassDescriptor cd, ScheduleNode sn) {
57         if(this.targetSNodes == null) {
58             this.targetSNodes = new Hashtable<ClassDescriptor, Vector<ScheduleNode>>();
59         }
60         
61         if(!this.targetSNodes.containsKey(cd)) {
62             this.targetSNodes.put(cd, new Vector<ScheduleNode>());
63         }
64         this.targetSNodes.get(cd).add(sn);
65     }
66     
67     public void listTasks() {
68         if(this.tasks == null) {
69             this.tasks = new Vector();
70         }
71         
72         int i = 0;
73         for(i = 0; i < classNodes.size(); i++) {
74             Iterator it_flags = classNodes.elementAt(i).getFlags();
75             while(it_flags.hasNext()) {
76                 FlagState fs = (FlagState)it_flags.next();
77                 Iterator it_edges = fs.edges();
78                 while(it_edges.hasNext()) {
79                     TaskDescriptor td = ((FEdge)it_edges.next()).getTask();
80                     if(!this.tasks.contains(td)) {
81                         this.tasks.add(td);
82                     }
83                 }
84             }
85         }
86     }
87     
88     public void addTask(TaskDescriptor task){
89         tasks.add(task);
90     }
91     
92     public Vector getTasks(){
93         return tasks;
94     }
95     
96     public boolean isSorted() {
97         return sorted;
98     }
99     
100     public void setSorted(boolean sorted) {
101         this.sorted = sorted;
102     }
103     
104     public boolean isclone() {
105         return clone;
106     }
107     
108     public String toString() {
109         String temp = new String("");
110         for(int i = 0; i < classNodes.size(); i++) {
111             temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
112         }
113         temp += getTextLabel();
114         return temp;
115     }
116
117     public Vector getClassNodes() {
118         if(classNodes == null) {
119             classNodes = new Vector<ClassNode>();
120         }
121         return classNodes;
122     }
123     
124     public Iterator getClassNodesIterator() {
125         return classNodes.iterator();
126     }
127     
128     public void resetClassNodes() {
129         classNodes = null;
130     }
131     
132     public Vector getScheduleEdges() {
133         if(scheduleEdges == null) {
134             scheduleEdges = new Vector<ScheduleEdge>();
135         }
136         return scheduleEdges;
137     }
138     
139     public Iterator getScheduleEdgesIterator() {
140         return scheduleEdges.iterator();
141     }
142     
143     public void resetScheduleEdges() {
144         scheduleEdges = null;
145     }
146     
147     /** Tests for equality of two flagstate objects.
148     */
149     
150     public boolean equals(Object o) {
151         if (o instanceof ScheduleNode) {
152             ScheduleNode fs=(ScheduleNode)o;
153             if ((fs.getCoreNum() != this.coreNum) ||
154                 (fs.sorted != this.sorted) ||
155                 (fs.clone != this.clone)){ 
156                 return false;
157             }
158             if(fs.tasks != null) {
159                 if(!fs.tasks.equals(this.tasks)) {
160                     return false;
161                 }
162             } else if (tasks != null) {
163                 return false;
164             }
165             if (fs.targetSNodes != null) {
166                 if(!fs.targetSNodes.equals(this.targetSNodes)) {
167                     return false;
168                 }
169             } else if(this.targetSNodes != null) {
170                 return false;
171             }
172             if(fs.classNodes != null) {
173                 if(!fs.classNodes.equals(classNodes)) {
174                     return false;
175                 }
176             } else if(classNodes != null) {
177                 return false;
178             }
179             return (fs.scheduleEdges.equals(scheduleEdges));
180         }
181         return false;
182     }
183
184     public int hashCode() {
185         return classNodes.hashCode()^scheduleEdges.hashCode();
186     }
187
188     public String getLabel() {
189         return "cluster" + uid;
190     }   
191
192     public String getTextLabel() {
193         String label=null;
194         if(this.coreNum != -1) {
195             label = "Core " + this.coreNum;
196         }
197         
198         if (label==null)
199             return " ";
200         return label;
201     }
202     
203     public Object clone(Hashtable<ClassNode, ClassNode> cn2cn) {
204         ScheduleNode o = null;
205         try {
206             o = (ScheduleNode)super.clone();
207         } catch(CloneNotSupportedException e){
208             e.printStackTrace();
209         }
210         o.uid = ScheduleNode.nodeID++;
211         // Clone all the internal ClassNodes and ScheduleEdges
212         Vector<ClassNode> tcns = new Vector<ClassNode>();
213         Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
214         int i = 0;
215         for(i = 0; i < this.classNodes.size(); i++) {
216             ClassNode tcn = this.classNodes.elementAt(i);
217             ClassNode cn = (ClassNode)tcn.clone();
218             cn.setScheduleNode(o);
219             tcns.add(cn);
220             cn2cn.put(tcn, cn);
221         }
222         for(i = 0; i < this.scheduleEdges.size(); i++) {
223             ScheduleEdge temp = this.scheduleEdges.elementAt(i);
224             ScheduleEdge se = new ScheduleEdge(o, "new", temp.getTask(), temp.getClassDescriptor());
225             se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
226             se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
227             tses.add(se);
228         }
229         o.classNodes = tcns;
230         o.scheduleEdges = tses;
231         tcns = null;
232         tses = null;
233         o.inedges = new Vector();
234         o.edges = new Vector();
235         
236         o.clone = true;
237         return o;
238     }
239     
240     public void merge(ScheduleEdge se) {
241         Vector<ClassNode> targetCNodes = (Vector<ClassNode>)((ScheduleNode)se.getTarget()).getClassNodes();
242         Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)((ScheduleNode)se.getTarget()).getScheduleEdges();
243         
244         for(int i = 0; i <  targetCNodes.size(); i++) {
245             targetCNodes.elementAt(i).setScheduleNode(this);
246         }
247         
248         if(classNodes == null) {
249             classNodes = targetCNodes;
250             scheduleEdges = targetSEdges;
251         } else {
252             if(targetCNodes.size() != 0) {
253                 classNodes.addAll(targetCNodes);
254             }
255             if(targetSEdges.size() != 0) {
256                 scheduleEdges.addAll(targetSEdges);
257             }
258         }
259         targetCNodes = null;
260         targetSEdges = null;
261         
262         scheduleEdges.add(se);
263         se.getTarget().removeInedge(se);
264         this.removeEdge(se);
265         //this.addEdge(se.getTarget().getEdgeVector());
266         Iterator it_edges = se.getTarget().edges();
267         while(it_edges.hasNext()) {
268             ScheduleEdge tse = (ScheduleEdge)it_edges.next();
269             tse.setSource(this);
270             this.edges.addElement(tse);
271         }
272     }
273 }