package diskCacheV111.util;
import java.util.Arrays;
import org.dcache.util.ByteUnit;
import org.dcache.util.ByteUnits.JedecPrefix;
import org.dcache.util.ByteUnits.Representation;
import static com.google.common.base.Preconditions.checkArgument;
import static org.dcache.util.ByteUnit.BYTES;
import static org.dcache.util.ByteUnit.KiB;
import static org.dcache.util.ByteUnit.Type.BINARY;
import static org.dcache.util.ByteUnits.jedecPrefix;
/**
* Immutable quantity of disk space.
*
* Essentially just an integer, but can parse suffixes for kibibytes, mebibytes,
* gibibytes, and tebibytes.
*
* The quantity can be unspecified, with the string representation being a dash.
* This is represented as Long.MAX_VALUE bytes, the quantity larger than any other
* disk space.
*
* Disk space is always positive.
*/
public class DiskSpace
{
public static final DiskSpace UNSPECIFIED = new DiskSpace(Long.MAX_VALUE);
private static final Representation JEDEC_WITH_LOWER_K = new JedecPrefixLowerKRepresentation();
private final long _value;
private static class JedecPrefixLowerKRepresentation extends JedecPrefix
{
@Override
public String of(ByteUnit unit)
{
return (unit == KiB) ? "k" : super.of(unit);
}
}
public DiskSpace(long value)
{
checkArgument(value >= 0, "Negative value is not allowed");
_value = value;
}
public DiskSpace(String s)
{
this(parseUnitLong(s));
}
private static long parseUnitLong(String s)
{
checkArgument(!s.isEmpty(), "Argument must not be empty");
if (s.equals("Infinity") || s.equals("-")) {
return Long.MAX_VALUE;
}
String lastChar = s.substring(s.length()-1).toUpperCase();
ByteUnit units = Arrays.stream(ByteUnit.values())
.skip(1)
.filter(u -> u.hasType(BINARY) && lastChar.equals(jedecPrefix().of(u)))
.findFirst()
.orElse(BYTES);
String number = units == BYTES ? s : s.substring(0, s.length() -1);
return units.toBytes(Long.parseLong(number));
}
@Override
public String toString()
{
return toUnitString(_value);
}
public static String toUnitString(long value)
{
if (value == Long.MAX_VALUE) {
return "-";
}
ByteUnit units = BINARY.exactUnitsOf(value);
return Long.toString(units.convert(value, BYTES)) + JEDEC_WITH_LOWER_K.of(units);
}
public long longValue()
{
return _value;
}
@Override
public boolean equals(Object o)
{
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DiskSpace that = (DiskSpace) o;
return _value == that._value;
}
@Override
public int hashCode()
{
return (int) (_value ^ (_value >>> 32));
}
public boolean isLargerThan(long value)
{
return value < _value && _value < Long.MAX_VALUE;
}
public boolean isLessThan(long value)
{
return _value < value;
}
public boolean isSpecified()
{
return _value != Long.MAX_VALUE;
}
public long orElse(long other)
{
return isSpecified() ? _value : other;
}
public DiskSpace orElse(DiskSpace other)
{
return isSpecified() ? this : other;
}
}