1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package net.sf.jour.rt.swingmonitor;
22
23 import java.io.BufferedWriter;
24 import java.io.File;
25 import java.io.FileWriter;
26 import java.io.IOException;
27 import java.io.Serializable;
28 import java.util.HashMap;
29 import java.util.Iterator;
30
31 import net.sf.jour.filter.MatchFilter;
32 import net.sf.jour.rt.agent.ProfilerEvent;
33 import net.sf.jour.rt.swingmonitor.ui.FDouble;
34 import net.sf.jour.rt.view.ViewFilter;
35 import net.sf.jour.rt.view.ViewFilterItem;
36 import net.sf.jour.statistic.MethodAccumulation;
37 import net.sf.jour.statistic.TimeBaseAccumulationList;
38 import net.sf.jour.util.queue.Queue;
39
40 import org.apache.log4j.Logger;
41
42 /***
43 *
44 * TODO ...
45 *
46 * Created on 04.12.2004
47 *
48 * Contributing Author(s):
49 *
50 * Misha Lifschitz <mishalifschitz at users.sourceforge.net> (Inital implementation)
51 * Vlad Skarzhevskyy <vlads at users.sourceforge.net> (Inital implementation)
52 *
53 * @author michaellif
54 * @version $Revision: 1.19 $ ($Author: vlads $) $Date: 2004/12/17 04:17:46 $
55 */
56 public class MethodExceutionStatistics implements Serializable {
57
58 protected static final Logger log = Logger.getLogger(MethodExceutionStatistics.class);
59
60 private HashMap methodStatHash = new HashMap();
61 private ViewFilter viewFilter;
62
63 TimeBaseAccumulationList totals;
64
65 private transient HashMap notCompletedMethodsHash = new HashMap();
66
67 public final static String[] columnNames = { "Method", "first", "min", "max", "average", "count", "sd", "total", "Exc" };
68
69 long countTotal;
70
71 public MethodExceutionStatistics(ViewFilter viewFilter) {
72 totals = new TimeBaseAccumulationList();
73 this.viewFilter = viewFilter;
74 }
75
76 /***
77 * @return Returns the countTotal.
78 */
79 public long getCountTotal() {
80 return countTotal;
81 }
82
83 /***
84 * DOCUMENT ME!
85 *
86 * @param clazz DOCUMENT ME!
87 */
88 public boolean processEvent(ProfilerEvent event, MatchFilter filter) {
89 countTotal ++;
90 if (event.onMethodStart()) {
91 addStartedMethodEvent(event);
92 } else {
93 recalcMethodStat(event, filter);
94 }
95 return true;
96 }
97
98 public void recalcMethodStat(ProfilerEvent endMethodEvent, MatchFilter filter) {
99 Object methodInstanceId = getMethodInstanceId(endMethodEvent);
100 if (!notCompletedMethodsHash.containsKey(methodInstanceId)) {
101
102 log.warn("Method end event before method start:" + endMethodEvent);
103 return;
104 }
105 Queue queue = (Queue) notCompletedMethodsHash.get(methodInstanceId);
106 if (queue == null) {
107 log.warn("Method end but there is no start events:" + endMethodEvent);
108 return;
109 }
110 if (queue.isEmpty()) {
111 log.warn("Method end but there is no start events:" + endMethodEvent);
112 return;
113 }
114 ProfilerEvent startMethodEvent = (ProfilerEvent)queue.dequeue();
115 double time = endMethodEvent.getTimestamp() - startMethodEvent.getTimestamp();
116
117 if ((totals.getCount() == 0) && (filter != null) && (filter instanceof ViewFilterItem)) {
118 totals.setTimeFrame(((ViewFilterItem)filter).getTimeFrame());
119 }
120 totals.add(endMethodEvent.getTimestamp(), new Double(time));
121
122 MethodAccumulation methodStat = getMethodStat(endMethodEvent.getMethodID(), endMethodEvent, filter);
123 methodStat.add(startMethodEvent, endMethodEvent);
124 }
125
126 public void addStartedMethodEvent(ProfilerEvent event) {
127 Object methodInstanceId = getMethodInstanceId(event);
128 Queue queue = null;
129 if (!notCompletedMethodsHash.containsKey(methodInstanceId)) {
130 queue = new Queue();
131 notCompletedMethodsHash.put(methodInstanceId, queue);
132 } else {
133 queue = (Queue) notCompletedMethodsHash.get(methodInstanceId);
134 }
135 if (queue != null) {
136 queue.enqueue(event);
137 }
138 }
139
140 public MethodAccumulation getMethodStat(Object methodId, ProfilerEvent endMethodEvent, MatchFilter filter) {
141 MethodAccumulation methodStat;
142 if (!methodStatHash.containsKey(methodId)) {
143 methodStat = new MethodAccumulation(getUiMethodName(endMethodEvent));
144 if ((filter != null) && (filter instanceof ViewFilterItem)) {
145 methodStat.setTimeFrame(((ViewFilterItem)filter).getTimeFrame());
146 }
147 synchronized (this) {
148 methodStatHash.put(methodId, methodStat);
149 }
150 } else {
151 methodStat = (MethodAccumulation) methodStatHash.get(methodId);
152 if (methodStat.getCount() == 0) {
153 if (filter instanceof ViewFilterItem) {
154 methodStat.setTimeFrame(((ViewFilterItem)filter).getTimeFrame());
155 }
156
157 methodStat.setName(getUiMethodName(endMethodEvent));
158 }
159 }
160 return methodStat;
161 }
162
163 /***
164 * DOCUMENT ME!
165 *
166 * @return DOCUMENT ME!
167 */
168 public synchronized Object[][] getReport() {
169 Object[][] retVal = new Object[methodStatHash.keySet().size()][10];
170 Iterator iter = methodStatHash.keySet().iterator();
171 int counter = 0;
172
173 while (iter.hasNext()) {
174 Object methodId = iter.next();
175 MethodAccumulation methodStat = (MethodAccumulation) methodStatHash.get(methodId);
176 retVal[counter][0] = methodStat;
177 retVal[counter][1] = methodStat.getName();
178 retVal[counter][2] = new FDouble(methodStat.getFirstRunElapsedTime());
179 retVal[counter][3] = new FDouble(methodStat.getMin());
180 retVal[counter][4] = new FDouble(methodStat.getMax());
181 retVal[counter][5] = new FDouble(methodStat.getMean());
182 retVal[counter][6] = new Long(methodStat.getCount());
183 retVal[counter][7] = new FDouble(methodStat.getStandardDeviation());
184 retVal[counter][8] = new FDouble(methodStat.getTotal());
185 retVal[counter][9] = new Long(methodStat.getExceptionCount());
186
187 counter++;
188 }
189
190 return retVal;
191 }
192
193 public void writeCSV(BufferedWriter bw, Object[] line) throws IOException {
194 bw.write("\"");
195 for (int i = 1; i < line.length; i++) {
196 bw.write(line[i].toString());
197 if (i < line.length -1) {
198 bw.write("\",\"");
199 }
200 }
201 bw.write("\"\n");
202 }
203
204 public synchronized boolean saveReport(File file, Object[][] data) {
205 try {
206 BufferedWriter bw = new BufferedWriter(new FileWriter(file));
207
208 writeCSV(bw, columnNames);
209
210 for (int i = 0; i < data.length; i++) {
211 writeCSV(bw, data[i]);
212 }
213 bw.close();
214 return true;
215 } catch (IOException e) {
216
217 log.error("Error", e);
218 return false;
219 }
220
221 }
222
223 public synchronized void reset() {
224 totals.reset();
225
226 Iterator iter = methodStatHash.values().iterator();
227 while (iter.hasNext()) {
228 MethodAccumulation methodStat = (MethodAccumulation) iter.next();
229 methodStat.reset();
230 }
231
232 this.notCompletedMethodsHash = new HashMap();
233 this.countTotal = 0;
234 }
235
236 public String getUiMethodSignature(ProfilerEvent endMethodEvent) {
237 String s = endMethodEvent.getMethodSignature();
238 if (s == null) {
239 return "";
240 }
241 return viewFilter.getMethodsignatureView().subst(s);
242 }
243
244 private String getUiMethodName(ProfilerEvent endMethodEvent) {
245 String method = endMethodEvent.getMethodName().trim();
246 if (method.equals(endMethodEvent.getClassName())) {
247 method = "<init>";
248 }
249 return viewFilter.getClassnameView().subst(endMethodEvent.getClassName())
250 + "->" + method
251 + getUiMethodSignature(endMethodEvent);
252 }
253
254
255 private String x_getMethodId(String clazz, String method) {
256 return clazz.trim() + "->" + method.trim() +"";
257 }
258
259 /***
260 *
261 * @param clazz
262 * @param method
263 * @param threadName
264 * @return
265 */
266
267 private String x_getMethodInstanceId(String clazz, String method, String threadName) {
268 return clazz.trim() + "->(" + method.trim() +")[" + threadName.trim() + "]";
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298 private Object getMethodInstanceId(ProfilerEvent event) {
299
300
301 return event.getMethodID().toString() + "@" + event.getThreadID().toString();
302 }
303
304
305 /***
306 * @return Returns the totals.
307 */
308 public TimeBaseAccumulationList getTotals() {
309 return totals;
310 }
311 }