001: /*
002: * Copyright 2004 Clinton Begin
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package com.ibatis.common.util;
017:
018: import com.ibatis.common.logging.Log;
019: import com.ibatis.common.logging.LogFactory;
020:
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.Map;
024:
025: /**
026: * Stopwatch class used for testing.
027: */
028: public class Stopwatch {
029:
030: private static final Log log = LogFactory.getLog(Stopwatch.class);
031:
032: private Map taskMap = new HashMap();
033:
034: private String currentTaskName = null;
035: private long currentTaskTime = 0;
036:
037: /**
038: * Get an iterator of the tasks
039: * @return - the Iterator
040: */
041: public Iterator getTaskNames() {
042: return taskMap.keySet().iterator();
043: }
044:
045: /**
046: * Get the number of times assigned to a task
047: * @param taskName - the name of the task
048: * @return - the number of times
049: */
050: public long getTaskCount(String taskName) {
051: return ((TaskStat) taskMap.get(taskName)).getCount();
052: }
053:
054: /**
055: * Get the total time added to a task
056: * @param taskName - the name of the task
057: * @return - the total time added to the task
058: */
059: public long getTotalTaskTime(String taskName) {
060: return ((TaskStat) taskMap.get(taskName)).getTotal();
061: }
062:
063: /**
064: * Get the maximum time added to a task
065: * @param taskName - the name of the task
066: * @return - the maximum time added to a task
067: */
068: public long getMaxTaskTime(String taskName) {
069: return ((TaskStat) taskMap.get(taskName)).getMax();
070: }
071:
072: /**
073: * Get the minimum time added to a task
074: * @param taskName - the name of the task
075: * @return - the minimum time added to a task
076: */
077: public long getMinTaskTime(String taskName) {
078: return ((TaskStat) taskMap.get(taskName)).getMin();
079: }
080:
081: /**
082: * Get the average time added to a task
083: * @param taskName - the name of the task
084: * @return - the average time added to a task
085: */
086: public long getAvgTaskTime(String taskName) {
087: return ((TaskStat) taskMap.get(taskName)).getAverage();
088: }
089:
090: /**
091: * Start (create) a task
092: * @param taskName - the name of the task
093: */
094: public void start(String taskName) {
095: if (log.isDebugEnabled()) {
096: log.debug("Starting: " + taskName);
097: }
098: this .currentTaskName = taskName;
099: currentTaskTime = System.currentTimeMillis();
100: }
101:
102: /**
103: * Stop the timer on a task
104: */
105: public void stop() {
106: if (log.isDebugEnabled()) {
107: log.debug("Stopping: " + currentTaskName);
108: }
109: currentTaskTime = System.currentTimeMillis() - currentTaskTime;
110: appendTaskTime(currentTaskName, currentTaskTime);
111: }
112:
113: private synchronized void appendTaskTime(String taskName,
114: long taskTime) {
115: TaskStat stat = (TaskStat) taskMap.get(taskName);
116: if (stat == null) {
117: stat = new TaskStat();
118: taskMap.put(taskName, stat);
119: }
120: stat.appendTaskTime(taskTime);
121: }
122:
123: /**
124: * Merge another StopWatch into this one
125: * @param watch - the StopWatch to merge into this one
126: */
127: public void mergeStopwatch(Stopwatch watch) {
128: Iterator names = watch.getTaskNames();
129: while (names.hasNext()) {
130: String name = (String) names.next();
131: long taskTime = watch.getTotalTaskTime(name);
132: appendTaskTime(name, taskTime);
133: }
134: }
135:
136: /**
137: * Reset all of the timers in this StopWatch
138: */
139: public synchronized void reset() {
140: taskMap.clear();
141: }
142:
143: public String toString() {
144: StringBuffer buffer = new StringBuffer();
145: buffer.append("Task,Count,Total,Max,Min,Avg\n");
146: Iterator names = getTaskNames();
147: while (names.hasNext()) {
148: String name = (String) names.next();
149: long taskCount = getTaskCount(name);
150: long taskTime = getTotalTaskTime(name);
151: long taskMin = getMinTaskTime(name);
152: long taskMax = getMaxTaskTime(name);
153: long taskAvg = getAvgTaskTime(name);
154: buffer.append(name + "," + taskCount + "," + taskTime + ","
155: + taskMax + "," + taskMin + "," + taskAvg + "\n");
156: }
157: return buffer.toString();
158: }
159:
160: private class TaskStat {
161: private static final long UNSET = -999999;
162:
163: private long count = 0;
164: private long total = 0;
165: private long min = UNSET;
166: private long max = UNSET;
167:
168: /**
169: * Add some time to a task
170: * @param taskTime - the time to add
171: */
172: public void appendTaskTime(long taskTime) {
173: count++;
174: total += taskTime;
175: if (max == UNSET || taskTime > max) {
176: max = taskTime;
177: }
178: if (min == UNSET || taskTime < min) {
179: min = taskTime;
180: }
181: }
182:
183: /**
184: * Get the total time for the task
185: * @return - the total time
186: */
187: public long getTotal() {
188: return total;
189: }
190:
191: /**
192: * Get the maximum of the times added to the task
193: * @return - the max value
194: */
195: public long getMax() {
196: return max;
197: }
198:
199: /**
200: * Get the minimum of the times added to the task
201: * @return - the minimum value
202: */
203: public long getMin() {
204: return min;
205: }
206:
207: /**
208: * Get the number of times added to the task
209: * @return - the number of times
210: */
211: public long getCount() {
212: return count;
213: }
214:
215: /**
216: * Get the average of the times added to the task
217: * @return - the average
218: */
219: public long getAverage() {
220: if (count > 0) {
221: return Math.round((double) total / (double) count);
222: } else {
223: return 0;
224: }
225: }
226:
227: }
228:
229: }
|