diff options
Diffstat (limited to 'core/src/main/java/org/elasticsearch/common/unit/TimeValue.java')
-rw-r--r-- | core/src/main/java/org/elasticsearch/common/unit/TimeValue.java | 123 |
1 files changed, 86 insertions, 37 deletions
diff --git a/core/src/main/java/org/elasticsearch/common/unit/TimeValue.java b/core/src/main/java/org/elasticsearch/common/unit/TimeValue.java index 2058355d30..5a56603dad 100644 --- a/core/src/main/java/org/elasticsearch/common/unit/TimeValue.java +++ b/core/src/main/java/org/elasticsearch/common/unit/TimeValue.java @@ -30,14 +30,50 @@ import org.joda.time.format.PeriodFormat; import org.joda.time.format.PeriodFormatter; import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.Locale; +import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.TimeUnit; public class TimeValue implements Writeable { /** How many nano-seconds in one milli-second */ - public static final long NSEC_PER_MSEC = 1000000; + public static final long NSEC_PER_MSEC = TimeUnit.NANOSECONDS.convert(1, TimeUnit.MILLISECONDS); + + private static Map<TimeUnit, Byte> TIME_UNIT_BYTE_MAP; + private static Map<Byte, TimeUnit> BYTE_TIME_UNIT_MAP; + + static { + final Map<TimeUnit, Byte> timeUnitByteMap = new HashMap<>(); + timeUnitByteMap.put(TimeUnit.NANOSECONDS, (byte)0); + timeUnitByteMap.put(TimeUnit.MICROSECONDS, (byte)1); + timeUnitByteMap.put(TimeUnit.MILLISECONDS, (byte)2); + timeUnitByteMap.put(TimeUnit.SECONDS, (byte)3); + timeUnitByteMap.put(TimeUnit.MINUTES, (byte)4); + timeUnitByteMap.put(TimeUnit.HOURS, (byte)5); + timeUnitByteMap.put(TimeUnit.DAYS, (byte)6); + + final Set<Byte> bytes = new HashSet<>(); + for (TimeUnit value : TimeUnit.values()) { + assert timeUnitByteMap.containsKey(value) : value; + assert bytes.add(timeUnitByteMap.get(value)); + } + + final Map<Byte, TimeUnit> byteTimeUnitMap = new HashMap<>(); + for (Map.Entry<TimeUnit, Byte> entry : timeUnitByteMap.entrySet()) { + byteTimeUnitMap.put(entry.getValue(), entry.getKey()); + } + + TIME_UNIT_BYTE_MAP = Collections.unmodifiableMap(timeUnitByteMap); + BYTE_TIME_UNIT_MAP = Collections.unmodifiableMap(byteTimeUnitMap); + } + + public static final TimeValue MINUS_ONE = timeValueMillis(-1); + public static final TimeValue ZERO = timeValueMillis(0); public static TimeValue timeValueNanos(long nanos) { return new TimeValue(nanos, TimeUnit.NANOSECONDS); @@ -60,8 +96,19 @@ public class TimeValue implements Writeable { } private final long duration; + + // visible for testing + long duration() { + return duration; + } + private final TimeUnit timeUnit; + // visible for testing + TimeUnit timeUnit() { + return timeUnit; + } + public TimeValue(long millis) { this(millis, TimeUnit.MILLISECONDS); } @@ -76,12 +123,13 @@ public class TimeValue implements Writeable { */ public TimeValue(StreamInput in) throws IOException { duration = in.readZLong(); - timeUnit = TimeUnit.NANOSECONDS; + timeUnit = BYTE_TIME_UNIT_MAP.get(in.readByte()); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeZLong(nanos()); + out.writeZLong(duration); + out.writeByte(TIME_UNIT_BYTE_MAP.get(timeUnit)); } public long nanos() { @@ -240,19 +288,19 @@ public class TimeValue implements Writeable { } switch (timeUnit) { case NANOSECONDS: - return Strings.format1Decimals(duration, "nanos"); + return duration + "nanos"; case MICROSECONDS: - return Strings.format1Decimals(duration, "micros"); + return duration + "micros"; case MILLISECONDS: - return Strings.format1Decimals(duration, "ms"); + return duration + "ms"; case SECONDS: - return Strings.format1Decimals(duration, "s"); + return duration + "s"; case MINUTES: - return Strings.format1Decimals(duration, "m"); + return duration + "m"; case HOURS: - return Strings.format1Decimals(duration, "h"); + return duration + "h"; case DAYS: - return Strings.format1Decimals(duration, "d"); + return duration + "d"; default: throw new IllegalArgumentException("unknown time unit: " + timeUnit.name()); } @@ -270,47 +318,48 @@ public class TimeValue implements Writeable { return defaultValue; } try { - long millis; String lowerSValue = sValue.toLowerCase(Locale.ROOT).trim(); - if (lowerSValue.endsWith("ms")) { - millis = parse(lowerSValue, 2, 1); + if (lowerSValue.endsWith("nanos")) { + return new TimeValue(parse(lowerSValue, 5), TimeUnit.NANOSECONDS); + } else if (lowerSValue.endsWith("micros")) { + return new TimeValue(parse(lowerSValue, 6), TimeUnit.MICROSECONDS); + } else if (lowerSValue.endsWith("ms")) { + return new TimeValue(parse(lowerSValue, 2), TimeUnit.MILLISECONDS); } else if (lowerSValue.endsWith("s")) { - millis = parse(lowerSValue, 1, 1000); + return new TimeValue(parse(lowerSValue, 1), TimeUnit.SECONDS); } else if (lowerSValue.endsWith("m")) { - millis = parse(lowerSValue, 1, 60 * 1000); + return new TimeValue(parse(lowerSValue, 1), TimeUnit.MINUTES); } else if (lowerSValue.endsWith("h")) { - millis = parse(lowerSValue, 1, 60 * 60 * 1000); + return new TimeValue(parse(lowerSValue, 1), TimeUnit.HOURS); } else if (lowerSValue.endsWith("d")) { - millis = parse(lowerSValue, 1, 24 * 60 * 60 * 1000); - } else if (lowerSValue.endsWith("w")) { - millis = parse(lowerSValue, 1, 7 * 24 * 60 * 60 * 1000); - } else if (lowerSValue.equals("-1")) { - // Allow this special value to be unit-less: - millis = -1; - } else if (lowerSValue.equals("0")) { - // Allow this special value to be unit-less: - millis = 0; + return new TimeValue(parse(lowerSValue, 1), TimeUnit.DAYS); + } else if (lowerSValue.matches("-0*1")) { + return TimeValue.MINUS_ONE; + } else if (lowerSValue.matches("0+")) { + return TimeValue.ZERO; } else { // Missing units: - throw new ElasticsearchParseException("Failed to parse setting [{}] with value [{}] as a time value: unit is missing or unrecognized", settingName, sValue); + throw new ElasticsearchParseException( + "failed to parse setting [{}] with value [{}] as a time value: unit is missing or unrecognized", + settingName, + sValue); } - return new TimeValue(millis, TimeUnit.MILLISECONDS); } catch (NumberFormatException e) { - throw new ElasticsearchParseException("Failed to parse [{}]", e, sValue); + throw new ElasticsearchParseException("failed to parse [{}]", e, sValue); } } - private static long parse(String s, int suffixLength, long scale) { - return (long) (Double.parseDouble(s.substring(0, s.length() - suffixLength)) * scale); + private static long parse(String s, int suffixLength) { + return Long.parseLong(s.substring(0, s.length() - suffixLength).trim()); } - static final long C0 = 1L; - static final long C1 = C0 * 1000L; - static final long C2 = C1 * 1000L; - static final long C3 = C2 * 1000L; - static final long C4 = C3 * 60L; - static final long C5 = C4 * 60L; - static final long C6 = C5 * 24L; + private static final long C0 = 1L; + private static final long C1 = C0 * 1000L; + private static final long C2 = C1 * 1000L; + private static final long C3 = C2 * 1000L; + private static final long C4 = C3 * 60L; + private static final long C5 = C4 * 60L; + private static final long C6 = C5 * 24L; @Override public boolean equals(Object o) { |