1 package Analysis.TaskStateAnalysis;
2 import Analysis.Scheduling.ClassNode;
3 import Analysis.TaskStateAnalysis.*;
11 /** This class is used to hold the flag states that a class in the Bristlecone
12 * program can exist in, during runtime.
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;
20 private static int nodeid=0;
22 private final HashSet flagstate;
23 private final ClassDescriptor cd;
24 private final Hashtable<TagDescriptor,Integer> tags;
25 private boolean issourcenode;
27 public static final int KLIMIT=2;
30 private int executeTime;
33 * Creates a new flagstate with all flags set to false.
34 * @param cd ClassDescriptor
36 public FlagState(ClassDescriptor cd) {
37 this.flagstate=new HashSet();
39 this.tags=new Hashtable<TagDescriptor,Integer>();
40 this.uid=FlagState.nodeid++;
41 this.issourcenode=false;
42 this.executeTime = -1;
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
51 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
52 this.flagstate=flagstate;
55 this.uid=FlagState.nodeid++;
56 this.issourcenode=false;
57 this.executeTime = -1;
65 * @param fd FlagDescriptor
66 * @return true if the flagstate contains fd else false.
68 public boolean get(FlagDescriptor fd) {
69 return flagstate.contains(fd);
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).
76 public boolean isSourceNode(){
80 /** Sets the flagstate as a source node.
82 public void setAsSourceNode(){
85 this.tasks=new Vector();
89 public void addAllocatingTask(TaskDescriptor task){
93 public Vector getAllocatingTasks(){
98 public String toString() {
99 return cd.toString()+getTextLabel();
102 /** @return Iterator over the flags in the flagstate.
105 public Iterator getFlags() {
106 return flagstate.iterator();
109 public int numFlags(){
110 return flagstate.size();
113 public FlagState[] setTag(TagDescriptor tag, boolean set){
114 HashSet newset1=(HashSet)flagstate.clone();
115 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
119 if (tags.containsKey(tag))
120 count=tags.get(tag).intValue();
123 newtags1.put(tag, new Integer(count));
124 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
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)};
133 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
137 public FlagState[] setTag(TagDescriptor tag){
138 HashSet newset1=(HashSet)flagstate.clone();
139 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
141 if (tags.containsKey(tag)){
142 //Code could try to remove flag that doesn't exist
144 switch (tags.get(tag).intValue()){
146 newtags1.put(tag,new Integer(MULTITAGS));
147 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
149 return new FlagState[] {this};
154 newtags1.put(tag,new Integer(ONETAG));
155 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
159 public int getTagCount(TagDescriptor tag) {
160 if (tags.containsKey(tag))
161 return tags.get(tag).intValue();
165 public int getTagCount(String tagtype){
166 return getTagCount(new TagDescriptor(tagtype));
169 public FlagState[] clearTag(TagDescriptor tag){
170 if (tags.containsKey(tag)){
171 switch(tags.get(tag).intValue()){
173 HashSet newset=(HashSet)flagstate.clone();
174 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
176 return new FlagState[]{new FlagState(newset,cd,newtags)};
179 //two possibilities - count remains 2 or becomes 1
181 HashSet newset1=(HashSet)flagstate.clone();
182 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
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)};
194 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
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.
203 public String toString(FlagDescriptor[] flags)
205 StringBuffer sb = new StringBuffer(flagstate.size());
206 for(int i=0;i < flags.length; i++)
214 return new String(sb);
218 * @return returns the classdescriptor of the flagstate.
221 public ClassDescriptor getClassDescriptor(){
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>.
231 public FlagState setFlag(FlagDescriptor fd, boolean status) {
232 HashSet newset=(HashSet) flagstate.clone();
233 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
236 else if (newset.contains(fd)){
240 return new FlagState(newset, cd, newtags);
243 /** Tests for equality of two flagstate objects.
246 public boolean equals(Object o) {
247 if (o instanceof FlagState) {
248 FlagState fs=(FlagState)o;
251 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
256 public int hashCode() {
257 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
260 public String getLabel() {
264 public String getTextLabel() {
266 for(Iterator it=getFlags();it.hasNext();) {
267 FlagDescriptor fd=(FlagDescriptor) it.next();
271 label+=", "+fd.toString();
273 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
274 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
275 switch (tags.get(td).intValue()){
278 label=td.toString()+"(1)";
280 label+=", "+td.toString()+"(1)";
284 label=td.toString()+"(n)";
286 label+=", "+td.toString()+"(n)";
297 public Enumeration getTags(){
301 public int getExeTime() {
303 if(this.executeTime == -1) {
306 } catch (Exception e) {
310 return this.executeTime;
313 public void setExeTime(int exeTime) {
314 this.executeTime = exeTime;
317 public void calExeTime() throws Exception {
318 Iterator it = this.edges();
320 FEdge fe = (FEdge)it.next();
321 if(fe.getExeTime() == -1) {
322 throw new Exception("Error: Uninitiate FEdge!");
324 this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
326 this.executeTime = 0;
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;
337 public Object clone() {
340 o = (FlagState)super.clone();
341 } catch(CloneNotSupportedException e){
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));
349 o.inedges = new Vector();
350 for(int i = 0; i < this.inedges.size(); i++) {
351 o.inedges.addElement(this.inedges.elementAt(i));