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;
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;
56 * @param fd FlagDescriptor
57 * @return true if the flagstate contains fd else false.
59 public boolean get(FlagDescriptor fd) {
60 return flagstate.contains(fd);
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).
67 public boolean isSourceNode(){
71 /** Sets the flagstate as a source node.
73 public void setAsSourceNode(){
75 this.tasks=new Vector();
78 public void addAllocatingTask(TaskDescriptor task){
79 tasks.addElement(task);
82 public Vector getAllocatingTasks(){
87 public String toString() {
88 return cd.toString()+getTextLabel();
91 /** @return Iterator over the flags in the flagstate.
94 public Iterator getFlags() {
95 return flagstate.iterator();
98 public FlagState setTag(TagDescriptor tag){
100 HashSet newset=(HashSet)flagstate.clone();
101 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
103 if (newtags.containsKey(tag)){
104 switch (newtags.get(tag).intValue()){
106 newtags.put(tag,new Integer(MULTITAGS));
109 newtags.put(tag,new Integer(MULTITAGS));
114 newtags.put(tag,new Integer(ONETAG));
117 return new FlagState(newset,cd,newtags);
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
131 public FlagState[] clearTag(TagDescriptor tag){
132 FlagState[] retstates;
134 if (tags.containsKey(tag)){
135 switch(tags.get(tag).intValue()){
137 HashSet newset=(HashSet)flagstate.clone();
138 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
140 retstates=new FlagState[]{new FlagState(newset,cd,newtags)};
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);
159 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
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.
170 public String toString(FlagDescriptor[] flags)
172 StringBuffer sb = new StringBuffer(flagstate.size());
173 for(int i=0;i < flags.length; i++)
181 return new String(sb);
185 * @return returns the classdescriptor of the flagstate.
188 public ClassDescriptor getClassDescriptor(){
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>.
198 public FlagState setFlag(FlagDescriptor fd, boolean status) {
199 HashSet newset=(HashSet) flagstate.clone();
200 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
203 else if (newset.contains(fd)){
207 return new FlagState(newset, cd,newtags);
210 /** Tests for equality of two flagstate objects.
213 public boolean equals(Object o) {
214 if (o instanceof FlagState) {
215 FlagState fs=(FlagState)o;
218 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
223 public int hashCode() {
224 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
227 public String getLabel() {
234 public String getTextLabel() {
236 for(Iterator it=getFlags();it.hasNext();) {
237 FlagDescriptor fd=(FlagDescriptor) it.next();
241 label+=", "+fd.toString();
243 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
244 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
245 switch (tags.get(td).intValue()){
248 label=td.toString()+"(1)";
250 label+=", "+td.toString()+"(1)";
254 label=td.toString()+"(n)";
256 label+=", "+td.toString()+"(n)";
267 public Enumeration getTags(){