Feature adds to webinterface:
[IRC.git] / Robust / src / Analysis / TaskStateAnalysis / FlagState.java
1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
3 import IR.*;
4 import IR.Tree.*;
5 import IR.Flat.*;
6 import java.util.*;
7 import java.io.*;
8 import Util.GraphNode;
9
10 /** This class is used to hold the flag states that a class in the Bristlecone 
11  *  program can exist in, during runtime.
12  */
13 public class FlagState extends GraphNode {
14     public static final int ONETAG=1;
15     public static final int NOTAGS=0;
16     public static final int MULTITAGS=-1;
17     
18     private int uid;
19     private static int nodeid=0;
20
21     private final HashSet flagstate;
22     private final ClassDescriptor cd;
23     private final Hashtable<TagDescriptor,Integer> tags;
24     private boolean issourcenode;
25     private Vector tasks;
26     
27
28     /** Class constructor
29      *  Creates a new flagstate with all flags set to false.
30      *  @param cd ClassDescriptor
31      */
32     public FlagState(ClassDescriptor cd) {
33         this.flagstate=new HashSet();
34         this.cd=cd;
35         this.tags=new Hashtable<TagDescriptor,Integer>();
36         this.uid=FlagState.nodeid++;
37         this.issourcenode=false;
38     }
39
40     /** Class constructor
41      *  Creates a new flagstate with flags set according to the HashSet.
42      *  If the flag exists in the hashset, it's set to true else set to false.
43      *  @param cd ClassDescriptor
44      *  @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
45      */
46     private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
47         this.flagstate=flagstate;
48         this.cd=cd;
49         this.tags=tags;
50         this.uid=FlagState.nodeid++;
51         this.issourcenode=false;
52         
53     }
54     
55     /** Accessor method
56       *  @param fd FlagDescriptor
57       *  @return true if the flagstate contains fd else false.
58       */
59     public boolean get(FlagDescriptor fd) {
60         return flagstate.contains(fd);
61     }
62     
63     /** Checks if the flagstate is a source node. 
64      *  @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
65      */
66       
67     public boolean isSourceNode(){
68             return issourcenode;
69         }
70         
71         /**  Sets the flagstate as a source node. 
72      */
73         public void setAsSourceNode(){
74                 issourcenode=true;
75                 this.tasks=new Vector();
76         }
77         
78         public void addAllocatingTask(TaskDescriptor task){
79                 tasks.addElement(task);
80         }
81
82         public Vector getAllocatingTasks(){
83                 return tasks;
84         }
85                 
86     
87     public String toString() {
88         return cd.toString()+getTextLabel();
89     }
90
91     /** @return Iterator over the flags in the flagstate.
92      */
93      
94     public Iterator getFlags() {
95         return flagstate.iterator();
96     }
97     
98     public FlagState setTag(TagDescriptor tag){
99            
100             HashSet newset=(HashSet)flagstate.clone();
101             Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
102             
103             if (newtags.containsKey(tag)){
104                    switch (newtags.get(tag).intValue()){
105                            case ONETAG:
106                                         newtags.put(tag,new Integer(MULTITAGS));
107                                         break;
108                            case MULTITAGS:
109                                         newtags.put(tag,new Integer(MULTITAGS));
110                                         break;
111                         }
112                 }
113                 else{
114                         newtags.put(tag,new Integer(ONETAG));
115                 }
116                 
117                 return new FlagState(newset,cd,newtags);
118                                 
119     }
120
121     public int getTagCount(String tagtype){
122                 for (Enumeration en=getTags();en.hasMoreElements();){
123                         TagDescriptor td=(TagDescriptor)en.nextElement();
124                         if (tagtype.equals(td.getSymbol()))
125                                 return tags.get(td).intValue();   //returns either ONETAG or MULTITAG
126                 }
127                 return NOTAGS;
128                 
129     }
130     
131     public FlagState[] clearTag(TagDescriptor tag){
132             FlagState[] retstates;
133             
134             if (tags.containsKey(tag)){
135             switch(tags.get(tag).intValue()){
136                     case ONETAG:
137                         HashSet newset=(HashSet)flagstate.clone();
138                         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
139                         newtags.remove(tag);
140                         retstates=new FlagState[]{new FlagState(newset,cd,newtags)};
141                         return retstates;
142                         
143                     case MULTITAGS:
144                         //when tagcount is more than 2, COUNT stays at MULTITAGS
145                         retstates=new FlagState[2];
146                         HashSet newset1=(HashSet)flagstate.clone();
147                         Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
148                         retstates[1]=new FlagState(newset1,cd,newtags1);
149                         //when tagcount is 2, COUNT changes to ONETAG
150                         HashSet newset2=(HashSet)flagstate.clone();
151                         Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
152                         newtags1.put(tag,new Integer(ONETAG));
153                         retstates[1]=new FlagState(newset2,cd,newtags2);
154                         return retstates;
155                 default:
156                         return null;                    
157         }
158                 }else{
159                         throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
160                         
161                 }
162                 
163     }
164     
165     /** Creates a string description of the flagstate
166      *  e.g.  a flagstate with five flags could look like 01001
167      *  @param flags an array of flagdescriptors.
168      *  @return string representation of the flagstate.
169      */
170         public String toString(FlagDescriptor[] flags)
171         {
172                 StringBuffer sb = new StringBuffer(flagstate.size());
173                 for(int i=0;i < flags.length; i++)
174                 {
175                         if (get(flags[i]))
176                                 sb.append(1);
177                         else
178                                 sb.append(0);
179                 }
180                         
181                 return new String(sb);
182         }
183
184         /** Accessor method
185          *  @return returns the classdescriptor of the flagstate.
186          */
187          
188     public ClassDescriptor getClassDescriptor(){
189         return cd;
190     }
191
192         /** Sets the status of a specific flag in a flagstate after cloning it.
193          *  @param      fd FlagDescriptor of the flag whose status is being set.
194          *  @param  status boolean value
195          *  @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
196          */
197          
198     public FlagState setFlag(FlagDescriptor fd, boolean status) {
199         HashSet newset=(HashSet) flagstate.clone();
200         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
201         if (status)
202             newset.add(fd);
203         else if (newset.contains(fd)){
204             newset.remove(fd);
205         }
206         
207         return new FlagState(newset, cd,newtags);
208     }
209     
210     /** Tests for equality of two flagstate objects.
211     */
212     
213     public boolean equals(Object o) {
214         if (o instanceof FlagState) {
215             FlagState fs=(FlagState)o;
216             if (fs.cd!=cd)
217                 return false;
218             return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
219         }
220         return false;
221     }
222
223     public int hashCode() {
224         return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
225     }
226
227     public String getLabel() {
228         return "N"+uid;
229     }
230     
231     
232         
233
234     public String getTextLabel() {
235         String label=null;
236         for(Iterator it=getFlags();it.hasNext();) {
237             FlagDescriptor fd=(FlagDescriptor) it.next();
238             if (label==null)
239                 label=fd.toString();
240             else
241                 label+=", "+fd.toString();
242         }
243         for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
244                 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
245                 switch (tags.get(td).intValue()){
246                 case ONETAG:
247                     if (label==null)
248                         label=td.toString()+"(1)";
249                     else
250                         label+=", "+td.toString()+"(1)";
251                     break;
252                 case MULTITAGS:
253                     if (label==null)
254                         label=td.toString()+"(n)";
255                     else
256                         label+=", "+td.toString()+"(n)";
257                     break;
258                 default:
259                     break;
260                 }
261         }
262         if (label==null)
263             return " ";
264         return label;
265     }
266     
267     public Enumeration getTags(){
268             return tags.keys();
269     }
270 }