Package net.bpiwowar.mg4j.extensions.utils.timer

Source Code of net.bpiwowar.mg4j.extensions.utils.timer.TaskTimer$Task

package net.bpiwowar.mg4j.extensions.utils.timer;

import net.bpiwowar.mg4j.extensions.utils.LoggerPrintStream;
import net.bpiwowar.mg4j.extensions.utils.Memory;
import net.bpiwowar.mg4j.extensions.utils.Time;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import java.io.PrintStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.Vector;

/**
* A timer that reports upon the different tasks & subtasks
*
* @author Benjamin Piwowarski <benjamin@bpiwowar.net>
*/
final public class TaskTimer extends Timer {

  public class Task {

    /**
     * Starting timestamp
     */
    long start;

    /**
     * How much have we done?
     */
    int count;

    /**
     * How much units of works should we do? A value of 0 means unknown
     */
    int total;

    private String what;

    private final String name;

    private boolean removed = false;

    public Task(String name, String what, int total) {
      super();
      reset(what, total);
      this.name = name;
      this.start = System.currentTimeMillis();
      addTask(this);
    }

    public Task(String name, String what) {
      this(name, what, 0);
    }

    @Override
    protected void finalize() throws Throwable {
      super.finalize();
      if (!removed)
        remove(this);
      removed = true;
    }

    /**
     * Print the current status of the task
     *
     * @param timestamp
     *            The current timestamp
     * @param out
     *            The stream where things are printed
     */
    synchronized public void print(long timestamp, PrintStream out) {
      long elapsed = timestamp - start;
      float itemPerMinute = (float) (count * 1000f * 60f)
          / (float) (elapsed);
      if (total > 0) {
        if (count > 0) {
          int etaSeconds = (int) ((float) (total - count)
              * ((float) elapsed * 1e-3) / (float) count);
          out
              .format(
                  "(%s, RT/ETA: %s/%s) %d %s (on %d) processed at %.1f/min (%.2f%%)",
                  name,
                  Time.formatTimeInSeconds((int) (elapsed / 1000)),
                  Time.formatTimeInSeconds(etaSeconds), count,
                  what, total, itemPerMinute, count * 100.
                      / total);
        } else {
          out
              .format(
                  "(%s, RT/ETA: %s/?) %d %s (on %d) processed at %.1f/min (%.2f%%)",
                  name,
                  Time.formatTimeInSeconds((int) (elapsed / 1000)),
                  count, what, total, itemPerMinute, count
                      * 100. / total);
        }

      } else {
        out.format("(%s, RT: %s) %d %s processed at %.1f/min", name,
            Time.formatTimeInSeconds((int) (elapsed / 1000)), count,
            what, itemPerMinute);
      }
    }

    /**
     * Resets the task
     *
     * @param what
     *            Give a new description
     * @param total
     *            Give a new total
     */
    synchronized public void reset(String what, int total) {
      this.what = what;
      this.total = total;
      this.start = System.currentTimeMillis();
      this.count = 0;
    }

    synchronized public void regress(int d) {
      count -= d;
    }

    /**
     * Progress of 1 unit
     */
    synchronized public void progress() {
      count++;
    }

    /**
     * Notify a progress of an arbitrary number of units
     *
     * @param d
     */
    synchronized public void progress(int d) {
      count += d;
    }

    /**
     * End this task
     */
    public void end() {
      remove(this);
    }

  }

  /**
   * The set of tasks
   */
  private Vector<Task> tasks = new Vector<Task>();

  /**
   * Default constructor
   *
   * @param logger
   *            The logger that should be used to report
   * @param interval
   *            The interval between two reports
   */
  public TaskTimer(Logger logger, long interval) {
    super(logger, interval);
  }

  public TaskTimer(Logger logger) {
    super(logger);
  }

  /**
   * Remove a task from this timer (this method is private since it is called
   * by the task)
   *
   * @param task
   *            The task to remove
   */
  private void remove(Task task) {
    synchronized (tasks) {
      task.removed = true;
      tasks.remove(task);
    }
  }

  /**
   * Add a new task to this timer
   *
   * @param task
   *            The task to add
   */
  protected void addTask(Task task) {
    synchronized (tasks) {
      tasks.add(task);
    }
  }

  public void flush() {
    report();
  }

  private SimpleDateFormat formatter = (SimpleDateFormat) DateFormat
      .getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale
          .getDefault());
  {
    TimeZone tz = TimeZone.getDefault();
    formatter.setTimeZone(tz);
    formatter.applyPattern("dd/MM/yyyy HH:mm:ss z");
  }

  @Override
  protected void report() {
    long ts = System.currentTimeMillis();
    logger.info(String.format("%s -- %d%% memory available (total %d Mb)", formatter
        .format(Calendar.getInstance().getTime()), Memory.percAvailableMemory(),
        Memory.maxMemory() / (1024 * 1024)));
    int i = 0;
    LoggerPrintStream out = new LoggerPrintStream(logger, Level.INFO);
    synchronized (tasks) {
      for (Task task : tasks) {
        i++;
        final int size = tasks.size();
        out.format("\t[%d/%d] ", i, size);
        task.print(ts, out);
        out.flush();
      }
    }
  }

}
TOP

Related Classes of net.bpiwowar.mg4j.extensions.utils.timer.TaskTimer$Task

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.