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;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
|
||||
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_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 AbstractMavenTransferListener(PrintStream out) {
|
||||
|
@ -234,12 +85,15 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferList
|
|||
message.append(darkOff).append(resource.getRepositoryId());
|
||||
message.append(darkOn).append(": ").append(resource.getRepositoryUrl());
|
||||
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();
|
||||
if (duration > 0L) {
|
||||
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);
|
||||
|
|
|
@ -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(format.formatProgress(complete, total));
|
||||
format.formatProgress(buffer, complete, total);
|
||||
|
||||
if (printResourceNames) {
|
||||
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 org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
|
||||
import org.eclipse.aether.transfer.AbstractTransferListener;
|
||||
import org.eclipse.aether.transfer.TransferCancelledException;
|
||||
import org.eclipse.aether.transfer.TransferEvent;
|
||||
|
@ -81,13 +80,17 @@ public class Slf4jMavenTransferListener extends AbstractTransferListener {
|
|||
StringBuilder message = new StringBuilder();
|
||||
message.append(action).append(' ').append(direction).append(' ').append(resource.getRepositoryId());
|
||||
message.append(": ");
|
||||
message.append(resource.getRepositoryUrl()).append(resource.getResourceName());
|
||||
message.append(" (").append(format.format(contentLength));
|
||||
message.append(resource.getRepositoryUrl())
|
||||
.append(resource.getResourceName())
|
||||
.append(" (");
|
||||
format.format(message, contentLength);
|
||||
|
||||
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
|
||||
if (duration > 0L) {
|
||||
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(')');
|
||||
|
|
|
@ -20,8 +20,7 @@ package org.apache.maven.cli.transfer;
|
|||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
|
||||
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat.ScaleUnit;
|
||||
import org.apache.maven.cli.transfer.FileSizeFormat.ScaleUnit;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
|
Loading…
Reference in New Issue