-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Supports additional query timing types for profiling plugin query components #17146
base: 2.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ | |
package org.opensearch.search; | ||
|
||
import org.apache.lucene.search.BooleanQuery; | ||
import org.apache.lucene.search.Query; | ||
import org.opensearch.common.NamedRegistry; | ||
import org.opensearch.common.Nullable; | ||
import org.opensearch.common.geo.GeoShapeType; | ||
|
@@ -300,9 +301,11 @@ | |
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
|
@@ -335,6 +338,7 @@ public class SearchModule { | |
private final SearchPlugin.ExecutorServiceProvider indexSearcherExecutorProvider; | ||
|
||
private final Collection<ConcurrentSearchRequestDecider.Factory> concurrentSearchDeciderFactories; | ||
private final Map<Class<? extends Query>, Set<String>> profilerTimingsPerQuery = new HashMap<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not convinced that using Lucene There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thats a good point. The problem is to getting the profile breakdown is completely dependent on Query. To make it context aware and not have unnecessary timing in response, I chose the key as Query. Since the breakdown is obtained through any suggestions instead of |
||
|
||
/** | ||
* Constructs a new SearchModule object | ||
|
@@ -361,12 +365,19 @@ public SearchModule(Settings settings, List<SearchPlugin> plugins) { | |
registerSearchExts(plugins); | ||
registerShapes(); | ||
registerIntervalsSourceProviders(); | ||
registerProfilerTimingTypes(plugins); | ||
queryPhaseSearcher = registerQueryPhaseSearcher(plugins); | ||
indexSearcherExecutorProvider = registerIndexSearcherExecutorProvider(plugins); | ||
namedWriteables.addAll(SortValue.namedWriteables()); | ||
concurrentSearchDeciderFactories = registerConcurrentSearchDeciderFactories(plugins); | ||
} | ||
|
||
private void registerProfilerTimingTypes(List<SearchPlugin> plugins) { | ||
for (SearchPlugin plugin : plugins) { | ||
profilerTimingsPerQuery.putAll(plugin.registerProfilerTimingTypes()); | ||
} | ||
} | ||
|
||
private Collection<ConcurrentSearchRequestDecider.Factory> registerConcurrentSearchDeciderFactories(List<SearchPlugin> plugins) { | ||
List<ConcurrentSearchRequestDecider.Factory> concurrentSearchDeciderFactories = new ArrayList<>(); | ||
for (SearchPlugin plugin : plugins) { | ||
|
@@ -383,6 +394,10 @@ public Collection<ConcurrentSearchRequestDecider.Factory> getConcurrentSearchReq | |
return concurrentSearchDeciderFactories; | ||
} | ||
|
||
public Map<Class<? extends Query>, Set<String>> getQueryProfilerTimingTypes() { | ||
return profilerTimingsPerQuery; | ||
} | ||
|
||
public List<NamedWriteableRegistry.Entry> getNamedWriteables() { | ||
return namedWriteables; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,9 +32,16 @@ | |
|
||
package org.opensearch.search.profile; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Locale; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.TreeMap; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import static java.util.Collections.emptyMap; | ||
|
||
|
@@ -50,37 +57,41 @@ public abstract class AbstractProfileBreakdown<T extends Enum<T>> { | |
/** | ||
* The accumulated timings for this query node | ||
*/ | ||
protected final Timer[] timings; | ||
protected final T[] timingTypes; | ||
protected final Map<String, Timer> timings; | ||
public static final String TIMING_TYPE_COUNT_SUFFIX = "_count"; | ||
public static final String TIMING_TYPE_START_TIME_SUFFIX = "_start_time"; | ||
|
||
/** Sole constructor. */ | ||
public AbstractProfileBreakdown(Class<T> clazz) { | ||
this.timingTypes = clazz.getEnumConstants(); | ||
timings = new Timer[timingTypes.length]; | ||
for (int i = 0; i < timings.length; ++i) { | ||
timings[i] = new Timer(); | ||
} | ||
public AbstractProfileBreakdown(final Class<T> timingType, final Set<String> additionalProfilerTimings) { | ||
Set<String> additionalTimings = additionalProfilerTimings == null ? Collections.emptySet() : additionalProfilerTimings; | ||
timings = Stream.of(Arrays.stream(timingType.getEnumConstants()).map(Enum::name), additionalTimings.stream()) | ||
.flatMap(Function.identity()) | ||
.filter(Objects::nonNull) | ||
.map(val -> val.toLowerCase(Locale.ROOT)) | ||
.collect(Collectors.toUnmodifiableMap(value -> value, value -> new Timer(), (a, b) -> a)); | ||
} | ||
|
||
public Timer getTimer(T timing) { | ||
return timings[timing.ordinal()]; | ||
return timings.get(timing.name().toLowerCase(Locale.ROOT)); | ||
} | ||
|
||
public Timer getTimer(String timingName) { | ||
return timings.get(timingName.toLowerCase(Locale.ROOT)); | ||
} | ||
|
||
public void setTimer(T timing, Timer timer) { | ||
timings[timing.ordinal()] = timer; | ||
timings.put(timing.name().toLowerCase(Locale.ROOT), timer); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, didn't realize I made it unmodifiable. I will make the map modifiable |
||
} | ||
|
||
/** | ||
* Build a timing count breakdown for current instance | ||
*/ | ||
public Map<String, Long> toBreakdownMap() { | ||
Map<String, Long> map = new HashMap<>(this.timings.length * 3); | ||
for (T timingType : this.timingTypes) { | ||
map.put(timingType.toString(), this.timings[timingType.ordinal()].getApproximateTiming()); | ||
map.put(timingType + TIMING_TYPE_COUNT_SUFFIX, this.timings[timingType.ordinal()].getCount()); | ||
map.put(timingType + TIMING_TYPE_START_TIME_SUFFIX, this.timings[timingType.ordinal()].getEarliestTimerStartTime()); | ||
Map<String, Long> map = new TreeMap<>(); | ||
for (String timingType : this.timings.keySet()) { | ||
map.put(timingType, this.timings.get(timingType).getApproximateTiming()); | ||
map.put(timingType + TIMING_TYPE_COUNT_SUFFIX, this.timings.get(timingType).getCount()); | ||
map.put(timingType + TIMING_TYPE_START_TIME_SUFFIX, this.timings.get(timingType).getEarliestTimerStartTime()); | ||
Comment on lines
+91
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be an iteration over There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will change to entrySets instead |
||
} | ||
return Collections.unmodifiableMap(map); | ||
} | ||
|
@@ -94,8 +105,8 @@ public Map<String, Object> toDebugMap() { | |
|
||
public long toNodeTime() { | ||
long total = 0; | ||
for (T timingType : timingTypes) { | ||
total += timings[timingType.ordinal()].getApproximateTiming(); | ||
for (String timingType : timings.keySet()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should also be an iteration over There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will change to entrySets instead |
||
total += timings.get(timingType).getApproximateTiming(); | ||
} | ||
return total; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to remove this