Keep input time unit when parsing TimeValues

This commit modifies TimeValue parsing to keep the input time unit. This
enables round-trip parsing from instances of String to instances of
TimeValue and vice-versa. With this, this commit removes support for the
unit "w" representing weeks, and also removes support for fractional
values of units (e.g., 0.5s).

Relates #19102
This commit is contained in:
Jason Tedor 2016-06-27 18:41:18 -04:00 committed by GitHub
parent 1e6bebb6a3
commit 2f638b5a23
24 changed files with 183 additions and 122 deletions

View File

@ -323,7 +323,6 @@
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]recycler[/\\]Recyclers.java" checks="LineLength" /> <suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]recycler[/\\]Recyclers.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]rounding[/\\]Rounding.java" checks="LineLength" /> <suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]rounding[/\\]Rounding.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]ByteSizeValue.java" checks="LineLength" /> <suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]ByteSizeValue.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]unit[/\\]TimeValue.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]util[/\\]BigArrays.java" checks="LineLength" /> <suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]util[/\\]BigArrays.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]util[/\\]CancellableThreads.java" checks="LineLength" /> <suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]util[/\\]CancellableThreads.java" checks="LineLength" />
<suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]util[/\\]CollectionUtils.java" checks="LineLength" /> <suppress files="core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]common[/\\]util[/\\]CollectionUtils.java" checks="LineLength" />

View File

