Skip to content

Commit

Permalink
Handling the case when an item takes less than 1ms to be processed
Browse files Browse the repository at this point in the history
  • Loading branch information
vdurmont committed Oct 17, 2015
1 parent 06bd74f commit 19039bd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
36 changes: 26 additions & 10 deletions src/main/java/com/vdurmont/etaprinter/ETAPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,29 @@ public void update(long numProcessedDuringStep) {
throw new ETAPrinterException("You cannot update a closed ETAPrinter!");
}
DateTime now = DateTime.now();
Long itemDurationMillis = null;
ItemsDuration itemsDuration = null;
if (numProcessedDuringStep > 0) {
itemDurationMillis = new Duration(this.lastStep, now).getMillis() / numProcessedDuringStep;
long stepDuration = new Duration(this.lastStep, now).getMillis();
int numItems = 1;
do {
long duration = stepDuration / (numProcessedDuringStep / numItems);
itemsDuration = new ItemsDuration(numItems, duration);
numItems++;
} while (itemsDuration.durationMillis == 0);
}
this.lastStep = now;
this.numProcessed += numProcessedDuringStep;
if (this.numProcessed == this.totalElementsToProcess) {
this.close();
} else {
this.print(itemDurationMillis);
this.print(itemsDuration);
}
}

private void print(Long itemDurationMillis) {
private void print(ItemsDuration itemsDuration) {
try {
// Get the status
String status = this.getStatus(itemDurationMillis);
String status = this.getStatus(itemsDuration);

// Carriage return and print the status
this.stream.write("\r".getBytes());
Expand All @@ -150,23 +156,33 @@ private void close() {
}
}

private String getStatus(Long itemDurationMillis) {
private String getStatus(ItemsDuration itemsDuration) {
long percentage = this.numProcessed * 100 / this.totalElementsToProcess;
if (itemDurationMillis == null) {
if (itemsDuration == null) {
return ETAStatusGenerator.getStatus(percentage);
} else {
long etaMillis = (this.totalElementsToProcess - this.numProcessed) * itemDurationMillis;
double speed;
long etaMillis = (this.totalElementsToProcess - this.numProcessed) * itemsDuration.durationMillis / itemsDuration.numItems;
double speed = 0;
int index = 0;
int speedFactor = 1;
do {
speedFactor *= SPEED_FACTORS[index];
speed = speedFactor / itemDurationMillis;
speed = speedFactor * itemsDuration.numItems / itemsDuration.durationMillis;
index++;
} while (speed == 0 && index < SPEED_UNITS.length);

Duration eta = new Duration(etaMillis);
return ETAStatusGenerator.getStatus(this.elementName, percentage, speed, SPEED_UNITS[index - 1], eta);
}
}

private static class ItemsDuration {
public final int numItems;
public final long durationMillis;

private ItemsDuration(int numItems, long durationMillis) {
this.numItems = numItems;
this.durationMillis = durationMillis;
}
}
}
25 changes: 25 additions & 0 deletions src/test/java/com/vdurmont/etaprinter/ETAPrinterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.vdurmont.etaprinter;

import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class ETAPrinterTest {
@Test
public void update_with_an_itemDuration_lower_than_1ms_doesnt_fail() {
// GIVEN
DateTime now = DateTime.now();
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
ETAPrinter eta = ETAPrinter.init(42);

// WHEN
DateTimeUtils.setCurrentMillisFixed(now.getMillis() + 1);
eta.update(2);

// THEN
// No failure
}
}

0 comments on commit 19039bd

Please sign in to comment.