001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-10-4
005     * Time: 16:54:10
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util;
010    
011    import EVolve.util.Equators.Set;
012    
013    import java.util.*;
014    
015    public class DataTrace {
016        private ArrayList trace, stack;
017        private int invocationNum, setSize;
018        private Set currentSet;
019    
020        public DataTrace() {
021            trace = new ArrayList();
022            stack = new ArrayList();
023            invocationNum = 0;
024            currentSet = null;
025        }
026    
027        public DataTrace(Set workingSet) {
028            currentSet = workingSet;
029            trace = new ArrayList();
030            this.setSize = currentSet.size();
031            trace.add(currentSet);
032        }
033    
034        public void updateTrace(int calleeId, boolean methodEntry) {
035            int[] methodFootprint = new int[2];
036    
037            methodFootprint[0] = calleeId;
038            methodFootprint[1] = methodEntry ? 1 : 0; // 1 means a entry event, 0 means exit event
039            if (!methodEntry && (trace.size() == 0)) return;
040    
041            if (methodEntry) invocationNum++;
042            trace.add(methodFootprint);
043        }
044    
045        public void updateTrace2(int traceId) {
046            trace.add(new Integer(traceId));
047        }
048    
049        public void updateTrace3(int traceId) {
050            if (currentSet.setFull()) {
051                currentSet = currentSet.newSet();
052                trace.add(currentSet);
053            }
054    
055            currentSet.addElement(traceId);
056        }
057    
058        public ArrayList getCallerChains(int callerId,int calleeId) {
059            ArrayList returnVal = new ArrayList();
060            ArrayList callerChain;
061            int footprint[];
062    
063            stack.clear();
064            for (int i = 0; i<trace.size(); i++) {
065                footprint = (int[])trace.get(i);
066            
067                if (footprint[1] == 0) {// method exit
068                    if (stack.size() != 0) stack.remove(stack.size()-1);
069                }
070                else {
071                    stack.add(new Integer(footprint[0]));
072                    if ((stack.size()>=2) &&
073                        (((Integer)stack.get(stack.size()-1)).intValue() == calleeId) &&
074                        (((Integer)stack.get(stack.size()-2)).intValue() == callerId)) {
075                        callerChain = (ArrayList)stack.clone();
076                        callerChain.remove(callerChain.size()-1);
077                        returnVal.add(callerChain);
078                    }
079                }
080    
081            }
082    
083            // remove duplicates
084            ArrayList temp = new ArrayList(), tempReturnVal = new ArrayList();
085            for (int i = 1; i< returnVal.size(); i++) {
086                temp = (ArrayList)returnVal.get(i-1);
087                boolean found = false;
088                for (int j=i; j<returnVal.size(); j++) {
089                    callerChain = (ArrayList)returnVal.get(j);
090                    if (temp.size() != callerChain.size())
091                        continue;
092                    for (int k=0; k< temp.size(); k++) {
093                        if (((Integer)temp.get(k)).intValue() != ((Integer)callerChain.get(k)).intValue()) {
094                            found = false;
095                            break;
096                        }
097                        found = true;
098                    }
099                    if (found) break;
100                }
101                if (!found)
102                    tempReturnVal.add(temp);
103            }
104            if (tempReturnVal.size()>0)
105                returnVal = tempReturnVal;
106            return returnVal;
107        }
108        
109        public ArrayList getCallerChain(int callerId, int calleeId) {
110            ArrayList callerChain = new ArrayList();
111            int[] footprint;
112    
113            callerChain.add(new Integer(callerId));
114            stack.clear();
115            for (int i = 0; i<trace.size(); i++) {
116                footprint = (int[])trace.get(i);
117    
118                if (footprint[1] == 0) { // method exit event
119                    if (stack.size() != 0) stack.remove(stack.size()-1);
120                } else {
121                    stack.add(new Integer(footprint[0]));
122                    if ((stack.size()>=2) &&
123                        (((Integer)stack.get(stack.size()-1)).intValue() == calleeId) &&
124                        (((Integer)stack.get(stack.size()-2)).intValue() == callerId)) {
125                        callerChain = (ArrayList)stack.clone();
126                        callerChain.remove(callerChain.size()-1);
127                        break;
128                    }
129                }
130            }
131    
132            return callerChain;
133        }
134    
135        public ArrayList getCallees(int callerId, int calleeId) {
136            ArrayList callees = new ArrayList();
137            int footprint[],i;
138    
139            stack.clear();
140            for (i = 0; i<trace.size(); i++) {
141                footprint = (int[])trace.get(i);
142    
143                if (footprint[1] == 0) { // method exit event
144                    if (stack.size() != 0) stack.remove(stack.size()-1);
145                } else {
146                    stack.add(new Integer(footprint[0]));
147                    if ((stack.size()>=3) &&
148                        (((Integer)stack.get(stack.size()-2)).intValue() == calleeId) &&
149                        (((Integer)stack.get(stack.size()-3)).intValue() == callerId)) {
150                        callees.add(new Integer(footprint[0]));
151                    }
152                }
153            }
154    
155            // remove duplicates
156            ArrayList temp = new ArrayList();
157            for (i=0; i<callees.size();i++) {
158                int value = ((Integer)callees.get(i)).intValue();
159                boolean found = false;
160                if (i==0) {
161                    temp.add(new Integer(value));
162                    continue;
163                }
164                for (int j=0; j<temp.size();j++) {
165                    if (value == ((Integer)temp.get(j)).intValue()) {
166                        found = true;
167                        break;
168                    }
169                }
170                if (!found)
171                    temp.add(new Integer(value));
172            }
173            callees = temp;
174            return callees;
175        }
176    
177        public int size() {
178            return trace.size();
179        }
180    
181        public ArrayList getTrace() {
182            return trace;
183        }
184    }