All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.zaxxer.hikari.util.ClockSource Maven / Gradle / Ivy

There is a newer version: 2.4.13
Show newest version
/*
 * 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
 */
public interface ClockSource
{
   ClockSource INSTANCE = Factory.create();

   /**
    * Get the current time-stamp (resolution is opaque).
    *
    * @return the current time-stamp
    */
   long currentTime();

   /**
    * 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
    */
   long toMillis(long time);

   /**
    * 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
    */
   long toNanos(long time);

   /**
    * 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
    */
   long elapsedMillis(long startTime);

   /**
    * 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
    */
   long elapsedMillis(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.
    *
    * @param startTime an opaque time-stamp returned by an instance of this class
    * @return the elapsed time between startTime and now in milliseconds
    */
   long elapsedNanos(long startTime);

   /**
    * 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
    */
   long elapsedNanos(long startTime, long endTime);

   /**
    * 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
    */
   long plusMillis(long time, long millis);

   /**
    * Get the TimeUnit the ClockSource is denominated in.
    * @return
    */
   TimeUnit getSourceTimeUnit();

   /**
    * 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
    */
   String elapsedDisplayString(long startTime, long endTime);

   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.
    */
   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 extends NanosecondClockSource
   {
      /** {@inheritDoc} */
      @Override
      public long currentTime()
      {
         return System.currentTimeMillis();
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedMillis(final long startTime)
      {
         return System.currentTimeMillis() - startTime;
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedMillis(final long startTime, final long endTime)
      {
         return endTime - startTime;
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedNanos(final long startTime)
      {
         return MILLISECONDS.toNanos(System.currentTimeMillis() - startTime);
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedNanos(final long startTime, final long endTime)
      {
         return MILLISECONDS.toNanos(endTime - startTime);
      }

      /** {@inheritDoc} */
      @Override
      public long toMillis(final long time)
      {
         return time;
      }

      /** {@inheritDoc} */
      @Override
      public long toNanos(final long time)
      {
         return MILLISECONDS.toNanos(time);
      }

      /** {@inheritDoc} */
      @Override
      public long plusMillis(final long time, final long millis)
      {
         return time + millis;
      }

      /** {@inheritDoc} */
      @Override
      public TimeUnit getSourceTimeUnit()
      {
         return MILLISECONDS;
      }
   }

   class NanosecondClockSource implements ClockSource
   {
      /** {@inheritDoc} */
      @Override
      public long currentTime()
      {
         return System.nanoTime();
      }

      /** {@inheritDoc} */
      @Override
      public long toMillis(final long time)
      {
         return NANOSECONDS.toMillis(time);
      }

      /** {@inheritDoc} */
      @Override
      public long toNanos(final long time)
      {
         return time;
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedMillis(final long startTime)
      {
         return NANOSECONDS.toMillis(System.nanoTime() - startTime);
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedMillis(final long startTime, final long endTime)
      {
         return NANOSECONDS.toMillis(endTime - startTime);
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedNanos(final long startTime)
      {
         return System.nanoTime() - startTime;
      }

      /** {@inheritDoc} */
      @Override
      public long elapsedNanos(final long startTime, final long endTime)
      {
         return endTime - startTime;
      }

      /** {@inheritDoc} */
      @Override
      public long plusMillis(final long time, final long millis)
      {
         return time + MILLISECONDS.toNanos(millis);
      }

      /** {@inheritDoc} */
      @Override
      public TimeUnit getSourceTimeUnit()
      {
         return NANOSECONDS;
      }

      /** {@inheritDoc} */
      @Override
      public String elapsedDisplayString(long startTime, long endTime)
      {
         long elapsedNanos = elapsedNanos(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();
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy