Whenver I download a file, and the other end is very irradic in its connection speed, the estimated time jumps everywhere from 2 minutes to 2 hours, and it changes a couple of times per second. I find it somewhat difficult to know when I need to look at my computer again if I want to leave it running for a while.
I would suggest making download time estimations stable in the face of connection speed variations by displaying a rolling average of the last few file ETAs which continues to change as new ETAs are computed.
I have read some of the code, and as I understand it, my suggestion could be implemented by changing the DownloadDataLine class in the com.limegroup.gnutella.gui.download package as follows:
Code:
/* Beginning on line 786 */
// If we have a valid rate (can't compute if rate is 0),
// then determine how much time (in seconds) is remaining.
if ( _speed > 0) {
double kbLeft = ((_size/1024.0) -
(_amountRead/1024.0));
_timeLeft = newTimeRemaining((int)(kbLeft / _speed));
}
And then, add a new private method to do the rolling average, along with some member data:
Code:
// This member data is for the rolling average.
private final int N = 10; // the number of times to save, adjust at leasure
private boolean full = false; // to only use the average when we have N #s
private int index = 0; // the index for the element to replace in times[]
private int times[] = new int[N]; // the list of times
/**
* This method calculates the new time remaining based on a rolling average.
* @author bsdman
*/
private int newTimeRemaining(int anotherTime)
{
times[index++] = anotherTime;
if(index == N)
{
index = 0;
full = true;
}
if(!full)
return anotherTime; // since we can't average yet
// otherwise, take the average
// TODO this average could probably be written more efficeiently
long total = 0;
for(int i = 0; i < N; i++)
total += times[i];
return (int)(total/N);
}
I hope my code will be useful for getting it done -- if it works correctly. I haven't had an opportunity to test it yet, but since it compiles and I have faith in my programming skills with regard to such a simple problem, I think it will work.
Any comments are welcome.