@ -24,10 +24,7 @@ import java.io.IOException;
/** /**
* Implementers can be written to a {@linkplain StreamOutput} and read from a {@linkplain StreamInput}. This allows them to be "thrown * Implementers can be written to a {@linkplain StreamOutput} and read from a {@linkplain StreamInput}. This allows them to be "thrown
* across the wire" using Elasticsearch's internal protocol. If the implementer also implements equals and hashCode then a copy made by * across the wire" using Elasticsearch's internal protocol. If the implementer also implements equals and hashCode then a copy made by
* serializing and deserializing must be equal and have the same hashCode. It isn't required that such a copy be entirely unchanged. For * serializing and deserializing must be equal and have the same hashCode. It isn't required that such a copy be entirely unchanged.
* example, {@link org.elasticsearch.common.unit.TimeValue} converts the time to nanoseconds for serialization.
* {@linkplain org.elasticsearch.common.unit.TimeValue} actually implements {@linkplain Writeable} not {@linkplain Streamable} but it has
* the same contract.
* *
* Prefer implementing {@link Writeable} over implementing this interface where possible. Lots of code depends on this interface so this * Prefer implementing {@link Writeable} over implementing this interface where possible. Lots of code depends on this interface so this
* isn't always possible. * isn't always possible.

View File

@ -24,8 +24,7 @@ import java.io.IOException;
/** /**
* Implementers can be written to a {@linkplain StreamOutput} and read from a {@linkplain StreamInput}. This allows them to be "thrown * Implementers can be written to a {@linkplain StreamOutput} and read from a {@linkplain StreamInput}. This allows them to be "thrown
* across the wire" using Elasticsearch's internal protocol. If the implementer also implements equals and hashCode then a copy made by * across the wire" using Elasticsearch's internal protocol. If the implementer also implements equals and hashCode then a copy made by
* serializing and deserializing must be equal and have the same hashCode. It isn't required that such a copy be entirely unchanged. For * serializing and deserializing must be equal and have the same hashCode. It isn't required that such a copy be entirely unchanged.
* example, {@link org.elasticsearch.common.unit.TimeValue} converts the time to nanoseconds for serialization.
* *
* Prefer implementing this interface over implementing {@link Streamable} where possible. Lots of code depends on {@linkplain Streamable} * Prefer implementing this interface over implementing {@link Streamable} where possible. Lots of code depends on {@linkplain Streamable}
* so this isn't always possible. * so this isn't always possible.

View File

@ -30,14 +30,50 @@ import org.joda.time.format.PeriodFormat;
import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatter;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class TimeValue implements Writeable { public class TimeValue implements Writeable {
/** How many nano-seconds in one milli-second */ /** 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) { public static TimeValue timeValueNanos(long nanos) {
return new TimeValue(nanos, TimeUnit.NANOSECONDS); return new TimeValue(nanos, TimeUnit.NANOSECONDS);
@ -60,8 +96,19 @@ public class TimeValue implements Writeable {
} }
private final long duration; private final long duration;
// visible for testing
long duration() {
return duration;
}
private final TimeUnit timeUnit; private final TimeUnit timeUnit;
// visible for testing
TimeUnit timeUnit() {
return timeUnit;
}
public TimeValue(long millis) { public TimeValue(long millis) {
this(millis, TimeUnit.MILLISECONDS); this(millis, TimeUnit.MILLISECONDS);
} }
@ -76,12 +123,13 @@ public class TimeValue implements Writeable {
*/ */
public TimeValue(StreamInput in) throws IOException { public TimeValue(StreamInput in) throws IOException {
duration = in.readZLong(); duration = in.readZLong();
timeUnit = TimeUnit.NANOSECONDS; timeUnit = BYTE_TIME_UNIT_MAP.get(in.readByte());
} }
@Override @Override
public void writeTo(StreamOutput out) throws IOException { public void writeTo(StreamOutput out) throws IOException {
out.writeZLong(nanos()); out.writeZLong(duration);
out.writeByte(TIME_UNIT_BYTE_MAP.get(timeUnit));
} }
public long nanos() { public long nanos() {
@ -240,19 +288,19 @@ public class TimeValue implements Writeable {
} }
switch (timeUnit) { switch (timeUnit) {
case NANOSECONDS: case NANOSECONDS:
return Strings.format1Decimals(duration, "nanos"); return duration + "nanos";
case MICROSECONDS: case MICROSECONDS:
return Strings.format1Decimals(duration, "micros"); return duration + "micros";
case MILLISECONDS: case MILLISECONDS:
return Strings.format1Decimals(duration, "ms"); return duration + "ms";
case SECONDS: case SECONDS:
return Strings.format1Decimals(duration, "s"); return duration + "s";
case MINUTES: case MINUTES:
return Strings.format1Decimals(duration, "m"); return duration + "m";
case HOURS: case HOURS:
return Strings.format1Decimals(duration, "h"); return duration + "h";
case DAYS: case DAYS:
return Strings.format1Decimals(duration, "d"); return duration + "d";
default: default:
throw new IllegalArgumentException("unknown time unit: " + timeUnit.name()); throw new IllegalArgumentException("unknown time unit: " + timeUnit.name());
} }
@ -270,47 +318,48 @@ public class TimeValue implements Writeable {
return defaultValue; return defaultValue;
} }
try { try {
long millis;
String lowerSValue = sValue.toLowerCase(Locale.ROOT).trim(); String lowerSValue = sValue.toLowerCase(Locale.ROOT).trim();
if (lowerSValue.endsWith("ms")) { if (lowerSValue.endsWith("nanos")) {
millis = parse(lowerSValue, 2, 1); 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")) { } else if (lowerSValue.endsWith("s")) {
millis = parse(lowerSValue, 1, 1000); return new TimeValue(parse(lowerSValue, 1), TimeUnit.SECONDS);
} else if (lowerSValue.endsWith("m")) { } else if (lowerSValue.endsWith("m")) {
millis = parse(lowerSValue, 1, 60 * 1000); return new TimeValue(parse(lowerSValue, 1), TimeUnit.MINUTES);
} else if (lowerSValue.endsWith("h")) { } 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")) { } else if (lowerSValue.endsWith("d")) {
millis = parse(lowerSValue, 1, 24 * 60 * 60 * 1000); return new TimeValue(parse(lowerSValue, 1), TimeUnit.DAYS);
} else if (lowerSValue.endsWith("w")) { } else if (lowerSValue.matches("-0*1")) {
millis = parse(lowerSValue, 1, 7 * 24 * 60 * 60 * 1000); return TimeValue.MINUS_ONE;
} else if (lowerSValue.equals("-1")) { } else if (lowerSValue.matches("0+")) {
// Allow this special value to be unit-less: return TimeValue.ZERO;
millis = -1;
} else if (lowerSValue.equals("0")) {
// Allow this special value to be unit-less:
millis = 0;
} else { } else {
// Missing units: // 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) { } 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) { private static long parse(String s, int suffixLength) {
return (long) (Double.parseDouble(s.substring(0, s.length() - suffixLength)) * scale); return Long.parseLong(s.substring(0, s.length() - suffixLength).trim());
} }
static final long C0 = 1L; private static final long C0 = 1L;
static final long C1 = C0 * 1000L; private static final long C1 = C0 * 1000L;
static final long C2 = C1 * 1000L; private static final long C2 = C1 * 1000L;
static final long C3 = C2 * 1000L; private static final long C3 = C2 * 1000L;
static final long C4 = C3 * 60L; private static final long C4 = C3 * 60L;
static final long C5 = C4 * 60L; private static final long C5 = C4 * 60L;
static final long C6 = C5 * 24L; private static final long C6 = C5 * 24L;
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {

View File

@ -685,7 +685,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> imp
if (source.profile()) { if (source.profile()) {
context.setProfilers(new Profilers(context.searcher())); context.setProfilers(new Profilers(context.searcher()));
} }
context.timeoutInMillis(source.timeoutInMillis()); context.timeout(source.timeout());
context.terminateAfter(source.terminateAfter()); context.terminateAfter(source.terminateAfter());
if (source.aggregations() != null) { if (source.aggregations() != null) {
try { try {

View File

@ -143,7 +143,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
private Float minScore; private Float minScore;
private long timeoutInMillis = -1; private TimeValue timeout = null;
private int terminateAfter = SearchContext.DEFAULT_TERMINATE_AFTER; private int terminateAfter = SearchContext.DEFAULT_TERMINATE_AFTER;
private List<String> fieldNames; private List<String> fieldNames;
@ -241,7 +241,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
} }
suggestBuilder = in.readOptionalWriteable(SuggestBuilder::new); suggestBuilder = in.readOptionalWriteable(SuggestBuilder::new);
terminateAfter = in.readVInt(); terminateAfter = in.readVInt();
timeoutInMillis = in.readLong(); timeout = in.readOptionalWriteable(TimeValue::new);
trackScores = in.readBoolean(); trackScores = in.readBoolean();
version = in.readOptionalBoolean(); version = in.readOptionalBoolean();
ext = in.readOptionalBytesReference(); ext = in.readOptionalBytesReference();
@ -320,7 +320,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
} }
out.writeOptionalWriteable(suggestBuilder); out.writeOptionalWriteable(suggestBuilder);
out.writeVInt(terminateAfter); out.writeVInt(terminateAfter);
out.writeLong(timeoutInMillis); out.writeOptionalWriteable(timeout);
out.writeBoolean(trackScores); out.writeBoolean(trackScores);
out.writeOptionalBoolean(version); out.writeOptionalBoolean(version);
out.writeOptionalBytesReference(ext); out.writeOptionalBytesReference(ext);
@ -446,15 +446,15 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
* An optional timeout to control how long search is allowed to take. * An optional timeout to control how long search is allowed to take.
*/ */
public SearchSourceBuilder timeout(TimeValue timeout) { public SearchSourceBuilder timeout(TimeValue timeout) {
this.timeoutInMillis = timeout.millis(); this.timeout = timeout;
return this; return this;
} }
/** /**
* Gets the timeout to control how long search is allowed to take. * Gets the timeout to control how long search is allowed to take.
*/ */
public long timeoutInMillis() { public TimeValue timeout() {
return timeoutInMillis; return timeout;
} }
/** /**
@ -928,7 +928,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
rewrittenBuilder.stats = stats; rewrittenBuilder.stats = stats;
rewrittenBuilder.suggestBuilder = suggestBuilder; rewrittenBuilder.suggestBuilder = suggestBuilder;
rewrittenBuilder.terminateAfter = terminateAfter; rewrittenBuilder.terminateAfter = terminateAfter;
rewrittenBuilder.timeoutInMillis = timeoutInMillis; rewrittenBuilder.timeout = timeout;
rewrittenBuilder.trackScores = trackScores; rewrittenBuilder.trackScores = trackScores;
rewrittenBuilder.version = version; rewrittenBuilder.version = version;
return rewrittenBuilder; return rewrittenBuilder;
@ -958,7 +958,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
} else if (context.getParseFieldMatcher().match(currentFieldName, SIZE_FIELD)) { } else if (context.getParseFieldMatcher().match(currentFieldName, SIZE_FIELD)) {
size = parser.intValue(); size = parser.intValue();
} else if (context.getParseFieldMatcher().match(currentFieldName, TIMEOUT_FIELD)) { } else if (context.getParseFieldMatcher().match(currentFieldName, TIMEOUT_FIELD)) {
timeoutInMillis = TimeValue.parseTimeValue(parser.text(), null, TIMEOUT_FIELD.getPreferredName()).millis(); timeout = TimeValue.parseTimeValue(parser.text(), null, TIMEOUT_FIELD.getPreferredName());
} else if (context.getParseFieldMatcher().match(currentFieldName, TERMINATE_AFTER_FIELD)) { } else if (context.getParseFieldMatcher().match(currentFieldName, TERMINATE_AFTER_FIELD)) {
terminateAfter = parser.intValue(); terminateAfter = parser.intValue();
} else if (context.getParseFieldMatcher().match(currentFieldName, MIN_SCORE_FIELD)) { } else if (context.getParseFieldMatcher().match(currentFieldName, MIN_SCORE_FIELD)) {
@ -1095,8 +1095,8 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
builder.field(SIZE_FIELD.getPreferredName(), size); builder.field(SIZE_FIELD.getPreferredName(), size);
} }
if (timeoutInMillis != -1) { if (timeout != null && !timeout.equals(TimeValue.MINUS_ONE)) {
builder.field(TIMEOUT_FIELD.getPreferredName(), TimeValue.timeValueMillis(timeoutInMillis).toString()); builder.field(TIMEOUT_FIELD.getPreferredName(), timeout.getStringRep());
} }
if (terminateAfter != SearchContext.DEFAULT_TERMINATE_AFTER) { if (terminateAfter != SearchContext.DEFAULT_TERMINATE_AFTER) {
@ -1341,7 +1341,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
public int hashCode() { public int hashCode() {
return Objects.hash(aggregations, explain, fetchSourceContext, fieldDataFields, fieldNames, from, return Objects.hash(aggregations, explain, fetchSourceContext, fieldDataFields, fieldNames, from,
highlightBuilder, indexBoost, minScore, postQueryBuilder, queryBuilder, rescoreBuilders, scriptFields, highlightBuilder, indexBoost, minScore, postQueryBuilder, queryBuilder, rescoreBuilders, scriptFields,
size, sorts, searchAfterBuilder, sliceBuilder, stats, suggestBuilder, terminateAfter, timeoutInMillis, trackScores, version, profile); size, sorts, searchAfterBuilder, sliceBuilder, stats, suggestBuilder, terminateAfter, timeout, trackScores, version, profile);
} }
@Override @Override
@ -1373,7 +1373,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ
&& Objects.equals(stats, other.stats) && Objects.equals(stats, other.stats)
&& Objects.equals(suggestBuilder, other.suggestBuilder) && Objects.equals(suggestBuilder, other.suggestBuilder)
&& Objects.equals(terminateAfter, other.terminateAfter) && Objects.equals(terminateAfter, other.terminateAfter)
&& Objects.equals(timeoutInMillis, other.timeoutInMillis) && Objects.equals(timeout, other.timeout)
&& Objects.equals(trackScores, other.trackScores) && Objects.equals(trackScores, other.trackScores)
&& Objects.equals(version, other.version) && Objects.equals(version, other.version)
&& Objects.equals(profile, other.profile); && Objects.equals(profile, other.profile);

View File

@ -24,8 +24,8 @@ import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Collector; import org.apache.lucene.search.Collector;
import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.FieldDoc; import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Counter; import org.apache.lucene.util.Counter;
import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.search.SearchType;
@ -99,8 +99,7 @@ public class DefaultSearchContext extends SearchContext {
private final QuerySearchResult queryResult; private final QuerySearchResult queryResult;
private final FetchSearchResult fetchResult; private final FetchSearchResult fetchResult;
private float queryBoost = 1.0f; private float queryBoost = 1.0f;
// timeout in millis private TimeValue timeout;
private long timeoutInMillis;
// terminate after count // terminate after count
private int terminateAfter = DEFAULT_TERMINATE_AFTER; private int terminateAfter = DEFAULT_TERMINATE_AFTER;
private List<String> groupStats; private List<String> groupStats;
@ -174,7 +173,7 @@ public class DefaultSearchContext extends SearchContext {
this.indexService = indexService; this.indexService = indexService;
this.searcher = new ContextIndexSearcher(engineSearcher, indexService.cache().query(), indexShard.getQueryCachingPolicy()); this.searcher = new ContextIndexSearcher(engineSearcher, indexService.cache().query(), indexShard.getQueryCachingPolicy());
this.timeEstimateCounter = timeEstimateCounter; this.timeEstimateCounter = timeEstimateCounter;
this.timeoutInMillis = timeout.millis(); this.timeout = timeout;
queryShardContext = indexService.newQueryShardContext(searcher.getIndexReader()); queryShardContext = indexService.newQueryShardContext(searcher.getIndexReader());
queryShardContext.setTypes(request.types()); queryShardContext.setTypes(request.types());
} }
@ -512,13 +511,13 @@ public class DefaultSearchContext extends SearchContext {
} }
@Override @Override
public long timeoutInMillis() { public TimeValue timeout() {
return timeoutInMillis; return timeout;
} }
@Override @Override
public void timeoutInMillis(long timeoutInMillis) { public void timeout(TimeValue timeout) {
this.timeoutInMillis = timeoutInMillis; this.timeout = timeout;
} }
@Override @Override

View File

@ -25,6 +25,7 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.util.Counter; import org.apache.lucene.util.Counter;
import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.cache.bitset.BitsetFilterCache; import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
@ -264,13 +265,13 @@ public abstract class FilteredSearchContext extends SearchContext {
} }
@Override @Override
public long timeoutInMillis() { public TimeValue timeout() {
return in.timeoutInMillis(); return in.timeout();
} }
@Override @Override
public void timeoutInMillis(long timeoutInMillis) { public void timeout(TimeValue timeout) {
in.timeoutInMillis(timeoutInMillis); in.timeout(timeout);
} }
@Override @Override

View File

@ -28,6 +28,7 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.lease.Releasable; import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.lease.Releasables; import org.elasticsearch.common.lease.Releasables;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.util.iterable.Iterables; import org.elasticsearch.common.util.iterable.Iterables;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
@ -226,9 +227,9 @@ public abstract class SearchContext implements Releasable {
public abstract IndexFieldDataService fieldData(); public abstract IndexFieldDataService fieldData();
public abstract long timeoutInMillis(); public abstract TimeValue timeout();
public abstract void timeoutInMillis(long timeoutInMillis); public abstract void timeout(TimeValue timeout);
public abstract int terminateAfter(); public abstract int terminateAfter();

View File

@ -20,6 +20,7 @@ package org.elasticsearch.search.internal;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.util.Counter; import org.apache.lucene.util.Counter;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.search.aggregations.SearchContextAggregations; import org.elasticsearch.search.aggregations.SearchContextAggregations;
import org.elasticsearch.search.fetch.FetchSearchResult; import org.elasticsearch.search.fetch.FetchSearchResult;
@ -155,7 +156,7 @@ public class SubSearchContext extends FilteredSearchContext {
} }
@Override @Override
public void timeoutInMillis(long timeoutInMillis) { public void timeout(TimeValue timeout) {
throw new UnsupportedOperationException("Not supported"); throw new UnsupportedOperationException("Not supported");
} }

View File

@ -349,12 +349,12 @@ public class QueryPhase implements SearchPhase {
} }
} }
final boolean timeoutSet = searchContext.timeoutInMillis() != SearchService.NO_TIMEOUT.millis(); final boolean timeoutSet = searchContext.timeout() != null && !searchContext.timeout().equals(SearchService.NO_TIMEOUT);
if (timeoutSet && collector != null) { // collector might be null if no collection is actually needed if (timeoutSet && collector != null) { // collector might be null if no collection is actually needed
final Collector child = collector; final Collector child = collector;
// TODO: change to use our own counter that uses the scheduler in ThreadPool // TODO: change to use our own counter that uses the scheduler in ThreadPool
// throws TimeLimitingCollector.TimeExceededException when timeout has reached // throws TimeLimitingCollector.TimeExceededException when timeout has reached
collector = Lucene.wrapTimeLimitingCollector(collector, searchContext.timeEstimateCounter(), searchContext.timeoutInMillis()); collector = Lucene.wrapTimeLimitingCollector(collector, searchContext.timeEstimateCounter(), searchContext.timeout().millis());
if (doProfile) { if (doProfile) {
collector = new InternalProfileCollector(collector, CollectorResult.REASON_SEARCH_TIMEOUT, collector = new InternalProfileCollector(collector, CollectorResult.REASON_SEARCH_TIMEOUT,
Collections.singletonList((InternalProfileCollector) child)); Collections.singletonList((InternalProfileCollector) child));

View File

@ -263,7 +263,7 @@ public class ClusterSettingsIT extends ESIntegTestCase {
.get(); .get();
fail("bogus value"); fail("bogus value");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [discovery.zen.publish_timeout] with value [whatever] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [discovery.zen.publish_timeout] with value [whatever] as a time value: unit is missing or unrecognized");
} }
assertThat(discoverySettings.getPublishTimeout().seconds(), equalTo(1L)); assertThat(discoverySettings.getPublishTimeout().seconds(), equalTo(1L));

View File

@ -85,9 +85,6 @@ public class TimeValueTests extends ESTestCase {
assertEquals(new TimeValue(10, TimeUnit.SECONDS), assertEquals(new TimeValue(10, TimeUnit.SECONDS),
TimeValue.parseTimeValue("10S", null, "test")); TimeValue.parseTimeValue("10S", null, "test"));
assertEquals(new TimeValue(100, TimeUnit.MILLISECONDS),
TimeValue.parseTimeValue("0.1s", null, "test"));
assertEquals(new TimeValue(10, TimeUnit.MINUTES), assertEquals(new TimeValue(10, TimeUnit.MINUTES),
TimeValue.parseTimeValue("10 m", null, "test")); TimeValue.parseTimeValue("10 m", null, "test"));
assertEquals(new TimeValue(10, TimeUnit.MINUTES), assertEquals(new TimeValue(10, TimeUnit.MINUTES),
@ -115,14 +112,17 @@ public class TimeValueTests extends ESTestCase {
assertEquals(new TimeValue(10, TimeUnit.DAYS), assertEquals(new TimeValue(10, TimeUnit.DAYS),
TimeValue.parseTimeValue("10D", null, "test")); TimeValue.parseTimeValue("10D", null, "test"));
assertEquals(new TimeValue(70, TimeUnit.DAYS), final int length = randomIntBetween(0, 8);
TimeValue.parseTimeValue("10 w", null, "test")); final String zeros = new String(new char[length]).replace('\0', '0');
assertEquals(new TimeValue(70, TimeUnit.DAYS), assertTrue(TimeValue.parseTimeValue("-" + zeros + "1", null, "test") == TimeValue.MINUS_ONE);
TimeValue.parseTimeValue("10w", null, "test")); assertTrue(TimeValue.parseTimeValue(zeros + "0", null, "test") == TimeValue.ZERO);
assertEquals(new TimeValue(70, TimeUnit.DAYS), }
TimeValue.parseTimeValue("10 W", null, "test"));
assertEquals(new TimeValue(70, TimeUnit.DAYS), public void testRoundTrip() {
TimeValue.parseTimeValue("10W", null, "test")); final String s = randomTimeValue();
assertThat(TimeValue.parseTimeValue(s, null, "test").getStringRep(), equalTo(s));
final TimeValue t = new TimeValue(randomIntBetween(1, 128), randomFrom(TimeUnit.values()));
assertThat(TimeValue.parseTimeValue(t.getStringRep(), null, "test"), equalTo(t));
} }
private void assertEqualityAfterSerialize(TimeValue value, int expectedSize) throws IOException { private void assertEqualityAfterSerialize(TimeValue value, int expectedSize) throws IOException {
@ -134,13 +134,20 @@ public class TimeValueTests extends ESTestCase {
TimeValue inValue = new TimeValue(in); TimeValue inValue = new TimeValue(in);
assertThat(inValue, equalTo(value)); assertThat(inValue, equalTo(value));
assertThat(inValue.duration(), equalTo(value.duration()));
assertThat(inValue.timeUnit(), equalTo(value.timeUnit()));
} }
public void testSerialize() throws Exception { public void testSerialize() throws Exception {
assertEqualityAfterSerialize(new TimeValue(100, TimeUnit.DAYS), 8); assertEqualityAfterSerialize(new TimeValue(100, TimeUnit.DAYS), 3);
assertEqualityAfterSerialize(timeValueNanos(-1), 1); assertEqualityAfterSerialize(timeValueNanos(-1), 2);
assertEqualityAfterSerialize(timeValueNanos(1), 1); assertEqualityAfterSerialize(timeValueNanos(1), 2);
assertEqualityAfterSerialize(timeValueSeconds(30), 6); assertEqualityAfterSerialize(timeValueSeconds(30), 2);
final TimeValue timeValue = new TimeValue(randomIntBetween(0, 1024), randomFrom(TimeUnit.values()));
BytesStreamOutput out = new BytesStreamOutput();
out.writeZLong(timeValue.duration());
assertEqualityAfterSerialize(timeValue, 1 + out.bytes().length());
} }
public void testFailOnUnknownUnits() { public void testFailOnUnknownUnits() {
@ -148,7 +155,7 @@ public class TimeValueTests extends ESTestCase {
TimeValue.parseTimeValue("23tw", null, "test"); TimeValue.parseTimeValue("23tw", null, "test");
fail("Expected ElasticsearchParseException"); fail("Expected ElasticsearchParseException");
} catch (ElasticsearchParseException e) { } catch (ElasticsearchParseException e) {
assertThat(e.getMessage(), containsString("Failed to parse")); assertThat(e.getMessage(), containsString("failed to parse"));
} }
} }
@ -157,7 +164,7 @@ public class TimeValueTests extends ESTestCase {
TimeValue.parseTimeValue("42", null, "test"); TimeValue.parseTimeValue("42", null, "test");
fail("Expected ElasticsearchParseException"); fail("Expected ElasticsearchParseException");
} catch (ElasticsearchParseException e) { } catch (ElasticsearchParseException e) {
assertThat(e.getMessage(), containsString("Failed to parse")); assertThat(e.getMessage(), containsString("failed to parse"));
} }
} }
@ -166,7 +173,7 @@ public class TimeValueTests extends ESTestCase {
TimeValue.parseTimeValue("42ms.", null, "test"); TimeValue.parseTimeValue("42ms.", null, "test");
fail("Expected ElasticsearchParseException"); fail("Expected ElasticsearchParseException");
} catch (ElasticsearchParseException e) { } catch (ElasticsearchParseException e) {
assertThat(e.getMessage(), containsString("Failed to parse")); assertThat(e.getMessage(), containsString("failed to parse"));
} }
} }

View File

@ -176,28 +176,28 @@ public class IndexingSlowLogTests extends ESTestCase {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_TRACE_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.indexing.slowlog.threshold.index.trace] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.indexing.slowlog.threshold.index.trace] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_DEBUG_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.indexing.slowlog.threshold.index.debug] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.indexing.slowlog.threshold.index.debug] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_INFO_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.indexing.slowlog.threshold.index.info] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.indexing.slowlog.threshold.index.info] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(IndexingSlowLog.INDEX_INDEXING_SLOWLOG_THRESHOLD_INDEX_WARN_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.indexing.slowlog.threshold.index.warn] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.indexing.slowlog.threshold.index.warn] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
} }

View File

@ -249,28 +249,28 @@ public class SearchSlowLogTests extends ESSingleNodeTestCase {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_TRACE_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.query.trace] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.query.trace] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_DEBUG_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.query.debug] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.query.debug] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_INFO_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.query.info] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.query.info] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_QUERY_WARN_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.query.warn] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.query.warn] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
} }
@ -320,28 +320,28 @@ public class SearchSlowLogTests extends ESSingleNodeTestCase {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_TRACE_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.fetch.trace] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.fetch.trace] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_DEBUG_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.fetch.debug] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.fetch.debug] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_INFO_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.fetch.info] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.fetch.info] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
try { try {
settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN_SETTING.getKey(), "NOT A TIME VALUE").build())); settings.updateIndexMetaData(newIndexMeta("index", Settings.builder().put(SearchSlowLog.INDEX_SEARCH_SLOWLOG_THRESHOLD_FETCH_WARN_SETTING.getKey(), "NOT A TIME VALUE").build()));
fail(); fail();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
assertEquals(ex.getMessage(), "Failed to parse setting [index.search.slowlog.threshold.fetch.warn] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized"); assertEquals(ex.getMessage(), "failed to parse setting [index.search.slowlog.threshold.fetch.warn] with value [NOT A TIME VALUE] as a time value: unit is missing or unrecognized");
} }
} }

View File

@ -139,7 +139,7 @@ public class TTLMappingTests extends ESSingleNodeTestCase {
String updatedMapping = XContentFactory.jsonBuilder().startObject().startObject("type") String updatedMapping = XContentFactory.jsonBuilder().startObject().startObject("type")
.startObject("_ttl") .startObject("_ttl")
.field("default", "1w") .field("default", "7d")
.endObject() .endObject()
.startObject("properties").field("field").startObject().field("type", "text").endObject().endObject() .startObject("properties").field("field").startObject().field("type", "text").endObject().endObject()
.endObject().endObject().string(); .endObject().endObject().string();

View File

@ -140,7 +140,7 @@ public class PipelineExecutionServiceTests extends ESTestCase {
IngestDocument ingestDocument = (IngestDocument) invocationOnMock.getArguments()[0]; IngestDocument ingestDocument = (IngestDocument) invocationOnMock.getArguments()[0];
for (IngestDocument.MetaData metaData : IngestDocument.MetaData.values()) { for (IngestDocument.MetaData metaData : IngestDocument.MetaData.values()) {
if (metaData == IngestDocument.MetaData.TTL) { if (metaData == IngestDocument.MetaData.TTL) {
ingestDocument.setFieldValue(IngestDocument.MetaData.TTL.getFieldName(), "5w"); ingestDocument.setFieldValue(IngestDocument.MetaData.TTL.getFieldName(), "35d");
} else { } else {
ingestDocument.setFieldValue(metaData.getFieldName(), "update" + metaData.getFieldName()); ingestDocument.setFieldValue(metaData.getFieldName(), "update" + metaData.getFieldName());
} }

View File

@ -86,7 +86,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import static org.elasticsearch.test.ClusterServiceUtils.createClusterService; import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
import static org.elasticsearch.test.ClusterServiceUtils.setState; import static org.elasticsearch.test.ClusterServiceUtils.setState;
@ -208,7 +207,7 @@ public class SearchSourceBuilderTests extends ESTestCase {
builder.minScore(randomFloat() * 1000); builder.minScore(randomFloat() * 1000);
} }
if (randomBoolean()) { if (randomBoolean()) {
builder.timeout(new TimeValue(randomIntBetween(1, 100), randomFrom(TimeUnit.values()))); builder.timeout(TimeValue.parseTimeValue(randomTimeValue(), null, "timeout"));
} }
if (randomBoolean()) { if (randomBoolean()) {
builder.terminateAfter(randomIntBetween(1, 100000)); builder.terminateAfter(randomIntBetween(1, 100000));
@ -456,7 +455,7 @@ public class SearchSourceBuilderTests extends ESTestCase {
public void testEqualsAndHashcode() throws IOException { public void testEqualsAndHashcode() throws IOException {
SearchSourceBuilder firstBuilder = createSearchSourceBuilder(); SearchSourceBuilder firstBuilder = createSearchSourceBuilder();
assertFalse("source builder is equal to null", firstBuilder.equals(null)); assertNotNull("source builder is equal to null", firstBuilder);
assertFalse("source builder is equal to incompatible type", firstBuilder.equals("")); assertFalse("source builder is equal to incompatible type", firstBuilder.equals(""));
assertTrue("source builder is not equal to self", firstBuilder.equals(firstBuilder)); assertTrue("source builder is not equal to self", firstBuilder.equals(firstBuilder));
assertThat("same source builder's hashcode returns different values if called multiple times", firstBuilder.hashCode(), assertThat("same source builder's hashcode returns different values if called multiple times", firstBuilder.hashCode(),
@ -601,7 +600,7 @@ public class SearchSourceBuilderTests extends ESTestCase {
final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}"; final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}";
try (XContentParser parser = XContentFactory.xContent(query).createParser(query)) { try (XContentParser parser = XContentFactory.xContent(query).createParser(query)) {
final SearchSourceBuilder builder = SearchSourceBuilder.fromXContent(createParseContext(parser), aggParsers, suggesters); final SearchSourceBuilder builder = SearchSourceBuilder.fromXContent(createParseContext(parser), aggParsers, suggesters);
assertThat(builder.timeoutInMillis(), equalTo(TimeValue.parseTimeValue(timeout, null, "timeout").millis())); assertThat(builder.timeout(), equalTo(TimeValue.parseTimeValue(timeout, null, "timeout")));
} }
} }

View File

@ -594,9 +594,9 @@ public class DecayFunctionScoreIT extends ESIntegTestCase {
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source( searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
searchSource().query( searchSource().query(
functionScoreQuery(QueryBuilders.matchAllQuery(), new FilterFunctionBuilder[]{ functionScoreQuery(QueryBuilders.matchAllQuery(), new FilterFunctionBuilder[]{
new FilterFunctionBuilder(linearDecayFunction("num1", null, "1000w")), new FilterFunctionBuilder(linearDecayFunction("num1", null, "7000d")),
new FilterFunctionBuilder(gaussDecayFunction("num1", null, "1d")), new FilterFunctionBuilder(gaussDecayFunction("num1", null, "1d")),
new FilterFunctionBuilder(exponentialDecayFunction("num1", null, "1000w")) new FilterFunctionBuilder(exponentialDecayFunction("num1", null, "7000d"))
}).scoreMode(FiltersFunctionScoreQuery.ScoreMode.MULTIPLY)))); }).scoreMode(FiltersFunctionScoreQuery.ScoreMode.MULTIPLY))));
SearchResponse sr = response.actionGet(); SearchResponse sr = response.actionGet();

View File

@ -220,7 +220,7 @@ public class SimpleVersioningIT extends ESIntegTestCase {
fail("did not hit expected exception"); fail("did not hit expected exception");
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
// expected // expected
assertTrue(iae.getMessage().contains("Failed to parse setting [index.gc_deletes] with value [42] as a time value: unit is missing or unrecognized")); assertTrue(iae.getMessage().contains("failed to parse setting [index.gc_deletes] with value [42] as a time value: unit is missing or unrecognized"));
} }
} }

View File

@ -286,3 +286,11 @@ The setting `bootstrap.mlockall` has been renamed to
The default setting `include_global_state` for restoring snapshots has been The default setting `include_global_state` for restoring snapshots has been
changed from `true` to `false`. It has not been changed for taking snapshots and changed from `true` to `false`. It has not been changed for taking snapshots and
still defaults to `true` in that case. still defaults to `true` in that case.
==== Time value parsing
The unit 'w' representing weeks is no longer supported.
Fractional time values (e.g., 0.5s) are no longer supported. For
example, this means when setting timeouts "0.5s" will be rejected and
should instead be input as "500ms".

View File

@ -413,7 +413,7 @@ public abstract class ESTestCase extends LuceneTestCase {
return generateRandomStringArray(maxArraySize, maxStringSize, allowNull, true); return generateRandomStringArray(maxArraySize, maxStringSize, allowNull, true);
} }
private static String[] TIME_SUFFIXES = new String[]{"d", "H", "ms", "s", "S", "w"}; private static String[] TIME_SUFFIXES = new String[]{"d", "h", "ms", "s", "m"};
private static String randomTimeValue(int lower, int upper) { private static String randomTimeValue(int lower, int upper) {
return randomIntBetween(lower, upper) + randomFrom(TIME_SUFFIXES); return randomIntBetween(lower, upper) + randomFrom(TIME_SUFFIXES);

View File

@ -410,12 +410,12 @@ public final class InternalTestCluster extends TestCluster {
builder.put("cache.recycler.page.type", RandomPicks.randomFrom(random, PageCacheRecycler.Type.values())); builder.put("cache.recycler.page.type", RandomPicks.randomFrom(random, PageCacheRecycler.Type.values()));
} }
if (random.nextInt(10) == 0) { // 10% of the nodes have a very frequent check interval if (random.nextInt(10) == 0) { // 10% of the nodes have a very frequent check interval
builder.put(SearchService.KEEPALIVE_INTERVAL_SETTING.getKey(), TimeValue.timeValueMillis(10 + random.nextInt(2000))); builder.put(SearchService.KEEPALIVE_INTERVAL_SETTING.getKey(), TimeValue.timeValueMillis(10 + random.nextInt(2000)).getStringRep());
} else if (random.nextInt(10) != 0) { // 90% of the time - 10% of the time we don't set anything } else if (random.nextInt(10) != 0) { // 90% of the time - 10% of the time we don't set anything
builder.put(SearchService.KEEPALIVE_INTERVAL_SETTING.getKey(), TimeValue.timeValueSeconds(10 + random.nextInt(5 * 60))); builder.put(SearchService.KEEPALIVE_INTERVAL_SETTING.getKey(), TimeValue.timeValueSeconds(10 + random.nextInt(5 * 60)).getStringRep());
} }
if (random.nextBoolean()) { // sometimes set a if (random.nextBoolean()) { // sometimes set a
builder.put(SearchService.DEFAULT_KEEPALIVE_SETTING.getKey(), TimeValue.timeValueSeconds(100 + random.nextInt(5 * 60))); builder.put(SearchService.DEFAULT_KEEPALIVE_SETTING.getKey(), TimeValue.timeValueSeconds(100 + random.nextInt(5 * 60)).getStringRep());
} }
builder.put(EsExecutors.PROCESSORS_SETTING.getKey(), 1 + random.nextInt(3)); builder.put(EsExecutors.PROCESSORS_SETTING.getKey(), 1 + random.nextInt(3));
@ -469,7 +469,7 @@ public final class InternalTestCluster extends TestCluster {
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), RandomInts.randomIntBetween(random, 0, 2000)); builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING.getKey(), RandomInts.randomIntBetween(random, 0, 2000));
} }
if (random.nextBoolean()) { if (random.nextBoolean()) {
builder.put(ScriptService.SCRIPT_CACHE_EXPIRE_SETTING.getKey(), TimeValue.timeValueMillis(RandomInts.randomIntBetween(random, 750, 10000000))); builder.put(ScriptService.SCRIPT_CACHE_EXPIRE_SETTING.getKey(), TimeValue.timeValueMillis(RandomInts.randomIntBetween(random, 750, 10000000)).getStringRep());
} }
return builder.build(); return builder.build();

View File

@ -28,6 +28,7 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.util.Counter; import org.apache.lucene.util.Counter;
import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.index.IndexService; import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.analysis.AnalysisService; import org.elasticsearch.index.analysis.AnalysisService;
@ -311,12 +312,12 @@ public class TestSearchContext extends SearchContext {
} }
@Override @Override
public long timeoutInMillis() { public TimeValue timeout() {
return 0; return TimeValue.ZERO;
} }
@Override @Override
public void timeoutInMillis(long timeoutInMillis) { public void timeout(TimeValue timeout) {
} }
@Override @Override