// Copyright (c) 2003 Dustin Sallings <dustin@spy.net>
package net.spy.util;
import java.text.MessageFormat;
import java.util.Date;
/**
* A simple class for keeping up with the progress of an operation.
*/
public class ProgressStats extends Object {
private static final String DEFAULT_FORMAT=
"{5} remaining. Avg={0,number,#.##}s, Estimate={1,number,#.##}s "
+ "({2,date,EEE MMMdd HH:mm:ss})";
private int done=0;
private int todo=0;
private long totalTime=0;
private long lastTime=0;
private long lastProcessTime=0;
private double avg=0.0;
/**
* Get an instance of ProgressStats to process the given number of
* things.
*/
public ProgressStats(int size) {
super();
this.todo=size;
}
/**
* Get the current time for this ProgressStats instance. This exists as a
* test fixture, but if you want to do something more exciting with it,
* go right ahead.
*/
protected long getTime() {
return System.currentTimeMillis();
}
/**
* Mark us having started processing something.
*/
public void start() {
lastTime=getTime();
}
/**
* Mark this iteration as complete.
*/
public void stop() {
long thistime=getTime();
lastProcessTime=thistime-lastTime;
done++;
totalTime+=lastProcessTime;
double df=done;
double v=lastProcessTime / 1000.0;
avg = ((avg * df) + v) / (df + 1);
}
/**
* Get the running average of the number of seconds spent processing.
* @return ((avg * df) + v) / (df + 1)
*/
public double getRunningAverage() {
return(avg);
}
/**
* Get the overall average.
*/
public double getOverallAverage() {
double avgProcessTime=((double)totalTime/(double)done)/1000.0;
return(avgProcessTime);
}
/**
* Get the estimated number of seconds remaining with the given average
* time per unit.
*/
public double getEstimatedTimeRemaining(double avgProcessTime) {
double estimate=avgProcessTime*(todo-done);
return(estimate);
}
/**
* Get the estimated number of seconds remaining with the current
* average.
*/
public double getEstimatedTimeRemaining() {
return(getEstimatedTimeRemaining(getRunningAverage()));
}
/**
* Get the number of milliseconds spent processing the last item.
*/
public long getLastProcessTime() {
return(lastProcessTime);
}
/**
* Get a string representation fo the processing statistics.
*
* <p>
*
* The following arguments are available to this format string.
*
* <ul>
* <li>0: Average processing time in seconds (double)</li>
* <li>1: Estimated seconds to completion (double)</li>
* <li>2: Estimated time of completion (Date)</li>
* <li>3: Number completed (int)</li>
* <li>4: Number total (int)</li>
* <li>5: Number remaining (int)</li>
* </ul>
*
*/
public String getStats(String format) {
double average=getRunningAverage();
// Estimated number of seconds left
double estimate=getEstimatedTimeRemaining(average);
// Estimated time of completion
Date ofCompletion=new Date(getTime() + (1000*(long)estimate));
// Assemble arguments
Object[] args={
new Double(average),
new Double(estimate),
ofCompletion,
new Integer(done),
new Integer(todo),
new Integer(todo-done)
};
String rv=MessageFormat.format(format, args);
return(rv);
}
/**
* Get a string representation of the processing statistics using the
* default format.
*/
public String getStats() {
return(getStats(DEFAULT_FORMAT));
}
/**
* String me.
*
* @return getStats()
*/
@Override
public String toString() {
return(getStats());
}
}