001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.util;
020
021import java.io.Closeable;
022import java.util.concurrent.TimeUnit;
023
024/**
025 * A simplified StopWatch implementation which can measure times in nanoseconds.
026 */
027public class StopWatch implements Closeable {
028  private boolean isStarted;
029  private long startNanos;
030  private long currentElapsedNanos;
031
032  public StopWatch() {
033  }
034
035  /**
036   * The method is used to find out if the StopWatch is started.
037   * @return boolean If the StopWatch is started.
038   */
039  public boolean isRunning() {
040    return isStarted;
041  }
042
043  /**
044   * Start to measure times and make the state of stopwatch running.
045   * @return this instance of StopWatch.
046   */
047  public StopWatch start() {
048    if (isStarted) {
049      throw new IllegalStateException("StopWatch is already running");
050    }
051    isStarted = true;
052    startNanos = System.nanoTime();
053    return this;
054  }
055
056  /**
057   * Stop elapsed time and make the state of stopwatch stop.
058   * @return this instance of StopWatch.
059   */
060  public StopWatch stop() {
061    if (!isStarted) {
062      throw new IllegalStateException("StopWatch is already stopped");
063    }
064    long now = System.nanoTime();
065    isStarted = false;
066    currentElapsedNanos += now - startNanos;
067    return this;
068  }
069
070  /**
071   * Reset elapsed time to zero and make the state of stopwatch stop.
072   * @return this instance of StopWatch.
073   */
074  public StopWatch reset() {
075    currentElapsedNanos = 0;
076    isStarted = false;
077    return this;
078  }
079
080  /**
081   * @return current elapsed time in specified timeunit.
082   */
083  public long now(TimeUnit timeUnit) {
084    return timeUnit.convert(now(), TimeUnit.NANOSECONDS);
085
086  }
087
088  /**
089   * @return current elapsed time in nanosecond.
090   */
091  public long now() {
092    return isStarted ?
093        System.nanoTime() - startNanos + currentElapsedNanos :
094        currentElapsedNanos;
095  }
096
097  @Override
098  public String toString() {
099    return String.valueOf(now());
100  }
101
102  @Override
103  public void close() {
104    if (isStarted) {
105      stop();
106    }
107  }
108}