mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-25 01:19:02 +00:00
[7.x] Add TimeValue.toHumanReadableString() to allow specifyin… (#43545)
* Enhance TimeValue.toString() to allow specifying fractional values. This enhances the `TimeValue` class to allow specifying the number of truncated fractional decimals when calling `toString()`. The default remains 1, however, more (or less, such as 0) can be specified to change the output. This commit also re-organizes some things in `TimeValue` such as putting all the class variables near the top of the class, and moving the constructors to the first methods in the class, in order to follow the structure of our other code. * Rename `toString(...)` to `toHumanReadableString(...)`
This commit is contained in:
parent
50eac875e4
commit
8927081981
@ -31,6 +31,26 @@ public class TimeValue implements Comparable<TimeValue> {
|
||||
public static final TimeValue MINUS_ONE = timeValueMillis(-1);
|
||||
public static final TimeValue ZERO = timeValueMillis(0);
|
||||
|
||||
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;
|
||||
|
||||
private final long duration;
|
||||
private final TimeUnit timeUnit;
|
||||
|
||||
public TimeValue(long millis) {
|
||||
this(millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public TimeValue(long duration, TimeUnit timeUnit) {
|
||||
this.duration = duration;
|
||||
this.timeUnit = timeUnit;
|
||||
}
|
||||
|
||||
public static TimeValue timeValueNanos(long nanos) {
|
||||
return new TimeValue(nanos, TimeUnit.NANOSECONDS);
|
||||
}
|
||||
@ -51,17 +71,6 @@ public class TimeValue implements Comparable<TimeValue> {
|
||||
return new TimeValue(hours, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
private final long duration;
|
||||
|
||||
/**
|
||||
* @return the number of {@link #timeUnit()} units this value contains
|
||||
*/
|
||||
public long duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
private final TimeUnit timeUnit;
|
||||
|
||||
/**
|
||||
* @return the unit used for the this time value, see {@link #duration()}
|
||||
*/
|
||||
@ -69,13 +78,11 @@ public class TimeValue implements Comparable<TimeValue> {
|
||||
return timeUnit;
|
||||
}
|
||||
|
||||
public TimeValue(long millis) {
|
||||
this(millis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public TimeValue(long duration, TimeUnit timeUnit) {
|
||||
this.duration = duration;
|
||||
this.timeUnit = timeUnit;
|
||||
/**
|
||||
* @return the number of {@link #timeUnit()} units this value contains
|
||||
*/
|
||||
public long duration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public long nanos() {
|
||||
@ -187,9 +194,31 @@ public class TimeValue implements Comparable<TimeValue> {
|
||||
*
|
||||
* Note that this method might produce fractional time values (ex 1.6m) which cannot be
|
||||
* parsed by method like {@link TimeValue#parse(String, String, String)}.
|
||||
*
|
||||
* Also note that the maximum string value that will be generated is
|
||||
* {@code 106751.9d} due to the way that values are internally converted
|
||||
* to nanoseconds (106751.9 days is Long.MAX_VALUE nanoseconds)
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.toHumanReadableString(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link String} representation of the current {@link TimeValue}.
|
||||
*
|
||||
* Note that this method might produce fractional time values (ex 1.6m) which cannot be
|
||||
* parsed by method like {@link TimeValue#parse(String, String, String)}. The number of
|
||||
* fractional decimals (up to 10 maximum) are truncated to the number of fraction pieces
|
||||
* specified.
|
||||
*
|
||||
* Also note that the maximum string value that will be generated is
|
||||
* {@code 106751.9d} due to the way that values are internally converted
|
||||
* to nanoseconds (106751.9 days is Long.MAX_VALUE nanoseconds)
|
||||
*
|
||||
* @param fractionPieces the number of decimal places to include
|
||||
*/
|
||||
public String toHumanReadableString(int fractionPieces) {
|
||||
if (duration < 0) {
|
||||
return Long.toString(duration);
|
||||
}
|
||||
@ -218,25 +247,68 @@ public class TimeValue implements Comparable<TimeValue> {
|
||||
value = microsFrac();
|
||||
suffix = "micros";
|
||||
}
|
||||
return formatDecimal(value) + suffix;
|
||||
// Limit fraction pieces to a min of 0 and maximum of 10
|
||||
return formatDecimal(value, Math.min(10, Math.max(0, fractionPieces))) + suffix;
|
||||
}
|
||||
|
||||
private static String formatDecimal(double value) {
|
||||
private static String formatDecimal(double value, int fractionPieces) {
|
||||
String p = String.valueOf(value);
|
||||
int totalLength = p.length();
|
||||
int ix = p.indexOf('.') + 1;
|
||||
int ex = p.indexOf('E');
|
||||
char fraction = p.charAt(ix);
|
||||
if (fraction == '0') {
|
||||
// Location where the fractional values end
|
||||
int fractionEnd = ex == -1 ? Math.min(ix + fractionPieces, totalLength) : ex;
|
||||
|
||||
// Determine the value of the fraction, so if it were .000 the
|
||||
// actual long value is 0, in which case, it can be elided.
|
||||
long fractionValue;
|
||||
try {
|
||||
fractionValue = Long.parseLong(p.substring(ix, fractionEnd));
|
||||
} catch (NumberFormatException e) {
|
||||
fractionValue = 0;
|
||||
}
|
||||
|
||||
if (fractionValue == 0 || fractionPieces <= 0) {
|
||||
// Either the part of the fraction we were asked to report is
|
||||
// zero, or the user requested 0 fraction pieces, so return
|
||||
// only the integral value
|
||||
if (ex != -1) {
|
||||
return p.substring(0, ix - 1) + p.substring(ex);
|
||||
} else {
|
||||
return p.substring(0, ix - 1);
|
||||
}
|
||||
} else {
|
||||
// Build up an array of fraction characters, without going past
|
||||
// the end of the string. This keeps track of trailing '0' chars
|
||||
// that should be truncated from the end to avoid getting a
|
||||
// string like "1.3000d" (returning "1.3d" instead) when the
|
||||
// value is 1.30000009
|
||||
char[] fractions = new char[fractionPieces];
|
||||
int fracCount = 0;
|
||||
int truncateCount = 0;
|
||||
for (int i = 0; i < fractionPieces; i++) {
|
||||
int position = ix + i;
|
||||
if (position >= fractionEnd) {
|
||||
// No more pieces, the fraction has ended
|
||||
break;
|
||||
}
|
||||
char fraction = p.charAt(position);
|
||||
if (fraction == '0') {
|
||||
truncateCount++;
|
||||
} else {
|
||||
truncateCount = 0;
|
||||
}
|
||||
fractions[i] = fraction;
|
||||
fracCount++;
|
||||
}
|
||||
|
||||
// Generate the fraction string from the char array, truncating any trailing zeros
|
||||
String fractionStr = new String(fractions, 0, fracCount - truncateCount);
|
||||
|
||||
if (ex != -1) {
|
||||
return p.substring(0, ix) + fraction + p.substring(ex);
|
||||
return p.substring(0, ix) + fractionStr + p.substring(ex);
|
||||
} else {
|
||||
return p.substring(0, ix) + fraction;
|
||||
return p.substring(0, ix) + fractionStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -317,14 +389,6 @@ public class TimeValue implements Comparable<TimeValue> {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (this == o) return true;
|
||||
|
@ -47,6 +47,26 @@ public class TimeValueTests extends ESTestCase {
|
||||
assertThat("1.5m", equalTo(new TimeValue(90, TimeUnit.SECONDS).toString()));
|
||||
assertThat("1.5h", equalTo(new TimeValue(90, TimeUnit.MINUTES).toString()));
|
||||
assertThat("1.5d", equalTo(new TimeValue(36, TimeUnit.HOURS).toString()));
|
||||
assertThat("1d", equalTo(new TimeValue(36, TimeUnit.HOURS).toHumanReadableString(0)));
|
||||
assertThat("1d", equalTo(new TimeValue(36, TimeUnit.HOURS).toHumanReadableString(-4)));
|
||||
assertThat("1.5d", equalTo(new TimeValue(36, TimeUnit.HOURS).toHumanReadableString(2)));
|
||||
assertThat("1.45d", equalTo(new TimeValue(35, TimeUnit.HOURS).toHumanReadableString(2)));
|
||||
assertThat("1.4583333333d", equalTo(new TimeValue(35, TimeUnit.HOURS).toHumanReadableString(10)));
|
||||
assertThat("1d", equalTo(new TimeValue(103723200, TimeUnit.MILLISECONDS).toHumanReadableString(0)));
|
||||
assertThat("1.2d", equalTo(new TimeValue(103723200, TimeUnit.MILLISECONDS).toHumanReadableString(1)));
|
||||
assertThat("1.2d", equalTo(new TimeValue(103723200, TimeUnit.MILLISECONDS).toHumanReadableString(2)));
|
||||
assertThat("1.2d", equalTo(new TimeValue(103723200, TimeUnit.MILLISECONDS).toHumanReadableString(3)));
|
||||
assertThat("1.2005d", equalTo(new TimeValue(103723200, TimeUnit.MILLISECONDS).toHumanReadableString(4)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(0)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(1)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(2)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(3)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(4)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(5)));
|
||||
assertThat("1d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(6)));
|
||||
assertThat("1.0000008d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(7)));
|
||||
assertThat("1.00000089d", equalTo(new TimeValue(86400077, TimeUnit.MILLISECONDS).toHumanReadableString(8)));
|
||||
assertThat("1.4583333333d", equalTo(new TimeValue(35, TimeUnit.HOURS).toHumanReadableString(Integer.MAX_VALUE)));
|
||||
assertThat("1000d", equalTo(new TimeValue(1000, TimeUnit.DAYS).toString()));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user