1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
10 /** This class is used to hold the flag states that a class in the Bristlecone
11 * program can exist in, during runtime.
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;
19 private static int nodeid=0;
21 private final HashSet flagstate;
22 private final ClassDescriptor cd;
23 private final Hashtable<TagDescriptor,Integer> tags;
24 private boolean issourcenode;
26 public static final int KLIMIT=2;
29 * Creates a new flagstate with all flags set to false.
30 * @param cd ClassDescriptor
32 public FlagState(ClassDescriptor cd) {
33 this.flagstate=new HashSet();
35 this.tags=new Hashtable<TagDescriptor,Integer>();
36 this.uid=FlagState.nodeid++;
37 this.issourcenode=false;
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
46 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
47 this.flagstate=flagstate;
50 this.uid=FlagState.nodeid++;
51 this.issourcenode=false;
60 * @param fd FlagDescriptor
61 * @return true if the flagstate contains fd else false.
63 public boolean get(FlagDescriptor fd) {
64 return flagstate.contains(fd);
67 /** Checks if the flagstate is a source node.
68 * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
71 public boolean isSourceNode(){
75 /** Sets the flagstate as a source node.
77 public void setAsSourceNode(){
80 this.tasks=new Vector();
84 public void addAllocatingTask(TaskDescriptor task){
88 public Vector getAllocatingTasks(){
93 public String toString() {
94 return cd.toString()+getTextLabel();
97 /** @return Iterator over the flags in the flagstate.
100 public Iterator getFlags() {
101 return flagstate.iterator();
104 public int numFlags(){
105 return flagstate.size();
108 public FlagState[] setTag(TagDescriptor tag, boolean set){
109 HashSet newset1=(HashSet)flagstate.clone();
110 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
114 if (tags.containsKey(tag))
115 count=tags.get(tag).intValue();
118 newtags1.put(tag, new Integer(count));
119 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
122 if (tags.containsKey(tag))
123 count=tags.get(tag).intValue();
124 newtags1.put(tag, new Integer(count));
125 if ((count+1)==KLIMIT)
126 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
128 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
132 public FlagState[] setTag(TagDescriptor tag){
133 HashSet newset1=(HashSet)flagstate.clone();
134 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
136 if (tags.containsKey(tag)){
137 //Code could try to remove flag that doesn't exist
139 switch (tags.get(tag).intValue()){
141 newtags1.put(tag,new Integer(MULTITAGS));
142 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
144 return new FlagState[] {this};
149 newtags1.put(tag,new Integer(ONETAG));
150 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
154 public int getTagCount(TagDescriptor tag) {
155 if (tags.containsKey(tag))
156 return tags.get(tag).intValue();
160 public int getTagCount(String tagtype){
161 return getTagCount(new TagDescriptor(tagtype));
164 public FlagState[] clearTag(TagDescriptor tag){
165 if (tags.containsKey(tag)){
166 switch(tags.get(tag).intValue()){
168 HashSet newset=(HashSet)flagstate.clone();
169 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
171 return new FlagState[]{new FlagState(newset,cd,newtags)};
174 //two possibilities - count remains 2 or becomes 1
176 HashSet newset1=(HashSet)flagstate.clone();
177 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
180 HashSet newset2=(HashSet)flagstate.clone();
181 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
182 newtags1.put(tag,new Integer(ONETAG));
183 return new FlagState[] {new FlagState(newset1, cd, newtags2),
184 new FlagState(newset2, cd, newtags2)};
189 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
193 /** Creates a string description of the flagstate
194 * e.g. a flagstate with five flags could look like 01001
195 * @param flags an array of flagdescriptors.
196 * @return string representation of the flagstate.
198 public String toString(FlagDescriptor[] flags)
200 StringBuffer sb = new StringBuffer(flagstate.size());
201 for(int i=0;i < flags.length; i++)
209 return new String(sb);
213 * @return returns the classdescriptor of the flagstate.
216 public ClassDescriptor getClassDescriptor(){
220 /** Sets the status of a specific flag in a flagstate after cloning it.
221 * @param fd FlagDescriptor of the flag whose status is being set.
222 * @param status boolean value
223 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
226 public FlagState setFlag(FlagDescriptor fd, boolean status) {
227 HashSet newset=(HashSet) flagstate.clone();
228 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
231 else if (newset.contains(fd)){
235 return new FlagState(newset, cd, newtags);
238 /** Tests for equality of two flagstate objects.
241 public boolean equals(Object o) {
242 if (o instanceof FlagState) {
243 FlagState fs=(FlagState)o;
246 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
251 public int hashCode() {
252 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
255 public String getLabel() {
259 public String getTextLabel() {
261 for(Iterator it=getFlags();it.hasNext();) {
262 FlagDescriptor fd=(FlagDescriptor) it.next();
266 label+=", "+fd.toString();
268 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
269 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
270 switch (tags.get(td).intValue()){
273 label=td.toString()+"(1)";
275 label+=", "+td.toString()+"(1)";
279 label=td.toString()+"(n)";
281 label+=", "+td.toString()+"(n)";
292 public Enumeration getTags(){