8129cd6d159f57c5b0e5b1501f804400e9ba323a
[IRC.git] / Robust / src / Analysis / Scheduling / ScheduleNode.java
1 package Analysis.Scheduling;
2
3 import java.util.*;
4
5 import Analysis.TaskStateAnalysis.FEdge;
6 import Analysis.TaskStateAnalysis.FlagState;
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 int gid;
15   private int cid;
16   private static int nodeID=0;
17   public static int colorID = 0;
18
19   private Vector<ClassNode> classNodes;
20   Vector<ScheduleEdge> scheduleEdges;
21
22   private int executionTime;
23
24   /** Class constructor
25    *    @param cd ClassDescriptor
26    *  @param fStates
27    */
28   public ScheduleNode(int gid) {
29     this.uid = ScheduleNode.nodeID++;
30     this.gid = gid;
31     this.cid = -1;
32     this.executionTime = -1;
33     this.classNodes = null;
34     this.scheduleEdges = null;
35   }
36
37   public ScheduleNode(ClassNode cn, int gid) {
38     this.uid = ScheduleNode.nodeID++;
39     this.gid = gid;
40     this.cid = -1;
41     this.classNodes = new Vector<ClassNode>();
42     this.scheduleEdges = new Vector<ScheduleEdge>();
43     this.classNodes.add(cn);
44     this.addEdge(cn.getEdgeVector());
45     this.executionTime = -1;
46   }
47
48   public int getuid() {
49     return uid;
50   }
51
52   public int getCid() {
53     return cid;
54   }
55
56   public void setCid(int cid) {
57     this.cid = cid;
58   }
59
60   public String toString() {
61     String temp = new String("");
62     for(int i = 0; i < classNodes.size(); i++) {
63       temp += classNodes.elementAt(i).getClassDescriptor().toString() + ", ";
64     }
65     temp += getTextLabel();
66     return temp;
67   }
68
69   public Vector getClassNodes() {
70     return classNodes;
71   }
72
73   public Iterator getClassNodesIterator() {
74     if(classNodes == null) {
75       return null;
76     }
77     return classNodes.iterator();
78   }
79
80   public void resetClassNodes() {
81     classNodes = null;
82   }
83
84   public Vector getScheduleEdges() {
85     return scheduleEdges;
86   }
87
88   public Iterator getScheduleEdgesIterator() {
89     if(scheduleEdges == null) {
90       return null;
91     }
92     return scheduleEdges.iterator();
93   }
94
95   public void resetScheduleEdges() {
96     scheduleEdges = null;
97   }
98
99   public int getExeTime() {
100     if(this.executionTime == -1) {
101       try {
102         calExeTime();
103       } catch (Exception e) {
104         e.printStackTrace();
105       }
106     }
107     return this.executionTime;
108   }
109
110   public void calExeTime() throws Exception {
111     if(this.classNodes.size() != 1) {
112       throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime");
113     }
114     ClassNode cn = this.classNodes.elementAt(0);
115     if(!cn.isSorted()) {
116       throw new Error("Error: Non-sorted ClassNode!");
117     }
118     this.executionTime = cn.getFlagStates().elementAt(0).getExeTime();
119   }
120
121   /** Tests for equality of two flagstate objects.
122    */
123
124   public boolean equals(Object o) {
125     if (o instanceof ScheduleNode) {
126       ScheduleNode fs=(ScheduleNode)o;
127       if(fs.gid == this.gid) {
128         if(fs.uid != this.uid) {
129           return false;
130         }
131         if(fs.cid != this.cid) {
132           return false;
133         }
134       }
135       if ((fs.executionTime != this.executionTime)){
136         return false;
137       }
138       if(fs.classNodes != null) {
139         if(!fs.classNodes.equals(classNodes)) {
140           return false;
141         }
142       } else if(classNodes != null) {
143         return false;
144       }
145       return true;
146     }
147     return false;
148   }
149
150   public int hashCode() {
151     int hashcode = gid^uid^cid^executionTime;
152     if(this.classNodes != null) {
153       hashcode ^= classNodes.hashCode();
154     }
155     return hashcode;
156   }
157
158   public String getLabel() {
159     return "cluster" + uid;
160   }
161
162   public String getTextLabel() {
163     String label=null;
164
165     if (label==null)
166       return " ";
167     return label;
168   }
169
170   public Object clone(Hashtable<ClassNode, ClassNode> cn2cn, int gid) {
171     ScheduleNode o = null;
172     try {
173       o = (ScheduleNode) super.clone();
174     } catch(CloneNotSupportedException e){
175       e.printStackTrace();
176     }
177     o.uid = ScheduleNode.nodeID++;
178     o.gid = gid;
179     o.cid = this.cid;
180     // Clone all the internal ClassNodes and ScheduleEdges
181     Vector<ClassNode> tcns = new Vector<ClassNode>();
182     Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
183     int i = 0;
184     for(i = 0; i < this.classNodes.size(); i++) {
185       ClassNode tcn = this.classNodes.elementAt(i);
186       ClassNode cn = (ClassNode)tcn.clone();
187       cn.setScheduleNode(o);
188       tcns.add(cn);
189       cn2cn.put(tcn, cn);
190     }
191     for(i = 0; i < this.scheduleEdges.size(); i++) {
192       ScheduleEdge temp = this.scheduleEdges.elementAt(i);
193       ScheduleEdge se = null;
194       switch(temp.getType()) {
195       case ScheduleEdge.NEWEDGE: {
196         se = new ScheduleEdge(o, "new", temp.getFstate(), ScheduleEdge.NEWEDGE, gid);
197         se.setProbability(temp.getProbability());
198         se.setNewRate(temp.getNewRate());
199         break;
200       }
201
202       case ScheduleEdge.TRANSEDGE: {
203         se = new ScheduleEdge(o, "transmit", temp.getFstate(), ScheduleEdge.TRANSEDGE, gid);
204         se.setProbability(temp.getProbability());
205         se.setNewRate(temp.getNewRate());
206         break;
207       }
208       }
209       se.setSourceCNode(cn2cn.get(temp.getSourceCNode()));
210       se.setTargetCNode(cn2cn.get(temp.getTargetCNode()));
211       se.setTransTime(temp.getTransTime());
212       se.setFEdge(temp.getFEdge());
213       se.setTargetFState(temp.getTargetFState());
214       se.setIsclone(true);
215       tses.add(se);
216     }
217     o.classNodes = tcns;
218     o.scheduleEdges = tses;
219     tcns = null;
220     tses = null;
221
222     o.inedges = new Vector();
223     o.edges = new Vector();
224     return o;
225   }
226
227   public void mergeSEdge(ScheduleEdge se) throws Exception {
228     ScheduleNode sn = (ScheduleNode)se.getTarget();
229     Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
230     Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
231
232     for(int i = 0; i <  targetCNodes.size(); i++) {
233       targetCNodes.elementAt(i).setScheduleNode(this);
234     }
235
236     if(classNodes == null) {
237       classNodes = targetCNodes;
238       scheduleEdges = targetSEdges;
239     } else {
240       if(targetCNodes.size() != 0) {
241         classNodes.addAll(targetCNodes);
242       }
243       if(targetSEdges.size() != 0) {
244         scheduleEdges.addAll(targetSEdges);
245       }
246     }
247     targetCNodes = null;
248
249     if(ScheduleEdge.TRANSEDGE == se.getType()) {
250       sn.removeInedge(se);
251       this.removeEdge(se);
252
253       // merge the split ClassNode of same class
254       FlagState sfs = se.getFstate();
255       FlagState tfs = se.getTargetFState();
256       ClassNode scn = se.getSourceCNode();
257       ClassNode tcn = se.getTargetCNode();
258       sfs.getEdgeVector().addAll(tfs.getEdgeVector());
259       // merge the subtree whose root is nfs from the whole flag transition tree
260       Vector<FlagState> sfss = scn.getFlagStates();
261       sfss.addAll(tcn.getFlagStates());
262       sfss.removeElement(tfs);
263       classNodes.removeElement(tcn);
264
265       // flush the exeTime of fs and its ancestors
266       sfs.setExeTime(0);
267       Queue<FlagState> toiterate = new LinkedList<FlagState>();
268       toiterate.add(sfs);
269       while(!toiterate.isEmpty()) {
270         FlagState tmpfs = toiterate.poll();
271         int ttime = tmpfs.getExeTime();
272         Iterator it_inedges = tmpfs.inedges();
273         while(it_inedges.hasNext()) {
274           FEdge fEdge = (FEdge)it_inedges.next();
275           FlagState temp = (FlagState)fEdge.getSource();
276           int time = fEdge.getExeTime() + ttime;
277           if(temp.getExeTime() > time) {
278             temp.setExeTime(time);
279             toiterate.add(temp);
280           }
281         }
282       }
283       toiterate = null;
284
285       // redirct internal ScheduleEdge from tcn to scn
286       for(int i = 0; i < targetSEdges.size(); ++i) {
287         ScheduleEdge tmpse = targetSEdges.elementAt(i);
288         if(tmpse.getSourceCNode().equals(tcn)) {
289           tmpse.setSourceCNode(scn);
290         }
291       }
292
293       // redirect external ScheduleEdges to this ScheduleNode
294       // and scn if it is originally from tcn
295       Iterator it_edges = sn.edges();
296       while(it_edges.hasNext()) {
297         ScheduleEdge tse = (ScheduleEdge)it_edges.next();
298         tse.setSource(this);
299         if(tse.getSourceCNode().equals(tcn)) {
300           tse.setSourceCNode(scn);
301         }
302         this.edges.addElement(tse);
303       }
304
305       targetSEdges = null;
306
307       // As all tasks inside one ScheduleNode are executed sequentially,
308       // simply add the execution time of all the ClassNodes inside one ScheduleNode.
309       if(this.executionTime == -1) {
310         throw new Exception("Error: ScheduleNode without initiate execution time when analysising.");
311       }
312       if(this.executionTime < sn.getExeTime()) {
313         this.executionTime = sn.getExeTime();
314       }
315     } else if(ScheduleEdge.NEWEDGE == se.getType()) {
316       targetSEdges = null;
317
318       scheduleEdges.add(se);
319       se.resetListExeTime();
320       sn.removeInedge(se);
321       this.removeEdge(se);
322       Iterator it_edges = sn.edges();
323       while(it_edges.hasNext()) {
324         ScheduleEdge tse = (ScheduleEdge)it_edges.next();
325         tse.setSource(this);
326         this.edges.addElement(tse);
327       }
328
329       // As all tasks inside one ScheduleNode are executed sequentially,
330       // simply add the execution time of all the ClassNodes inside one ScheduleNode.
331       if(this.executionTime == -1) {
332         this.executionTime = 0;
333       }
334       this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
335     }
336   }
337
338   public void mergeSNode(ScheduleNode sn) throws Exception {
339     Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
340     Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)sn.getScheduleEdges();
341
342     for(int i = 0; i <  targetCNodes.size(); i++) {
343       targetCNodes.elementAt(i).setScheduleNode(this);
344     }
345
346     if(classNodes == null) {
347       classNodes = targetCNodes;
348       scheduleEdges = targetSEdges;
349     } else {
350       if(targetCNodes.size() != 0) {
351         classNodes.addAll(targetCNodes);
352       }
353       if(targetSEdges.size() != 0) {
354         scheduleEdges.addAll(targetSEdges);
355       }
356     }
357     targetCNodes = null;
358     targetSEdges = null;
359
360     // redirect external ScheduleEdges to this ScheduleNode
361     Iterator it_edges = sn.edges();
362     while(it_edges.hasNext()) {
363       ScheduleEdge tse = (ScheduleEdge)it_edges.next();
364       tse.setSource(this);
365       this.edges.addElement(tse);
366     }
367
368     it_edges = sn.inedges();
369     while(it_edges.hasNext()) {
370       ScheduleEdge tse = (ScheduleEdge)it_edges.next();
371       tse.setTarget(this);
372       this.inedges.addElement(tse);
373     }
374
375     // As all tasks inside one ScheduleNode are executed sequentially,
376     // simply add the execution time of all the ClassNodes inside one ScheduleNode.
377     if(this.executionTime == -1) {
378       this.executionTime = 0;
379     }
380     this.executionTime += sn.getExeTime();
381
382   }
383 }