
org.xipki.common.ProcessLog Maven / Gradle / Ivy
The newest version!
/*
*
* Copyright (c) 2013 - 2017 Lijun Liao
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xipki.common;
import java.util.Calendar;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import org.xipki.common.qa.MeasurePoint;
import org.xipki.common.util.StringUtil;
/**
* @author Lijun Liao
* @since 2.0.0
*/
public class ProcessLog {
private static final long MS_900 = 900L;
private static final long DAY_IN_SEC = 24L * 60 * 60;
private static final int MIN_LEN = 12;
private final long total;
private final boolean hasTotal;
private long startTimeMs;
private long endTimeMs;
private AtomicLong numProcessed;
private AtomicLong lastPrintTimeMs;
private final AtomicBoolean finished = new AtomicBoolean(false);
private long totalElapsedTimeMs;
private int totalAverageSpeed;
private final ConcurrentLinkedDeque measureDeque = new ConcurrentLinkedDeque<>();
public ProcessLog(final long total) {
this.total = total;
this.hasTotal = total > 0;
reset();
}
public void printHeader() {
StringBuilder sb = new StringBuilder();
// first header line
final int n = hasTotal ? 7 : 4;
for (int i = 0; i < n * MIN_LEN; i++) {
sb.append('-');
}
sb.append('\n');
// second header line
sb.append(formatText("total"));
if (hasTotal) {
sb.append(formatText("%"));
}
sb.append(formatText("average"));
sb.append(formatText("current"));
sb.append(formatText("time"));
if (hasTotal) {
sb.append(formatText("time"));
sb.append(formatText("finish"));
}
sb.append('\n');
// third header line
sb.append(formatText(""));
if (hasTotal) {
sb.append(formatText(""));
}
sb.append(formatText("speed"));
sb.append(formatText("speed"));
sb.append(formatText("spent"));
if (hasTotal) {
sb.append(formatText("left"));
sb.append(formatText("at"));
}
sb.append('\n');
System.out.println(sb.toString());
System.out.flush();
} // method printHeader
public void finish() {
finished.set(true);
endTimeMs = System.currentTimeMillis();
totalElapsedTimeMs = endTimeMs - startTimeMs;
totalAverageSpeed = 0;
if (totalElapsedTimeMs > 0) {
totalAverageSpeed = (int) (numProcessed.get() * 1000 / totalElapsedTimeMs);
}
}
public void printTrailer() {
finish();
printStatus(true);
StringBuilder sb = new StringBuilder();
sb.append('\n');
final int n = hasTotal ? 7 : 4;
for (int i = 0; i < n * MIN_LEN; i++) {
sb.append('-');
}
System.out.println(sb.toString());
System.out.flush();
}
public long numProcessed() {
return numProcessed.get();
}
public long total() {
return total;
}
public void reset() {
startTimeMs = System.currentTimeMillis();
numProcessed = new AtomicLong(0);
lastPrintTimeMs = new AtomicLong(0);
measureDeque.clear();
measureDeque.add(new MeasurePoint(startTimeMs, 0));
}
public long startTimeMs() {
return startTimeMs;
}
public long endTimeMs() {
return endTimeMs;
}
public long addNumProcessed(final long numProcessed) {
return this.numProcessed.addAndGet(numProcessed);
}
public void printStatus() {
printStatus(false);
}
private void printStatus(final boolean forcePrint) {
final long nowMs = System.currentTimeMillis();
final long tmpNumProcessed = numProcessed.get();
if (!forcePrint && nowMs - lastPrintTimeMs.get() < MS_900) {
return;
}
measureDeque.addLast(new MeasurePoint(nowMs, numProcessed.get()));
lastPrintTimeMs.set(nowMs);
int numMeasurePoints = measureDeque.size();
// CHECKSTYLE:SKIP
MeasurePoint referenceMeasurePoint = (numMeasurePoints > 10) ? measureDeque.removeFirst()
: measureDeque.getFirst();
StringBuilder sb = new StringBuilder("\r");
// processed number
sb.append(StringUtil.formatAccount(tmpNumProcessed, true));
// processed percent
if (hasTotal) {
int percent = (int) (tmpNumProcessed * 100 / total);
String percentS = Integer.toString(percent);
sb.append(formatText(percentS));
}
// average speed
long averageSpeed = 0;
long elapsedTimeMs = nowMs - startTimeMs;
if (elapsedTimeMs > 0) {
averageSpeed = tmpNumProcessed * 1000 / elapsedTimeMs;
}
sb.append(StringUtil.formatAccount(averageSpeed, true));
// current speed
long currentSpeed = 0;
long t2inms = nowMs - referenceMeasurePoint.measureTime(); // in ms
if (t2inms > 0) {
currentSpeed =
(tmpNumProcessed - referenceMeasurePoint.measureAccount()) * 1000 / t2inms;
}
sb.append(StringUtil.formatAccount(currentSpeed, true));
// elapsed time
sb.append(StringUtil.formatTime(elapsedTimeMs / 1000, true));
// remaining time and finish at
if (hasTotal) {
long remaingTimeMs = -1;
if (currentSpeed > 0) {
remaingTimeMs = (total - tmpNumProcessed) * 1000 / currentSpeed;
}
long finishAtMs = -1;
if (remaingTimeMs != -1) {
finishAtMs = nowMs + remaingTimeMs;
}
if (remaingTimeMs == -1) {
sb.append(formatText("--"));
} else {
sb.append(StringUtil.formatTime(remaingTimeMs / 1000, true));
}
if (finishAtMs == -1) {
sb.append(formatText("--"));
} else {
sb.append(buildDateTime(finishAtMs));
}
}
System.out.print(sb.toString());
System.out.flush();
} // method printStatus
public long totalElapsedTime() {
if (finished.get()) {
return totalElapsedTimeMs;
}
return System.currentTimeMillis() - startTimeMs;
}
public int totalAverageSpeed() {
if (finished.get()) {
return totalAverageSpeed;
}
long elapsedTimeMs = System.currentTimeMillis() - startTimeMs;
int averageSpeed = 0;
if (elapsedTimeMs > 0) {
averageSpeed = (int) (numProcessed.get() * 1000 / elapsedTimeMs);
}
return averageSpeed;
}
private static String formatText(String text) {
return StringUtil.formatText(text, MIN_LEN);
}
private static String buildDateTime(long timeMs) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timeMs);
StringBuilder sb = new StringBuilder();
int hour = cal.get(Calendar.HOUR_OF_DAY);
if (hour < 10) {
sb.append('0');
}
sb.append(hour);
int minute = cal.get(Calendar.MINUTE);
sb.append(":");
if (minute < 10) {
sb.append('0');
}
sb.append(minute);
int second = cal.get(Calendar.SECOND);
sb.append(":");
if (second < 10) {
sb.append('0');
}
sb.append(second);
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
long midNightSec = cal.getTimeInMillis() / 1000;
long days = (timeMs / 1000 - midNightSec) / DAY_IN_SEC;
if (days > 0) {
sb.append('+').append(days);
}
int size = sb.length();
for (int i = 0; i < (MIN_LEN - size); i++) {
sb.insert(0, ' ');
}
return sb.toString();
} // method buildDateTime
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy