package org.openlca.app.util; import java.util.Calendar; import java.util.LinkedList; import java.util.Queue; import org.eclipse.core.runtime.IProgressMonitor; public class TimeEstimatingMonitor { private final IProgressMonitor monitor; private final boolean showSeconds; private final Queue<Long> lastTimes = new LinkedList<>(); private long time; private int worked; private int total; private long lastTimeSet; private int considerationValue; private boolean showedTime; public TimeEstimatingMonitor(IProgressMonitor monitor) { this(monitor, false); } public TimeEstimatingMonitor(IProgressMonitor monitor, boolean showSeconds) { this.monitor = monitor; this.showSeconds = showSeconds; } public void beginTask(String task, int total) { this.total = total > 0 ? total : 0; worked = 0; time = Calendar.getInstance().getTimeInMillis(); lastTimeSet = time; lastTimes.clear(); considerationValue = total < 100 ? -1 : total / 25; showedTime = false; monitor.beginTask(task, total); } public void endTask() { monitor.subTask(""); } public void done() { monitor.done(); } public void worked() { worked++; monitor.worked(1); long remainingTime = getRemainingTime(); long current = Calendar.getInstance().getTimeInMillis(); long took = current - lastTimeSet; if (took < 1000) return; if (lastTimes.size() < considerationValue && took < 10000) return; if (!showedTime && (remainingTime < 150 || worked > (total / 10))) return; showedTime = true; String remaining = formatTime((long) remainingTime); if (remaining.isEmpty()) { monitor.subTask(""); } else { monitor.subTask("#Estimated time remaining: " + remaining); } lastTimeSet = current; } private long getRemainingTime() { long current = Calendar.getInstance().getTimeInMillis(); long took = current - time; time = current; if (lastTimes.size() == considerationValue) lastTimes.poll(); lastTimes.add(took); int count = 0; long lastTook = 0; for (Long t : lastTimes) { lastTook += t; count++; } double per = lastTook / (double) count; int remaining = total - worked; return (long) Math.ceil((per * remaining) / 1000d); } private String formatTime(long t) { if (t < 0) return ""; String s = ""; long h = t / 3600; if (h > 0) { t = t % 3600; s = h + "h "; } if (h > 2) return s; long m = t / 60; if (m > 0) { t = t % 60; if (!showSeconds && t > 30) { m++; } s += m + "m "; } if (!showSeconds || h > 0 || m > 9) { if (s.isEmpty()) return "< 1m"; return s; } if (t > 0) s += t + "s"; return s; } }