/*
* Copyright (C) 2015 Brett Wooldridge
*
* Licensed 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 com.zaxxer.hikari.util;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MICROSECONDS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.TimeUnit;
A resolution-independent provider of current time-stamps and elapsed time
calculations.
Author: Brett Wooldridge
/**
* A resolution-independent provider of current time-stamps and elapsed time
* calculations.
*
* @author Brett Wooldridge
*/
public interface ClockSource
{
static ClockSource CLOCK = Factory.create();
Get the current time-stamp (resolution is opaque).
Returns: the current time-stamp
/**
* Get the current time-stamp (resolution is opaque).
*
* @return the current time-stamp
*/
static long currentTime() {
return CLOCK.currentTime0();
}
long currentTime0();
Convert an opaque time-stamp returned by currentTime() into
milliseconds.
Params: - time – an opaque time-stamp returned by an instance of this class
Returns: the time-stamp in milliseconds
/**
* Convert an opaque time-stamp returned by currentTime() into
* milliseconds.
*
* @param time an opaque time-stamp returned by an instance of this class
* @return the time-stamp in milliseconds
*/
static long toMillis(long time) {
return CLOCK.toMillis0(time);
}
long toMillis0(long time);
Convert an opaque time-stamp returned by currentTime() into
nanoseconds.
Params: - time – an opaque time-stamp returned by an instance of this class
Returns: the time-stamp in nanoseconds
/**
* Convert an opaque time-stamp returned by currentTime() into
* nanoseconds.
*
* @param time an opaque time-stamp returned by an instance of this class
* @return the time-stamp in nanoseconds
*/
static long toNanos(long time) {
return CLOCK.toNanos0(time);
}
long toNanos0(long time);
Convert an opaque time-stamp returned by currentTime() into an
elapsed time in milliseconds, based on the current instant in time.
Params: - startTime – an opaque time-stamp returned by an instance of this class
Returns: the elapsed time between startTime and now in milliseconds
/**
* Convert an opaque time-stamp returned by currentTime() into an
* elapsed time in milliseconds, based on the current instant in time.
*
* @param startTime an opaque time-stamp returned by an instance of this class
* @return the elapsed time between startTime and now in milliseconds
*/
static long elapsedMillis(long startTime) {
return CLOCK.elapsedMillis0(startTime);
}
long elapsedMillis0(long startTime);
Get the difference in milliseconds between two opaque time-stamps returned
by currentTime().
Params: - startTime – an opaque time-stamp returned by an instance of this class
- endTime – an opaque time-stamp returned by an instance of this class
Returns: the elapsed time between startTime and endTime in milliseconds
/**
* Get the difference in milliseconds between two opaque time-stamps returned
* by currentTime().
*
* @param startTime an opaque time-stamp returned by an instance of this class
* @param endTime an opaque time-stamp returned by an instance of this class
* @return the elapsed time between startTime and endTime in milliseconds
*/
static long elapsedMillis(long startTime, long endTime) {
return CLOCK.elapsedMillis0(startTime, endTime);
}
long elapsedMillis0(long startTime, long endTime);
Convert an opaque time-stamp returned by currentTime() into an
elapsed time in milliseconds, based on the current instant in time.
Params: - startTime – an opaque time-stamp returned by an instance of this class
Returns: the elapsed time between startTime and now in milliseconds
/**
* Convert an opaque time-stamp returned by currentTime() into an
* elapsed time in milliseconds, based on the current instant in time.
*
* @param startTime an opaque time-stamp returned by an instance of this class
* @return the elapsed time between startTime and now in milliseconds
*/
static long elapsedNanos(long startTime) {
return CLOCK.elapsedNanos0(startTime);
}
long elapsedNanos0(long startTime);
Get the difference in nanoseconds between two opaque time-stamps returned
by currentTime().
Params: - startTime – an opaque time-stamp returned by an instance of this class
- endTime – an opaque time-stamp returned by an instance of this class
Returns: the elapsed time between startTime and endTime in nanoseconds
/**
* Get the difference in nanoseconds between two opaque time-stamps returned
* by currentTime().
*
* @param startTime an opaque time-stamp returned by an instance of this class
* @param endTime an opaque time-stamp returned by an instance of this class
* @return the elapsed time between startTime and endTime in nanoseconds
*/
static long elapsedNanos(long startTime, long endTime) {
return CLOCK.elapsedNanos0(startTime, endTime);
}
long elapsedNanos0(long startTime, long endTime);
Return the specified opaque time-stamp plus the specified number of milliseconds.
Params: - time – an opaque time-stamp
- millis – milliseconds to add
Returns: a new opaque time-stamp
/**
* Return the specified opaque time-stamp plus the specified number of milliseconds.
*
* @param time an opaque time-stamp
* @param millis milliseconds to add
* @return a new opaque time-stamp
*/
static long plusMillis(long time, long millis) {
return CLOCK.plusMillis0(time, millis);
}
long plusMillis0(long time, long millis);
Get the TimeUnit the ClockSource is denominated in.
Returns:
/**
* Get the TimeUnit the ClockSource is denominated in.
* @return
*/
static TimeUnit getSourceTimeUnit() {
return CLOCK.getSourceTimeUnit0();
}
TimeUnit getSourceTimeUnit0();
Get a String representation of the elapsed time in appropriate magnitude terminology.
Params: - startTime – an opaque time-stamp
- endTime – an opaque time-stamp
Returns: a string representation of the elapsed time interval
/**
* Get a String representation of the elapsed time in appropriate magnitude terminology.
*
* @param startTime an opaque time-stamp
* @param endTime an opaque time-stamp
* @return a string representation of the elapsed time interval
*/
static String elapsedDisplayString(long startTime, long endTime) {
return CLOCK.elapsedDisplayString0(startTime, endTime);
}
default String elapsedDisplayString0(long startTime, long endTime) {
long elapsedNanos = elapsedNanos0(startTime, endTime);
StringBuilder sb = new StringBuilder(elapsedNanos < 0 ? "-" : "");
elapsedNanos = Math.abs(elapsedNanos);
for (TimeUnit unit : TIMEUNITS_DESCENDING) {
long converted = unit.convert(elapsedNanos, NANOSECONDS);
if (converted > 0) {
sb.append(converted).append(TIMEUNIT_DISPLAY_VALUES[unit.ordinal()]);
elapsedNanos -= NANOSECONDS.convert(converted, unit);
}
}
return sb.toString();
}
TimeUnit[] TIMEUNITS_DESCENDING = {DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS};
String[] TIMEUNIT_DISPLAY_VALUES = {"ns", "µs", "ms", "s", "m", "h", "d"};
Factory class used to create a platform-specific ClockSource.
/**
* Factory class used to create a platform-specific ClockSource.
*/
class Factory
{
private static ClockSource create() {
String os = System.getProperty("os.name");
if ("Mac OS X".equals(os)) {
return new MillisecondClockSource();
}
return new NanosecondClockSource();
}
}
final class MillisecondClockSource implements ClockSource
{
{@inheritDoc} /** {@inheritDoc} */
@Override
public long currentTime0() {
return System.currentTimeMillis();
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedMillis0(final long startTime) {
return System.currentTimeMillis() - startTime;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedMillis0(final long startTime, final long endTime) {
return endTime - startTime;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedNanos0(final long startTime) {
return MILLISECONDS.toNanos(System.currentTimeMillis() - startTime);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedNanos0(final long startTime, final long endTime) {
return MILLISECONDS.toNanos(endTime - startTime);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long toMillis0(final long time) {
return time;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long toNanos0(final long time) {
return MILLISECONDS.toNanos(time);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long plusMillis0(final long time, final long millis) {
return time + millis;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public TimeUnit getSourceTimeUnit0() {
return MILLISECONDS;
}
}
class NanosecondClockSource implements ClockSource
{
{@inheritDoc} /** {@inheritDoc} */
@Override
public long currentTime0() {
return System.nanoTime();
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long toMillis0(final long time) {
return NANOSECONDS.toMillis(time);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long toNanos0(final long time) {
return time;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedMillis0(final long startTime) {
return NANOSECONDS.toMillis(System.nanoTime() - startTime);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedMillis0(final long startTime, final long endTime) {
return NANOSECONDS.toMillis(endTime - startTime);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedNanos0(final long startTime) {
return System.nanoTime() - startTime;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long elapsedNanos0(final long startTime, final long endTime) {
return endTime - startTime;
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public long plusMillis0(final long time, final long millis) {
return time + MILLISECONDS.toNanos(millis);
}
{@inheritDoc} /** {@inheritDoc} */
@Override
public TimeUnit getSourceTimeUnit0() {
return NANOSECONDS;
}
}
}