graphene.util.stats.TimeReporter.java Source code

Java tutorial

Introduction

Here is the source code for graphene.util.stats.TimeReporter.java

Source

/*
 *
 *  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 graphene.util.stats;

import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import org.slf4j.Logger;

public class TimeReporter {

    PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder().appendDays().appendSuffix(" day", " days")
            .appendSeparator(", ").appendHours().appendSuffix(" hour", " hours")

            .appendSeparator(", ").appendMinutes().appendSuffix(" minute", " minutes").appendSeparator(" and ")
            .appendSeconds().appendSuffix(" second", " seconds").toFormatter();
    long lastIntervalTime = 0;
    private Logger log;
    // Set when the reporter was created.
    private long startTime;

    // A string describing what we are doing. i.e. "Making Pizza"
    private String task = null;

    public TimeReporter() {
        init();
    }

    public TimeReporter(Logger logger) {
        log = logger;
        init();
    }

    public TimeReporter(String task, Logger logger) {
        this.task = task;
        log = logger;
        init();
    }

    public long getElapsed() {
        return System.currentTimeMillis() - startTime;
    }

    /**
     * This method allows you to use the TimeReporter as an interval calculator.
     * For example, each time you call getInterval, it will return the amount of
     * time since you last called it.
     * 
     * @return the amount of time since getInterval has been called.
     */
    public String getInterval() {
        StringBuilder b = new StringBuilder();
        long t2 = System.currentTimeMillis();
        long tdiff = t2 - lastIntervalTime;
        if (tdiff < 1000) {
            b.append("" + tdiff + "ms");
        } else {
            tdiff /= 1000; // now seconds
            if (tdiff > 3600) {
                b.append("" + tdiff / 3600 + " hours, ");
                tdiff = tdiff % 3600;
            }
            if (tdiff > 60) {
                b.append("" + tdiff / 60 + " minutes, ");
                tdiff = tdiff % 60;
            }

            b.append("" + tdiff + " seconds");
        }
        lastIntervalTime = t2;
        return b.toString();
    }

    /**
     * 
     * @param reportInterval
     *            the number of ms to divide the time difference by.
     * @return a String like "10ms per MyTask"
     */
    public String getInterval(long reportInterval) {
        StringBuilder b = new StringBuilder();
        long t2 = System.currentTimeMillis();

        long tdiff = t2 - lastIntervalTime;
        tdiff /= reportInterval;
        if (tdiff < 1000) {
            b.append("" + tdiff + "ms per " + task);
        } else {
            tdiff /= 1000; // now seconds
            if (tdiff > 3600) {
                b.append("" + tdiff / 3600 + " hours, ");
                tdiff = tdiff % 3600;
            }
            if (tdiff > 60) {
                b.append("" + tdiff / 60 + " minutes, ");
                tdiff = tdiff % 60;
            }

            b.append("" + tdiff + " seconds per " + task);
        }
        lastIntervalTime = t2;
        return b.toString();
    }

    /**
     * 
     * @param numberOfItems
     *            the number of things you've done so far. Does not update any
     *            intervals
     * @param unit
     *            a String like "records" or "widgets"
     * @return a String like " 34 records/ms"
     */
    public String getSpeed(long numberOfItems, String unit) {
        return (numberOfItems / getElapsed()) + " " + unit + "/ms";
    }

    public String getTask() {
        return task;
    }

    private void init() {
        startTime = System.currentTimeMillis();
        lastIntervalTime = startTime;
        logAsStarting();
    }

    private void logAsStarting() {
        if (log != null) {
            if (task != null) {
                log.info(String.format("Task:" + task + " starting."));
            } else {
                log.info("Starting task.");
            }
        }

    }

    /**
     * logs a message like "Task: MyTask finished in : 10ms"
     */
    public void logAsCompleted() {
        String message = "Finished in ";
        if (log != null) {
            if (task != null) {
                log.info(String.format("Task:" + task + " " + message + ": " + report()));
            } else {
                log.info(String.format(message + ": " + report()));
            }
        }
    }

    public void logAverageTime(long ntests) {
        long t2 = System.currentTimeMillis();
        long tdiff = t2 - lastIntervalTime;
        if (log != null) {
            if (task != null) {
                log.info(String.format("Task:" + task + " average time for %d : %d ms", ntests, tdiff));
            } else {
                log.info(String.format("average time for %d : %d ms", ntests, tdiff));
            }
        }
    }

    /**
     * logs a message like "Task: MyTask Request time : 10ms"
     */
    public void logElapsed() {
        logElapsed("Request time");
    }

    public void logElapsed(int percentComplete) {
        logElapsed(Integer.toString(percentComplete) + " percent complete in");
    }

    /**
     * logs a message like "Task: MyTask message : 10ms"
     * 
     * @param message
     */
    public void logElapsed(String message) {
        if (log != null) {
            if (task != null) {
                log.info(String.format("Task:" + task + " " + message + ": %d ms", getElapsed()));
            } else {
                log.info(String.format(message + ": %d ms", getElapsed()));
            }
        }
    }

    public void logEstimation(long estimatedTotal, long numberProcessed) {
        if (estimatedTotal <= numberProcessed) {
            log.info("Should be Completed");
        } else if (numberProcessed == 0) {
            log.info("inf");
        } else {
            double rate = getElapsed() / numberProcessed;
            double guess = ((estimatedTotal - numberProcessed) * rate) / 1000;
            int d = guess > 86400 ? (int) guess / 86400 : 0;
            guess %= 86400;
            int h = guess > 3600 ? (int) guess / 3600 : 0;
            guess %= 3600;
            int m = guess > 60 ? (int) guess / 60 : 0;
            guess %= 60;
            int s = (int) (guess > 0 ? guess : 0);
            Period period = new Period(d, h, m, s);

            log.info("Time remaining: " + daysHoursMinutes.print(period.normalizedStandard()));
        }
    }

    /**
     * 
     * @return A string like "1 hours, 23 minutes and 10 seconds"
     */
    public String report() {
        StringBuilder b = new StringBuilder();
        long tdiff = getElapsed();
        tdiff /= 1000; // now seconds
        if (tdiff > 3600) {
            b.append("" + tdiff / 3600 + " hours, ");
            tdiff = tdiff % 3600;
        }
        if (tdiff > 60) {
            b.append("" + tdiff / 60 + " minutes, ");
            tdiff = tdiff % 60;
        }

        b.append("" + tdiff + " seconds");

        return b.toString();
    }

    /**
     * Useful for resetting the time for loops, or between longer serial
     * processes
     */
    public void reset() {
        startTime = System.currentTimeMillis();
        lastIntervalTime = startTime;
    }

    public void setTask(String task) {
        this.task = task;
    }
}