/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.core.designer.util; import java.io.Serializable; import org.eclipse.core.runtime.IStatus; import org.teiid.core.designer.CoreModelerPlugin; /** * @since 8.0 */ public class Stopwatch implements Serializable { private static final long serialVersionUID = 8632873770474816540L; private long start = 0; private long stop = 0; private Statistics stats = new Statistics(); private boolean active = true; private static final String SECONDS = CoreModelerPlugin.Util.getString("Stopwatch.seconds"); //$NON-NLS-1$ private static final String MILLISECONDS = CoreModelerPlugin.Util.getString("Stopwatch.milliseconds"); //$NON-NLS-1$ private static final int VALUE_LENGTH = 10; /** * Return whether the stopwatch is active. When the stopwatch is active, it is recording the time durations (via * <code>start</code> and <code>stop</code>) and will print duration statistics (via <code>printDuration</code>). When the * stopwatch is inactive, invoking these methods does nothing but return immediately. * * @return true if the stopwatch is active, or false if it is inactive. */ public boolean isActive() { return active; } /** * If the stopwatch is active, record the starting time for a time segment. If the stopwatch is inactive, the method returns * immediately. * * @see #isActive */ public void start() { if (active) { start = System.currentTimeMillis(); } } /** * If the stopwatch is active, record the starting time for a time segment. If the stopwatch is inactive, the method returns * immediately. * * @see #isActive */ public void start( boolean reset ) { if (reset) reset(); start(); } /** * If the stopwatch is active, record the ending time for a time segment. If the stopwatch is inactive, the method returns * immediately. * * @see #isActive */ public void stop() { if (active) { stop = System.currentTimeMillis(); stats.add(stop - start); } } /** * Reset the statistics for this stopwatch, regardless of the active state. */ public void reset() { start = 0; stop = 0; stats.reset(); } /** * Return the total duration recorded, in milliseconds. * * @return the total number of milliseconds that have been recorded */ public long getTotalDuration() { return stats.getTotal(); } /** * Return the average duration recorded as a date. * * @return the number of milliseconds that have been recorded averaged over the number of segments */ public float getAverageDuration() { return stats.getAverage(); } /** * Return the number of segments that have been recorded. * * @return the number of segments */ public int getSegmentCount() { return stats.getCount(); } @Override public String toString() { String units = MILLISECONDS; StringBuffer valueString = null; long value = getTotalDuration(); if (value >= 1000) { float fvalue = value / 1000.0f; units = SECONDS; valueString = new StringBuffer(Float.toString(fvalue)); } else { valueString = new StringBuffer(Long.toString(value)); } valueString.append(units); return valueString.toString(); } public String getTimeValueAsString( long value ) { String units = MILLISECONDS; StringBuffer valueString = null; if (value >= 1000) { float fvalue = value / 1000.0f; units = SECONDS; valueString = new StringBuffer(Float.toString(fvalue)); } else { valueString = new StringBuffer(Long.toString(value)); } while (valueString.length() < VALUE_LENGTH) valueString.insert(0, ' '); return "" + valueString + units; //$NON-NLS-1$ } public String getTimeValueAsString( float value ) { String units = MILLISECONDS; if (value >= 1000.0f) { value = value / 1000.0f; units = SECONDS; } StringBuffer valueString = new StringBuffer(Float.toString(value)); while (valueString.length() < VALUE_LENGTH) valueString.insert(0, ' '); return "" + valueString + units; //$NON-NLS-1$ } public String getValueAsString( int value ) { StringBuffer valueString = new StringBuffer(Integer.toString(value)); while (valueString.length() < VALUE_LENGTH) valueString.insert(0, ' '); return "" + valueString; //$NON-NLS-1$ } /** * @since 8.0 */ public class Statistics implements Serializable { private static final long serialVersionUID = 6451257438010489623L; private long minimum = 0; private long maximum = 0; private long last = 0; private long total = 0; private int count = 0; private boolean minimumInitialized = false; public long getMinimum() { return minimum; } public long getMaximum() { return maximum; } public long getLast() { return last; } public float getAverage() { return ((float)total / (float)count); } public long getTotal() { return total; } public int getCount() { return count; } public void add( long duration ) { ++count; total += duration; last = duration; if (duration > maximum) { maximum = duration; } else if (!minimumInitialized || duration < minimum) { minimum = duration; minimumInitialized = true; } } public void reset() { minimum = 0; maximum = 0; last = 0; total = 0; count = 0; minimumInitialized = false; } } /** * Logs a message containing a time increment in milliseconds and a messages describing the operation or context that the time * relates to. * * @param message * @param time * @since 4.3 */ public static void logTimedMessage( String message, long time ) { CoreModelerPlugin.Util.log(IStatus.INFO, getTimeString(time) + message); } /** * This convience method stops the current stopwatch, logs a message containing the resulting time increment/duration and * restarts the stopwatch. * * @param message * @since 4.3 */ public void stopLogIncrementAndRestart( String message ) { stop(); logTimedMessage(message, getTotalDuration()); // Restart by reset = true start(true); } private static String getTimeString( long time ) { String timeString = CoreStringUtil.Constants.EMPTY_STRING + time; int nSpaces = 8 - timeString.length(); StringBuffer buff = new StringBuffer(); buff.append("Time = ["); //$NON-NLS-1$ for (int i = 0; i < nSpaces; i++) { buff.append(CoreStringUtil.Constants.SPACE); } buff.append(timeString + "] ms : "); //$NON-NLS-1$ return buff.toString(); } }