/* * 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.logging.log4j; import java.io.Serializable; import java.text.DecimalFormat; import org.apache.logging.log4j.util.StringBuilderFormattable; import org.apache.logging.log4j.util.Strings; /** * */ public class Timer implements Serializable, StringBuilderFormattable { private static final long serialVersionUID = 9175191792439630013L; private final String name; // The timer's name private String status; // The timer's status private long startTime; // The start time private long elapsedTime; // The elapsed time private final int iterations; private static long NANO_PER_SECOND = 1000000000L; private static long NANO_PER_MINUTE = NANO_PER_SECOND * 60; private static long NANO_PER_HOUR = NANO_PER_MINUTE * 60; /** * Constructor. * @param name the timer name. */ public Timer(final String name) { this(name, 0); } /** * Constructor. * * @param name the timer name. */ public Timer(final String name, final int iterations) { this.name = name; startTime = 0; status = "Stopped"; this.iterations = (iterations > 0) ? iterations : 0; } /** * Start the timer. */ public void start() { startTime = System.nanoTime(); elapsedTime = 0; status = "Start"; } /** * Stop the timer. */ public void stop() { elapsedTime += System.nanoTime() - startTime; startTime = 0; status = "Stop"; } /** * Pause the timer. */ public void pause() { elapsedTime += System.nanoTime() - startTime; startTime = 0; status = "Pause"; } /** * Resume the timer. */ public void resume() { startTime = System.nanoTime(); status = "Resume"; } /** * Accessor for the name. * @return the timer's name. */ public String getName() { return name; } /** * Access the elapsed time. * * @return the elapsed time. */ public long getElapsedTime() { return elapsedTime / 1000000; } /** * Access the elapsed time. * * @return the elapsed time. */ public long getElapsedNanoTime() { return elapsedTime; } /** * Returns the name of the last operation performed on this timer (Start, Stop, Pause or * Resume). * @return the string representing the last operation performed. */ public String getStatus() { return status; } /** * Returns the String representation of the timer based upon its current state */ @Override public String toString() { final StringBuilder result = new StringBuilder(); formatTo(result); return result.toString(); } @Override public void formatTo(StringBuilder buffer) { buffer.append("Timer ").append(name); switch (status) { case "Start": buffer.append(" started"); break; case "Pause": buffer.append(" paused"); break; case "Resume": buffer.append(" resumed"); break; case "Stop": long nanoseconds = elapsedTime; // Get elapsed hours long hours = nanoseconds / NANO_PER_HOUR; // Get remaining nanoseconds nanoseconds = nanoseconds % NANO_PER_HOUR; // Get minutes long minutes = nanoseconds / NANO_PER_MINUTE; // Get remaining nanoseconds nanoseconds = nanoseconds % NANO_PER_MINUTE; // Get seconds long seconds = nanoseconds / NANO_PER_SECOND; // Get remaining nanoseconds nanoseconds = nanoseconds % NANO_PER_SECOND; String elapsed = Strings.EMPTY; if (hours > 0) { elapsed += hours + " hours "; } if (minutes > 0 || hours > 0) { elapsed += minutes + " minutes "; } DecimalFormat numFormat; numFormat = new DecimalFormat("#0"); elapsed += numFormat.format(seconds) + '.'; numFormat = new DecimalFormat("000000000"); elapsed += numFormat.format(nanoseconds) + " seconds"; buffer.append(" stopped. Elapsed time: ").append(elapsed); if (iterations > 0) { nanoseconds = elapsedTime / iterations; // Get elapsed hours hours = nanoseconds / NANO_PER_HOUR; // Get remaining nanoseconds nanoseconds = nanoseconds % NANO_PER_HOUR; // Get minutes minutes = nanoseconds / NANO_PER_MINUTE; // Get remaining nanoseconds nanoseconds = nanoseconds % NANO_PER_MINUTE; // Get seconds seconds = nanoseconds / NANO_PER_SECOND; // Get remaining nanoseconds nanoseconds = nanoseconds % NANO_PER_SECOND; elapsed = Strings.EMPTY; if (hours > 0) { elapsed += hours + " hours "; } if (minutes > 0 || hours > 0) { elapsed += minutes + " minutes "; } numFormat = new DecimalFormat("#0"); elapsed += numFormat.format(seconds) + '.'; numFormat = new DecimalFormat("000000000"); elapsed += numFormat.format(nanoseconds) + " seconds"; buffer.append(" Average per iteration: ").append(elapsed); } break; default: buffer.append(' ').append(status); break; } } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof Timer)) { return false; } final Timer timer = (Timer) o; if (elapsedTime != timer.elapsedTime) { return false; } if (startTime != timer.startTime) { return false; } if (name != null ? !name.equals(timer.name) : timer.name != null) { return false; } if (status != null ? !status.equals(timer.status) : timer.status != null) { return false; } return true; } @Override public int hashCode() { int result; result = (name != null ? name.hashCode() : 0); result = 29 * result + (status != null ? status.hashCode() : 0); result = 29 * result + (int) (startTime ^ (startTime >>> 32)); result = 29 * result + (int) (elapsedTime ^ (elapsedTime >>> 32)); return result; } }