This commit was manufactured by cvs2svn to create tag 'buildscript'.
[IRC.git] /
1 package Analysis.TaskStateAnalysis;
2 import Analysis.Scheduling.ClassNode;
3 import Analysis.TaskStateAnalysis.*;
4 import IR.*;
5 import IR.Tree.*;
6 import IR.Flat.*;
7 import java.util.*;
8 import java.io.*;
9 import Util.GraphNode;
10
11 /** This class is used to hold the flag states that a class in the Bristlecone 
12  *  program can exist in, during runtime.
13  */
14 public class FlagState extends GraphNode implements Cloneable {
15     public static final int ONETAG=1;
16     public static final int NOTAGS=0;
17     public static final int MULTITAGS=-1;
18     
19     private int uid;
20     private static int nodeid=0;
21
22     private final HashSet flagstate;
23     private final ClassDescriptor cd;
24     private final Hashtable<TagDescriptor,Integer> tags;
25     private boolean issourcenode;
26     private Vector tasks;
27     public static final int KLIMIT=2;
28     
29     // jzhou
30     private int executeTime;
31
32     /** Class constructor
33      *  Creates a new flagstate with all flags set to false.
34      *  @param cd ClassDescriptor
35      */
36     public FlagState(ClassDescriptor cd) {
37         this.flagstate=new HashSet();
38         this.cd=cd;
39         this.tags=new Hashtable<TagDescriptor,Integer>();
40         this.uid=FlagState.nodeid++;
41         this.issourcenode=false;
42         this.executeTime = -1;
43     }
44
45     /** Class constructor
46      *  Creates a new flagstate with flags set according to the HashSet.
47      *  If the flag exists in the hashset, it's set to true else set to false.
48      *  @param cd ClassDescriptor
49      *  @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
50      */
51     private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
52         this.flagstate=flagstate;
53         this.cd=cd;
54         this.tags=tags;
55         this.uid=FlagState.nodeid++;
56         this.issourcenode=false;
57         this.executeTime = -1;
58     }
59    
60     public int getuid() {
61         return uid;
62     }
63
64     /** Accessor method
65       *  @param fd FlagDescriptor
66       *  @return true if the flagstate contains fd else false.
67       */
68     public boolean get(FlagDescriptor fd) {
69         return flagstate.contains(fd);
70     }
71     
72     /** Checks if the flagstate is a source node. 
73      *  @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
74      */
75       
76     public boolean isSourceNode(){
77         return issourcenode;
78     }
79     
80     /**  Sets the flagstate as a source node. 
81      */
82     public void setAsSourceNode(){
83         if(!issourcenode){
84             issourcenode=true;
85             this.tasks=new Vector();
86         }
87     }
88     
89     public void addAllocatingTask(TaskDescriptor task){
90         tasks.add(task);
91     }
92     
93     public Vector getAllocatingTasks(){
94         return tasks;
95     }
96     
97     
98     public String toString() {
99         return cd.toString()+getTextLabel();
100     }
101
102     /** @return Iterator over the flags in the flagstate.
103      */
104      
105     public Iterator getFlags() {
106         return flagstate.iterator();
107     }
108
109     public int numFlags(){
110         return flagstate.size();
111     }
112     
113     public FlagState[] setTag(TagDescriptor tag, boolean set){
114         HashSet newset1=(HashSet)flagstate.clone();
115         Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
116             
117         if (set) {
118             int count=0;
119             if (tags.containsKey(tag))
120                 count=tags.get(tag).intValue();
121             if (count<KLIMIT)
122                 count++;
123             newtags1.put(tag, new Integer(count));
124             return new FlagState[] {new FlagState(newset1, cd, newtags1)};
125         } else {
126             int count=1;
127             if (tags.containsKey(tag))
128                 count=tags.get(tag).intValue();
129             newtags1.put(tag, new Integer(count));
130             if ((count+1)==KLIMIT)
131                 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
132             else
133                 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
134         }
135     }
136
137     public FlagState[] setTag(TagDescriptor tag){
138         HashSet newset1=(HashSet)flagstate.clone();
139         Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
140             
141         if (tags.containsKey(tag)){
142             //Code could try to remove flag that doesn't exist
143             
144             switch (tags.get(tag).intValue()){
145             case ONETAG:
146                 newtags1.put(tag,new Integer(MULTITAGS));
147                 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
148             case MULTITAGS:
149                 return new FlagState[] {this};
150             default:
151                 throw new Error();
152             }
153         } else {
154             newtags1.put(tag,new Integer(ONETAG));
155             return new FlagState[] {new FlagState(newset1,cd,newtags1)};
156         }
157     }
158
159     public int getTagCount(TagDescriptor tag) {
160         if (tags.containsKey(tag))
161             return tags.get(tag).intValue();
162         else return 0;
163     }
164
165     public int getTagCount(String tagtype){
166         return getTagCount(new TagDescriptor(tagtype));
167     }
168     
169     public FlagState[] clearTag(TagDescriptor tag){
170         if (tags.containsKey(tag)){
171             switch(tags.get(tag).intValue()){
172             case ONETAG:
173                 HashSet newset=(HashSet)flagstate.clone();
174                 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
175                 newtags.remove(tag);
176                 return new FlagState[]{new FlagState(newset,cd,newtags)};
177                 
178             case MULTITAGS:
179                 //two possibilities - count remains 2 or becomes 1
180                 //2 case
181                 HashSet newset1=(HashSet)flagstate.clone();
182                 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
183                 
184                 //1 case
185                 HashSet newset2=(HashSet)flagstate.clone();
186                 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
187                 newtags1.put(tag,new Integer(ONETAG));
188                 return new FlagState[] {new FlagState(newset1, cd, newtags2),
189                                         new FlagState(newset2, cd, newtags2)};
190             default:
191                 throw new Error();
192             }
193         } else {
194             throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
195         }
196     }
197     
198     /** Creates a string description of the flagstate
199      *  e.g.  a flagstate with five flags could look like 01001
200      *  @param flags an array of flagdescriptors.
201      *  @return string representation of the flagstate.
202      */
203     public String toString(FlagDescriptor[] flags)
204     {
205         StringBuffer sb = new StringBuffer(flagstate.size());
206         for(int i=0;i < flags.length; i++)
207             {
208                 if (get(flags[i]))
209                     sb.append(1);
210                 else
211                     sb.append(0);
212             }
213         
214         return new String(sb);
215     }
216     
217         /** Accessor method
218          *  @return returns the classdescriptor of the flagstate.
219          */
220          
221     public ClassDescriptor getClassDescriptor(){
222         return cd;
223     }
224
225         /** Sets the status of a specific flag in a flagstate after cloning it.
226          *  @param      fd FlagDescriptor of the flag whose status is being set.
227          *  @param  status boolean value
228          *  @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
229          */
230          
231     public FlagState setFlag(FlagDescriptor fd, boolean status) {
232         HashSet newset=(HashSet) flagstate.clone();
233         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
234         if (status)
235             newset.add(fd);
236         else if (newset.contains(fd)){
237             newset.remove(fd);
238         }
239         
240         return new FlagState(newset, cd, newtags);
241     }
242     
243     /** Tests for equality of two flagstate objects.
244     */
245     
246     public boolean equals(Object o) {
247         if (o instanceof FlagState) {
248             FlagState fs=(FlagState)o;
249             if (fs.cd!=cd)
250                 return false;
251             return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
252         }
253         return false;
254     }
255
256     public int hashCode() {
257         return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
258     }
259
260     public String getLabel() {
261         return "N"+uid;
262     }
263     
264     public String getTextLabel() {
265         String label=null;
266         for(Iterator it=getFlags();it.hasNext();) {
267             FlagDescriptor fd=(FlagDescriptor) it.next();
268             if (label==null)
269                 label=fd.toString();
270             else
271                 label+=", "+fd.toString();
272         }
273         for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
274             TagDescriptor td=(TagDescriptor)en_tags.nextElement();
275             switch (tags.get(td).intValue()){
276             case ONETAG:
277                 if (label==null)
278                     label=td.toString()+"(1)";
279                 else
280                     label+=", "+td.toString()+"(1)";
281                 break;
282             case MULTITAGS:
283                 if (label==null)
284                     label=td.toString()+"(n)";
285                 else
286                     label+=", "+td.toString()+"(n)";
287                 break;
288             default:
289                 break;
290             }
291         }
292         if (label==null)
293             return " ";
294         return label;
295     }
296     
297     public Enumeration getTags(){
298         return tags.keys();
299     }
300     
301     public int getExeTime() {
302         try {
303             if(this.executeTime == -1) {
304                 calExeTime();
305             }
306         } catch (Exception e) {
307             e.printStackTrace();
308             System.exit(0);
309         }
310         return this.executeTime;
311     }
312     
313     public void setExeTime(int exeTime) {
314         this.executeTime = exeTime;
315     }
316     
317     public void calExeTime() throws Exception {
318         Iterator it = this.edges();
319         if(it.hasNext()) {
320             FEdge fe = (FEdge)it.next();
321             if(fe.getExeTime() == -1) {
322                 throw new Exception("Error: Uninitiate FEdge!");
323             }
324             this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
325         } else {
326             this.executeTime = 0;
327         }
328         while(it.hasNext()) {
329             FEdge fe = (FEdge)it.next();
330             int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
331             if(temp < this.executeTime) {
332                 this.executeTime = temp;
333             }
334         }
335     }
336     
337     public Object clone() {
338         FlagState o = null;
339         try {
340             o = (FlagState)super.clone();
341         } catch(CloneNotSupportedException e){
342             e.printStackTrace();
343         }
344         o.uid = FlagState.nodeid++;
345         o.edges = new Vector();
346         for(int i = 0; i < this.edges.size(); i++) {
347             o.edges.addElement(this.edges.elementAt(i));
348         }
349         o.inedges = new Vector();
350         for(int i = 0; i < this.inedges.size(); i++) {
351             o.inedges.addElement(this.inedges.elementAt(i));
352         }
353         return o;
354     }
355 }