/* * Copyright (C) 2015 SoftIndex LLC. * * 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 io.datakernel.util; import java.util.concurrent.TimeUnit; import static io.datakernel.util.Preconditions.check; import static java.util.concurrent.TimeUnit.*; public final class Stopwatch { private boolean isRunning; private long start; private long nanos; private Stopwatch() {} public static Stopwatch createUnstarted() { return new Stopwatch(); } public static Stopwatch createStarted() {return new Stopwatch().start(); } public Stopwatch start() { check(!isRunning, "This stopwatch is already running."); isRunning = true; start = System.nanoTime(); return this; } public Stopwatch stop() { long tick = System.nanoTime(); check(isRunning, "This stopwatch is already stopped."); isRunning = false; nanos += tick - start; return this; } public Stopwatch reset() { isRunning = false; nanos = 0; return this; } private long time() { if (isRunning) { return System.nanoTime() - start + nanos; } else { return nanos; } } private long elapsedNanos() { return isRunning ? System.nanoTime() - start + nanos : nanos; } @Override public String toString() { long nanos = elapsedNanos(); TimeUnit unit = chooseUnit(nanos); double value = (double) nanos / NANOSECONDS.convert(1, unit); return String.format("%.4g %s", value, abbreviate(unit)); } public long elapsed(TimeUnit timeUnit) { return timeUnit.convert(time(), TimeUnit.NANOSECONDS); } private static TimeUnit chooseUnit(long nanos) { if (DAYS.convert(nanos, NANOSECONDS) > 0) { return DAYS; } if (HOURS.convert(nanos, NANOSECONDS) > 0) { return HOURS; } if (MINUTES.convert(nanos, NANOSECONDS) > 0) { return MINUTES; } if (SECONDS.convert(nanos, NANOSECONDS) > 0) { return SECONDS; } if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) { return MILLISECONDS; } if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) { return MICROSECONDS; } return NANOSECONDS; } private static String abbreviate(TimeUnit unit) { switch (unit) { case NANOSECONDS: return "ns"; case MICROSECONDS: return "\u03bcs"; // μs case MILLISECONDS: return "ms"; case SECONDS: return "s"; case MINUTES: return "min"; case HOURS: return "h"; case DAYS: return "d"; default: throw new AssertionError(); } } }