blob: fb09c31643898e8e4aa802e1b264730b4b2209c6 [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.geode.internal;
import org.apache.geode.annotations.Immutable;
/**
* A timer class that reports current or elapsed time in nanonseconds. The static method
* {@link #getTime} reports the current time. The instance methods support basic stop-watch-style
* functions that are convenient for simple performance measurements. For example:
*
* <pre>
* class Example {
* void example() {
* NanoTimer timer = new NanoTimer();
* for (int i = 0; i < n; ++i) {
* someComputationThatYouAreMeasuring();
* long duration = timer.reset();
* System.out.println("Duration: " + duration);
* // To avoid contaminating timing with printing times,
* // you could call reset again here.
* }
* long average = timer.getTimeSinceConstruction() / n;
* System.out.println("Average: " + average);
* }
* }
* </pre>
*
*/
public class NanoTimer {
public static final long NANOS_PER_MILLISECOND = 1000000;
/**
* The timestamp taken when this timer was constructed.
*/
private final long constructionTime;
/**
* The timestamp taken when this timer was last reset or constructed.
*/
private long lastResetTime;
private final TimeService timeService;
@Immutable
private static final TimeService systemTimeService = new TimeService() {
@Override
public long getTime() {
return java.lang.System.nanoTime();
}
};
/**
* Create a NanoTimer.
*/
public NanoTimer() {
this.timeService = systemTimeService;
this.lastResetTime = systemTimeService.getTime();
this.constructionTime = this.lastResetTime;
}
/**
* For unit testing
*/
protected NanoTimer(TimeService ts) {
this.timeService = ts;
this.lastResetTime = ts.getTime();
this.constructionTime = this.lastResetTime;
}
/**
* Converts nanoseconds to milliseconds by dividing nanos by {@link #NANOS_PER_MILLISECOND}.
*
* @param nanos value in nanoseconds
* @return value converted to milliseconds
*/
public static long nanosToMillis(long nanos) {
return nanos / NANOS_PER_MILLISECOND;
}
/**
* Converts milliseconds to nanoseconds by multiplying millis by {@link #NANOS_PER_MILLISECOND}.
*
* @param millis value in milliseconds
* @return value converted to nanoseconds
*/
public static long millisToNanos(long millis) {
return millis * NANOS_PER_MILLISECOND;
}
/**
* Return the time in nanoseconds since some arbitrary time in the past. The time rolls over to
* zero every 2^64 nanosecs (approx 584 years). Interval computations spanning periods longer than
* this will be wrong.
*/
public static long getTime() {
return java.lang.System.nanoTime();
}
/**
* Return the construction time in nanoseconds since some arbitrary time in the past.
*
* @return timestamp in nanoseconds since construction.
*/
public long getConstructionTime() {
return this.constructionTime;
}
/**
* Return the last reset time in naonseconds since some arbitrary time in the past.
* <p/>
* The time rolls over to zero every 2^64 nanosecs (approx 584 years). Interval computations
* spanning periods longer than this will be wrong. If the timer has not yet been reset then the
* construction time is returned.
*
* @return timestamp in nanoseconds of construction or the last reset.
*/
public long getLastResetTime() {
return this.lastResetTime;
}
/**
* Compute and return the time in nanoseconds since the last reset or construction of this timer,
* and reset the timer to the current {@link #getTime}.
*
* @return time in nanoseconds since construction or last reset.
*/
public long reset() {
long save = this.lastResetTime;
this.lastResetTime = this.timeService.getTime();
return this.lastResetTime - save;
}
/**
* Compute and return the time in nanoseconds since the last reset or construction of this Timer,
* but does not reset this timer.
*
* @return time in nanoseconds since construction or last reset.
*/
public long getTimeSinceReset() {
return this.timeService.getTime() - this.lastResetTime;
}
/**
* Compute and return the time in nanoseconds since this timer was constructed.
*
* @return time in nanoseconds since construction.
*/
public long getTimeSinceConstruction() {
return this.timeService.getTime() - this.constructionTime;
}
/**
* Allows unit tests to insert a deterministic clock for testing.
*/
public interface TimeService {
/**
* Returns the current time.
*/
long getTime();
}
}