package org.ovirt.engine.core.common.utils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class SizeConverter {
public static final long CONVERT_FACTOR = 1024L;
public static final long BYTES_IN_KB = 1024L;
public static final long BYTES_IN_MB = 1024L * 1024L;
public static final long BYTES_IN_GB = 1024L * 1024L * 1024L;
public static final long BYTES_IN_TB = BYTES_IN_GB * 1024L;
public SizeConverter() {
}
public static enum SizeUnit {
BYTES(1, "B"),
KiB(2, "KiB"),
MiB(3, "MiB"),
GiB(4, "GiB"),
TiB(5, "TiB"),
PiB(6, "PiB"),
EiB(7, "EiB"),
ZiB(8, "ZiB"),
YiB(9, "YiB");
private long unitWeight;
private String unitInString;
private static List<Pair<Long, SizeUnit>> weightToUnit = new ArrayList<>();
private SizeUnit(long unitWeight, String unitString) {
this.unitWeight = unitWeight;
this.unitInString = unitString;
}
static {
for (SizeUnit unit : SizeUnit.values()) {
weightToUnit.add(new Pair<>(unit.getUnitWeight(), unit));
}
weightToUnit.sort(Comparator.comparing(Pair::getFirst, Comparator.reverseOrder()));
}
public long getUnitWeight() {
return unitWeight;
}
public SizeUnit getUnit(long weight) {
return weightToUnit.get((int) weight).getSecond();
}
public static SizeUnit getMaxHandledUnit() {
return weightToUnit.get(0).getSecond();
}
public static SizeUnit getMinHandledUnit() {
return weightToUnit.get(weightToUnit.size() - 1).getSecond();
}
@Override
public String toString() {
return unitInString;
}
};
public static Number convert(long size, SizeUnit fromUnit, SizeUnit toUnit) {
long fromType = fromUnit.getUnitWeight();
long toType = toUnit.getUnitWeight();
return size * (Math.pow(CONVERT_FACTOR, fromType) / Math.pow(CONVERT_FACTOR, toType));
}
public static Pair<SizeUnit, Double> autoConvert(long size, SizeUnit inUnit) {
for (Pair<Long, SizeUnit> currentUnitPair : SizeUnit.weightToUnit) {
if (size / Math.pow(CONVERT_FACTOR, currentUnitPair.getFirst() - inUnit.getUnitWeight()) >= 1) {
return new Pair<>(currentUnitPair.getSecond(),
SizeConverter.convert(size, inUnit, currentUnitPair.getSecond()).doubleValue());
}
}
return new Pair<>(SizeUnit.BYTES, (double) size);
}
public static SizeUnit leastUnitInList(List<Pair<SizeUnit, Double>> operands) {
SizeUnit leastUnit = SizeUnit.getMaxHandledUnit();
for(Pair<SizeUnit, Double> operand : operands) {
if(operand.getFirst().getUnitWeight() < leastUnit.getUnitWeight()) {
leastUnit = operand.getFirst();
}
}
return leastUnit;
}
public static SizeUnit maxUnitInList(List<Pair<SizeUnit, Double>> operands) {
SizeUnit maxUnit = SizeUnit.getMinHandledUnit();
for(Pair<SizeUnit, Double> operand : operands) {
if(operand.getFirst().getUnitWeight() > maxUnit.getUnitWeight()) {
maxUnit = operand.getFirst();
}
}
return maxUnit;
}
@SafeVarargs
public static List<Pair<SizeUnit, Double>> getMathOperationSafeOperands(Pair<SizeUnit, Double>... operands) {
List<Pair<SizeUnit, Double>> operationReadyOperands = new ArrayList<>();
List<Pair<SizeUnit, Double>> convertedOperands = new ArrayList<>();
for (Pair<SizeUnit, Double> operand : operands) {
convertedOperands.add(autoConvert(operand.getSecond().longValue(), operand.getFirst()));
}
SizeUnit finalUnit = leastUnitInList(convertedOperands);
for (Pair<SizeUnit, Double> operand : convertedOperands) {
if(operand.getFirst() != finalUnit) {
operationReadyOperands.add(new Pair<>(finalUnit,
convert(operand.getSecond().longValue(), operand.getFirst(), finalUnit).doubleValue()));
} else {
operationReadyOperands.add(operand);
}
}
return operationReadyOperands;
}
}