blob: db3718b071ccf85f715610b199a8daabb4129b2a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.event.common.apps;
import javax.persistence.Entity;
@Entity
/*
Millisecond (only) accuracy timer.
Java 1.4 supposedly has sun.misc.Perf.
Java 1.5 has System.nanoTime (JSR 166)
*/
public class Duration
implements Cloneable {
private String _name;
private boolean _started;
private boolean _running;
private long _startTime; // millis
private long _stopTime; // millis
// NYI clock time of day at start
public Duration(String name) {
_name = name;
_started = false;
_running = false;
}
public String getName() {
return _name;
}
public synchronized void start() {
if (_started) {
throw new RuntimeException("Duration was already started.");
}
_startTime = System.currentTimeMillis();
_started = true;
_running = true;
}
public synchronized void stop() {
if (!_started) {
throw new RuntimeException("Duration was never started.");
}
if (!_running) {
throw new RuntimeException("Duration was already stopped.");
}
_stopTime = System.currentTimeMillis();
_running = false;
}
protected Object clone()
throws CloneNotSupportedException {
return super.clone();
}
/*
Returns a new Duration object from a currently running timer
as a snapshot of this object.
The returned timer is stopped, while this object continue on.
*/
public synchronized Duration getCurrentDuration() {
if (!_started) {
throw new RuntimeException("Duration was never started.");
}
if (!_running) {
throw new RuntimeException("Duration is not running.");
}
long now = System.currentTimeMillis();
Duration currentDuration;
try {
currentDuration = (Duration) this.clone();
} catch (Exception e) {
currentDuration = new Duration("");
}
currentDuration._stopTime = now;
currentDuration._running = false;
return currentDuration;
}
/* Obtain the duration that this timer has run (in seconds) */
public synchronized double getDurationAsSeconds() {
if (!_started) {
throw new RuntimeException("Duration was never started.");
}
if (_running) {
// snapshot
Duration snapshot = getCurrentDuration();
return (1000.0 * (snapshot._stopTime - snapshot._startTime));
}
// Return a double value. Someday this class may make use of
// higher precision timing services (e.g. java 1.5)
return ((_stopTime - _startTime) / (double) 1000.0);
}
public synchronized boolean isRunning() {
return _running;
}
public synchronized boolean wasStarted() {
return _started;
}
public String toString() {
double time = 0.0;
StringBuffer buf = new StringBuffer(256);
if (wasStarted()) {
if (isRunning()) {
Duration snapshot = getCurrentDuration();
time = snapshot.getDurationAsSeconds();
} else {
time = getDurationAsSeconds();
}
buf.append("Duration for '" + _name + "' is " + time + " (s).");
} else {
buf.append("Duration for '" + _name +
"' has not yet been started.");
}
return buf.toString();
}
/* Example usage:
public static void main (String[] args)
throws Exception
{
Duration test = new Duration ("hello, count to 1 million");
System.out.println (test);
test.start ();
for (int i = 0; i < 1000000000; i++)
{
}
test.stop ();
System.out.println (test);
}
*/
}