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