1 package Analysis.TaskStateAnalysis;
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;
31 private int invokeNum;
34 * Creates a new flagstate with all flags set to false.
35 * @param cd ClassDescriptor
37 public FlagState(ClassDescriptor cd) {
38 this.flagstate=new HashSet();
40 this.tags=new Hashtable<TagDescriptor,Integer>();
41 this.uid=FlagState.nodeid++;
42 this.issourcenode=false;
43 this.executeTime = -1;
48 * Creates a new flagstate with flags set according to the HashSet.
49 * If the flag exists in the hashset, it's set to true else set to false.
50 * @param cd ClassDescriptor
51 * @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
53 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
54 this.flagstate=flagstate;
57 this.uid=FlagState.nodeid++;
58 this.issourcenode=false;
59 this.executeTime = -1;
68 * @param fd FlagDescriptor
69 * @return true if the flagstate contains fd else false.
71 public boolean get(FlagDescriptor fd) {
72 return flagstate.contains(fd);
75 /** Checks if the flagstate is a source node.
76 * @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
79 public boolean isSourceNode(){
83 /** Sets the flagstate as a source node.
85 public void setAsSourceNode(){
88 this.tasks=new Vector();
92 public void addAllocatingTask(TaskDescriptor task){
96 public Vector getAllocatingTasks(){
101 public String toString() {
102 return cd.toString()+getTextLabel();
105 /** @return Iterator over the flags in the flagstate.
108 public Iterator getFlags() {
109 return flagstate.iterator();
112 public int numFlags(){
113 return flagstate.size();
116 public FlagState[] setTag(TagDescriptor tag, boolean set){
117 HashSet newset1=(HashSet)flagstate.clone();
118 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
122 if (tags.containsKey(tag))
123 count=tags.get(tag).intValue();
126 newtags1.put(tag, new Integer(count));
127 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
130 if (tags.containsKey(tag))
131 count=tags.get(tag).intValue();
132 newtags1.put(tag, new Integer(count));
133 if ((count+1)==KLIMIT)
134 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
136 return new FlagState[] {new FlagState(newset1, cd, newtags1)};
140 public FlagState[] setTag(TagDescriptor tag){
141 HashSet newset1=(HashSet)flagstate.clone();
142 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
144 if (tags.containsKey(tag)){
145 //Code could try to remove flag that doesn't exist
147 switch (tags.get(tag).intValue()){
149 newtags1.put(tag,new Integer(MULTITAGS));
150 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
152 return new FlagState[] {this};
157 newtags1.put(tag,new Integer(ONETAG));
158 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
162 public int getTagCount(TagDescriptor tag) {
163 if (tags.containsKey(tag))
164 return tags.get(tag).intValue();
168 public int getTagCount(String tagtype){
169 return getTagCount(new TagDescriptor(tagtype));
172 public FlagState[] clearTag(TagDescriptor tag){
173 if (tags.containsKey(tag)){
174 switch(tags.get(tag).intValue()){
176 HashSet newset=(HashSet)flagstate.clone();
177 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
179 return new FlagState[]{new FlagState(newset,cd,newtags)};
182 //two possibilities - count remains 2 or becomes 1
184 HashSet newset1=(HashSet)flagstate.clone();
185 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
188 HashSet newset2=(HashSet)flagstate.clone();
189 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
190 newtags1.put(tag,new Integer(ONETAG));
191 return new FlagState[] {new FlagState(newset1, cd, newtags2),
192 new FlagState(newset2, cd, newtags2)};
197 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
201 /** Creates a string description of the flagstate
202 * e.g. a flagstate with five flags could look like 01001
203 * @param flags an array of flagdescriptors.
204 * @return string representation of the flagstate.
206 public String toString(FlagDescriptor[] flags)
208 StringBuffer sb = new StringBuffer(flagstate.size());
209 for(int i=0;i < flags.length; i++)
217 return new String(sb);
221 * @return returns the classdescriptor of the flagstate.
224 public ClassDescriptor getClassDescriptor(){
228 /** Sets the status of a specific flag in a flagstate after cloning it.
229 * @param fd FlagDescriptor of the flag whose status is being set.
230 * @param status boolean value
231 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
234 public FlagState setFlag(FlagDescriptor fd, boolean status) {
235 HashSet newset=(HashSet) flagstate.clone();
236 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
239 else if (newset.contains(fd)){
243 return new FlagState(newset, cd, newtags);
246 /** Tests for equality of two flagstate objects.
249 public boolean equals(Object o) {
250 if (o instanceof FlagState) {
251 FlagState fs=(FlagState)o;
254 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
259 public int hashCode() {
260 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
263 public String getLabel() {
267 public String getTextLabel() {
269 for(Iterator it=getFlags();it.hasNext();) {
270 FlagDescriptor fd=(FlagDescriptor) it.next();
274 label+=", "+fd.toString();
276 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
277 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
278 switch (tags.get(td).intValue()){
281 label=td.toString()+"(1)";
283 label+=", "+td.toString()+"(1)";
287 label=td.toString()+"(n)";
289 label+=", "+td.toString()+"(n)";
300 public Enumeration getTags(){
304 public int getExeTime() {
306 if(this.executeTime == -1) {
309 } catch (Exception e) {
313 return this.executeTime;
316 public void setExeTime(int exeTime) {
317 this.executeTime = exeTime;
320 public void calExeTime() throws Exception {
321 Iterator it = this.edges();
323 FEdge fe = (FEdge)it.next();
324 if(fe.getExeTime() == -1) {
325 throw new Exception("Error: Uninitiate FEdge!");
327 this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
329 this.executeTime = 0;
331 while(it.hasNext()) {
332 FEdge fe = (FEdge)it.next();
333 int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime();
334 if(temp < this.executeTime) {
335 this.executeTime = temp;
340 public Object clone() {
343 o = (FlagState)super.clone();
344 } catch(CloneNotSupportedException e){
347 o.uid = FlagState.nodeid++;
348 o.edges = new Vector();
349 for(int i = 0; i < this.edges.size(); i++) {
350 o.edges.addElement(this.edges.elementAt(i));
352 o.inedges = new Vector();
353 for(int i = 0; i < this.inedges.size(); i++) {
354 o.inedges.addElement(this.inedges.elementAt(i));
359 public void init4Simulate() {
363 public FEdge process(TaskDescriptor td) {
366 // refresh all the expInvokeNum of each edge
367 for(int i = 0; i < this.edges.size(); i++) {
368 next = (FEdge)this.edges.elementAt(i);
369 next.setExpInvokeNum((int)Math.round(this.invokeNum * (next.getProbability() / 100)));
372 // find the one with the biggest gap between its actual invoke time and the expected invoke time
373 // and associated with task td
376 for(int i = 0; i < this.edges.size(); i++) {
377 int temp = ((FEdge)this.edges.elementAt(index)).getInvokeNumGap();
378 if((temp > gap) && (next.getTask().equals(td))){
383 next = (FEdge)this.edges.elementAt(index);