mirror of https://github.com/apache/maven.git
[MNG-7899] Various memory usage improvements 4-1 (#1296)
* [MNG-7899] Various memory usage improvements - BatchModeMavenTransferListener removed - FileSizeFormat moved to top level class - FileSizeFormat.formatProcess() refactored to accept an StringBuilder as argument - FileSizeFormat refactored format() methods - FileSizeFormat refactored, replace DecimalFormat with Math logic to reduce memory allocation --------- Co-authored-by: Guillaume Nodet <gnodet@gmail.com>
This commit is contained in:
parent
4bd12915c9
commit
94749041b4
|
@ -19,8 +19,6 @@
|
||||||
package org.apache.maven.cli.transfer;
|
package org.apache.maven.cli.transfer;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.text.DecimalFormatSymbols;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.maven.cli.jansi.MessageUtils;
|
import org.apache.maven.cli.jansi.MessageUtils;
|
||||||
|
@ -38,153 +36,6 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferList
|
||||||
private static final String ANSI_DARK_SET = ESC + "[90m";
|
private static final String ANSI_DARK_SET = ESC + "[90m";
|
||||||
private static final String ANSI_DARK_RESET = ESC + "[0m";
|
private static final String ANSI_DARK_RESET = ESC + "[0m";
|
||||||
|
|
||||||
// CHECKSTYLE_OFF: LineLength
|
|
||||||
/**
|
|
||||||
* Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
|
|
||||||
* (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
|
|
||||||
* and <code>###0</code> for numbers between 10 and 1000+ by default.
|
|
||||||
*
|
|
||||||
* @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
|
|
||||||
* @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
|
|
||||||
* @see <a
|
|
||||||
* href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
|
|
||||||
*/
|
|
||||||
// CHECKSTYLE_ON: LineLength
|
|
||||||
// TODO Move me to Maven Shared Utils
|
|
||||||
static class FileSizeFormat {
|
|
||||||
enum ScaleUnit {
|
|
||||||
BYTE {
|
|
||||||
@Override
|
|
||||||
public long bytes() {
|
|
||||||
return 1L;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String symbol() {
|
|
||||||
return "B";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
KILOBYTE {
|
|
||||||
@Override
|
|
||||||
public long bytes() {
|
|
||||||
return 1000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String symbol() {
|
|
||||||
return "kB";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MEGABYTE {
|
|
||||||
@Override
|
|
||||||
public long bytes() {
|
|
||||||
return KILOBYTE.bytes() * KILOBYTE.bytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String symbol() {
|
|
||||||
return "MB";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
GIGABYTE {
|
|
||||||
@Override
|
|
||||||
public long bytes() {
|
|
||||||
return MEGABYTE.bytes() * KILOBYTE.bytes();
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String symbol() {
|
|
||||||
return "GB";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public abstract long bytes();
|
|
||||||
|
|
||||||
public abstract String symbol();
|
|
||||||
|
|
||||||
public static ScaleUnit getScaleUnit(long size) {
|
|
||||||
if (size < 0L) {
|
|
||||||
throw new IllegalArgumentException("file size cannot be negative: " + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size >= GIGABYTE.bytes()) {
|
|
||||||
return GIGABYTE;
|
|
||||||
} else if (size >= MEGABYTE.bytes()) {
|
|
||||||
return MEGABYTE;
|
|
||||||
} else if (size >= KILOBYTE.bytes()) {
|
|
||||||
return KILOBYTE;
|
|
||||||
} else {
|
|
||||||
return BYTE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DecimalFormat smallFormat;
|
|
||||||
private DecimalFormat largeFormat;
|
|
||||||
|
|
||||||
FileSizeFormat(Locale locale) {
|
|
||||||
smallFormat = new DecimalFormat("#0.0", new DecimalFormatSymbols(locale));
|
|
||||||
largeFormat = new DecimalFormat("###0", new DecimalFormatSymbols(locale));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String format(long size) {
|
|
||||||
return format(size, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String format(long size, ScaleUnit unit) {
|
|
||||||
return format(size, unit, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("checkstyle:magicnumber")
|
|
||||||
public String format(long size, ScaleUnit unit, boolean omitSymbol) {
|
|
||||||
if (size < 0L) {
|
|
||||||
throw new IllegalArgumentException("file size cannot be negative: " + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unit == null) {
|
|
||||||
unit = ScaleUnit.getScaleUnit(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
double scaledSize = (double) size / unit.bytes();
|
|
||||||
String scaledSymbol = " " + unit.symbol();
|
|
||||||
|
|
||||||
if (omitSymbol) {
|
|
||||||
scaledSymbol = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unit == ScaleUnit.BYTE) {
|
|
||||||
return largeFormat.format(size) + scaledSymbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scaledSize < 0.05 || scaledSize >= 10.0) {
|
|
||||||
return largeFormat.format(scaledSize) + scaledSymbol;
|
|
||||||
} else {
|
|
||||||
return smallFormat.format(scaledSize) + scaledSymbol;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String formatProgress(long progressedSize, long size) {
|
|
||||||
if (progressedSize < 0L) {
|
|
||||||
throw new IllegalArgumentException("progressed file size cannot be negative: " + size);
|
|
||||||
}
|
|
||||||
if (size >= 0 && progressedSize > size) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"progressed file size cannot be greater than size: " + progressedSize + " > " + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size >= 0L && progressedSize != size) {
|
|
||||||
ScaleUnit unit = ScaleUnit.getScaleUnit(size);
|
|
||||||
String formattedProgressedSize = format(progressedSize, unit, true);
|
|
||||||
String formattedSize = format(size, unit);
|
|
||||||
|
|
||||||
return formattedProgressedSize + "/" + formattedSize;
|
|
||||||
} else {
|
|
||||||
return format(progressedSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PrintStream out;
|
protected PrintStream out;
|
||||||
|
|
||||||
protected AbstractMavenTransferListener(PrintStream out) {
|
protected AbstractMavenTransferListener(PrintStream out) {
|
||||||
|
@ -234,12 +85,15 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferList
|
||||||
message.append(darkOff).append(resource.getRepositoryId());
|
message.append(darkOff).append(resource.getRepositoryId());
|
||||||
message.append(darkOn).append(": ").append(resource.getRepositoryUrl());
|
message.append(darkOn).append(": ").append(resource.getRepositoryUrl());
|
||||||
message.append(darkOff).append(resource.getResourceName());
|
message.append(darkOff).append(resource.getResourceName());
|
||||||
message.append(darkOn).append(" (").append(format.format(contentLength));
|
message.append(darkOn).append(" (");
|
||||||
|
format.format(message, contentLength);
|
||||||
|
|
||||||
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
|
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
|
||||||
if (duration > 0L) {
|
if (duration > 0L) {
|
||||||
double bytesPerSecond = contentLength / (duration / 1000.0);
|
double bytesPerSecond = contentLength / (duration / 1000.0);
|
||||||
message.append(" at ").append(format.format((long) bytesPerSecond)).append("/s");
|
message.append(" at ");
|
||||||
|
format.format(message, (long) bytesPerSecond);
|
||||||
|
message.append("/s");
|
||||||
}
|
}
|
||||||
|
|
||||||
message.append(')').append(darkOff);
|
message.append(')').append(darkOff);
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you 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.apache.maven.cli.transfer;
|
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BatchModeMavenTransferListener
|
|
||||||
*/
|
|
||||||
public class BatchModeMavenTransferListener extends AbstractMavenTransferListener {
|
|
||||||
public BatchModeMavenTransferListener(PrintStream out) {
|
|
||||||
super(out);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -87,7 +87,7 @@ public class ConsoleMavenTransferListener extends AbstractMavenTransferListener
|
||||||
buffer.append(" (");
|
buffer.append(" (");
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.append(format.formatProgress(complete, total));
|
format.formatProgress(buffer, complete, total);
|
||||||
|
|
||||||
if (printResourceNames) {
|
if (printResourceNames) {
|
||||||
buffer.append(")");
|
buffer.append(")");
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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.apache.maven.cli.transfer;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
|
||||||
|
* (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
|
||||||
|
* and <code>###0</code> for numbers between 10 and 1000+ by default.
|
||||||
|
*
|
||||||
|
* @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
|
||||||
|
* @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
|
||||||
|
* @see <a
|
||||||
|
* href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
|
||||||
|
*/
|
||||||
|
public class FileSizeFormat {
|
||||||
|
public enum ScaleUnit {
|
||||||
|
BYTE {
|
||||||
|
@Override
|
||||||
|
public long bytes() {
|
||||||
|
return 1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String symbol() {
|
||||||
|
return "B";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
KILOBYTE {
|
||||||
|
@Override
|
||||||
|
public long bytes() {
|
||||||
|
return 1000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String symbol() {
|
||||||
|
return "kB";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MEGABYTE {
|
||||||
|
@Override
|
||||||
|
public long bytes() {
|
||||||
|
return KILOBYTE.bytes() * KILOBYTE.bytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String symbol() {
|
||||||
|
return "MB";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GIGABYTE {
|
||||||
|
@Override
|
||||||
|
public long bytes() {
|
||||||
|
return MEGABYTE.bytes() * KILOBYTE.bytes();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String symbol() {
|
||||||
|
return "GB";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public abstract long bytes();
|
||||||
|
|
||||||
|
public abstract String symbol();
|
||||||
|
|
||||||
|
public static ScaleUnit getScaleUnit(long size) {
|
||||||
|
if (size < 0L) {
|
||||||
|
throw new IllegalArgumentException("file size cannot be negative: " + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size >= GIGABYTE.bytes()) {
|
||||||
|
return GIGABYTE;
|
||||||
|
} else if (size >= MEGABYTE.bytes()) {
|
||||||
|
return MEGABYTE;
|
||||||
|
} else if (size >= KILOBYTE.bytes()) {
|
||||||
|
return KILOBYTE;
|
||||||
|
} else {
|
||||||
|
return BYTE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileSizeFormat(Locale locale) {}
|
||||||
|
|
||||||
|
public String format(long size) {
|
||||||
|
return format(size, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(long size, ScaleUnit unit) {
|
||||||
|
return format(size, unit, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(long size, ScaleUnit unit, boolean omitSymbol) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
format(sb, size, unit, omitSymbol);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void format(StringBuilder builder, long size) {
|
||||||
|
format(builder, size, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void format(StringBuilder builder, long size, ScaleUnit unit) {
|
||||||
|
format(builder, size, unit, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("checkstyle:magicnumber")
|
||||||
|
private void format(StringBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {
|
||||||
|
if (size < 0L) {
|
||||||
|
throw new IllegalArgumentException("file size cannot be negative: " + size);
|
||||||
|
}
|
||||||
|
if (unit == null) {
|
||||||
|
unit = ScaleUnit.getScaleUnit(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
double scaledSize = (double) size / unit.bytes();
|
||||||
|
|
||||||
|
if (unit == ScaleUnit.BYTE) {
|
||||||
|
builder.append(size);
|
||||||
|
} else if (scaledSize < 0.05d || scaledSize >= 10.0d) {
|
||||||
|
builder.append(Math.round(scaledSize));
|
||||||
|
} else {
|
||||||
|
builder.append(Math.round(scaledSize * 10d) / 10d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!omitSymbol) {
|
||||||
|
builder.append(" ").append(unit.symbol());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String formatProgress(long progressedSize, long size) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
formatProgress(sb, progressedSize, size);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void formatProgress(StringBuilder builder, long progressedSize, long size) {
|
||||||
|
if (progressedSize < 0L) {
|
||||||
|
throw new IllegalArgumentException("progressed file size cannot be negative: " + size);
|
||||||
|
}
|
||||||
|
if (size >= 0 && progressedSize > size) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"progressed file size cannot be greater than size: " + progressedSize + " > " + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size >= 0L && progressedSize != size) {
|
||||||
|
ScaleUnit unit = ScaleUnit.getScaleUnit(size);
|
||||||
|
format(builder, progressedSize, unit, true);
|
||||||
|
builder.append("/");
|
||||||
|
format(builder, size, unit, false);
|
||||||
|
} else {
|
||||||
|
ScaleUnit unit = ScaleUnit.getScaleUnit(progressedSize);
|
||||||
|
|
||||||
|
format(builder, progressedSize, unit, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,6 @@ package org.apache.maven.cli.transfer;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
|
|
||||||
import org.eclipse.aether.transfer.AbstractTransferListener;
|
import org.eclipse.aether.transfer.AbstractTransferListener;
|
||||||
import org.eclipse.aether.transfer.TransferCancelledException;
|
import org.eclipse.aether.transfer.TransferCancelledException;
|
||||||
import org.eclipse.aether.transfer.TransferEvent;
|
import org.eclipse.aether.transfer.TransferEvent;
|
||||||
|
@ -81,13 +80,17 @@ public class Slf4jMavenTransferListener extends AbstractTransferListener {
|
||||||
StringBuilder message = new StringBuilder();
|
StringBuilder message = new StringBuilder();
|
||||||
message.append(action).append(' ').append(direction).append(' ').append(resource.getRepositoryId());
|
message.append(action).append(' ').append(direction).append(' ').append(resource.getRepositoryId());
|
||||||
message.append(": ");
|
message.append(": ");
|
||||||
message.append(resource.getRepositoryUrl()).append(resource.getResourceName());
|
message.append(resource.getRepositoryUrl())
|
||||||
message.append(" (").append(format.format(contentLength));
|
.append(resource.getResourceName())
|
||||||
|
.append(" (");
|
||||||
|
format.format(message, contentLength);
|
||||||
|
|
||||||
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
|
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
|
||||||
if (duration > 0L) {
|
if (duration > 0L) {
|
||||||
double bytesPerSecond = contentLength / (duration / 1000.0);
|
double bytesPerSecond = contentLength / (duration / 1000.0);
|
||||||
message.append(" at ").append(format.format((long) bytesPerSecond)).append("/s");
|
message.append(" at ");
|
||||||
|
format.format(message, (long) bytesPerSecond);
|
||||||
|
message.append("/s");
|
||||||
}
|
}
|
||||||
|
|
||||||
message.append(')');
|
message.append(')');
|
||||||
|
|
|
@ -20,8 +20,7 @@ package org.apache.maven.cli.transfer;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
|
import org.apache.maven.cli.transfer.FileSizeFormat.ScaleUnit;
|
||||||
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat.ScaleUnit;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
Loading…
Reference in New Issue