001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.invocation;
023:
024: import java.io.Serializable;
025: import java.lang.reflect.Method;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.Map;
029:
030: import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
031:
032: /** A method invocation statistics collection class.
033: *
034: * @author Scott.Stark@jboss.org
035: * @version $Revision: 61830 $
036: */
037: public class InvocationStatistics implements Serializable {
038: /** @since 4.2.0 */
039: private static final long serialVersionUID = -8031193044335393420L;
040:
041: /** A HashMap<Method, TimeStatistic> of the method invocations */
042: private Map methodStats;
043:
044: public long concurrentCalls = 0;
045: public long maxConcurrentCalls = 0;
046: public long lastResetTime = System.currentTimeMillis();
047:
048: public class TimeStatistic implements Serializable {
049: /** @since 4.2.0 */
050: private static final long serialVersionUID = -8689933338506854386L;
051:
052: public volatile long count;
053: public volatile long minTime = Long.MAX_VALUE;
054: public volatile long maxTime;
055: public volatile long totalTime;
056:
057: public void reset() {
058: count = 0;
059: minTime = Long.MAX_VALUE;
060: maxTime = 0;
061: totalTime = 0;
062: }
063: }
064:
065: public InvocationStatistics() {
066: methodStats = new ConcurrentReaderHashMap();
067: }
068:
069: /** Update the TimeStatistic for the given method. This synchronizes on
070: * m to ensure that the TimeStatistic for m is updated atomically.
071: *
072: * @param m the method to update the statistics for.
073: * @param elapsed the elapsed time in milliseconds for the invocation.
074: */
075: public void updateStats(Method m, long elapsed) {
076: TimeStatistic stat = (TimeStatistic) methodStats.get(m);
077: if (stat == null) {
078: stat = new TimeStatistic();
079: methodStats.put(m, stat);
080: }
081: stat.count++;
082: stat.totalTime += elapsed;
083: if (stat.minTime > elapsed)
084: stat.minTime = elapsed;
085: if (stat.maxTime < elapsed)
086: stat.maxTime = elapsed;
087: }
088:
089: public synchronized void callIn() {
090: concurrentCalls++;
091: if (concurrentCalls > maxConcurrentCalls)
092: maxConcurrentCalls = concurrentCalls;
093: }
094:
095: public synchronized void callOut() {
096: concurrentCalls--;
097: }
098:
099: /** Resets all current TimeStatistics.
100: *
101: */
102: public void resetStats() {
103: synchronized (methodStats) {
104: Iterator iter = methodStats.values().iterator();
105: while (iter.hasNext()) {
106: TimeStatistic stat = (TimeStatistic) iter.next();
107: stat.reset();
108: }
109: }
110: maxConcurrentCalls = 0;
111: lastResetTime = System.currentTimeMillis();
112: }
113:
114: /** Access the current collection of method invocation statistics
115: *
116: * @return A HashMap<Method, TimeStatistic> of the method invocations
117: */
118: public Map getStats() {
119: return methodStats;
120: }
121:
122: /** Generate an XML fragement for the InvocationStatistics. The format is
123: * <InvocationStatistics concurrentCalls="c">
124: * <method name="aMethod" count="x" minTime="y" maxTime="z" totalTime="t" />
125: * ...
126: * </InvocationStatistics>
127: *
128: * @return an XML representation of the InvocationStatistics
129: */
130: public String toString() {
131: StringBuffer tmp = new StringBuffer(
132: "<InvocationStatistics concurrentCalls='");
133: tmp.append(concurrentCalls);
134: tmp.append("' >\n");
135:
136: HashMap copy = new HashMap(methodStats);
137: Iterator iter = copy.entrySet().iterator();
138: while (iter.hasNext()) {
139: Map.Entry entry = (Map.Entry) iter.next();
140: TimeStatistic stat = (TimeStatistic) entry.getValue();
141: if (stat != null) {
142: tmp.append("<method name='");
143: tmp.append(entry.getKey());
144: tmp.append("' count='");
145: tmp.append(stat.count);
146: tmp.append("' minTime='");
147: tmp.append(stat.minTime);
148: tmp.append("' maxTime='");
149: tmp.append(stat.maxTime);
150: tmp.append("' totalTime='");
151: tmp.append(stat.totalTime);
152: tmp.append("' />\n");
153: }
154: }
155: tmp.append("</InvocationStatistics>");
156: return tmp.toString();
157: }
158: }
|