summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2020-06-30 21:54:47 +0200
committerGitHub <noreply@github.com>2020-06-30 21:54:47 +0200
commitaac7958354aab414dc036a82dcf493a749d6f1d5 (patch)
tree52a7b8bd9feb881aa28ed40a02e7c86561113538
parent0c0ec3379aa3cc4295bedae70cb51eb362731b6d (diff)
parent89a7efc22cf9c8362ab96cd9b72c8910c2446caa (diff)
Merge pull request #13757 from vespa-engine/bratseth/query-profile-optimization
Bratseth/query profile optimization
-rw-r--r--container-search/abi-spec.json8
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java46
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java57
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java54
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java21
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java2
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java35
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java29
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java8
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueWithSource.java36
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java1
13 files changed, 81 insertions, 218 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index ba52826cd3f..6a191248e13 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -5732,7 +5732,6 @@
"public final java.util.Map listValues(java.lang.String, java.util.Map)",
"public final java.util.Map listValues(com.yahoo.processing.request.CompoundName, java.util.Map)",
"public java.util.Map listValues(com.yahoo.processing.request.CompoundName, java.util.Map, com.yahoo.processing.request.Properties)",
- "public java.util.Map listTypes(com.yahoo.processing.request.CompoundName, java.util.Map)",
"public final java.lang.Object get(java.lang.String)",
"public final java.lang.Object get(java.lang.String, java.util.Map)",
"public final java.lang.Object get(java.lang.String, java.lang.String[])",
@@ -6064,8 +6063,8 @@
"public"
],
"methods": [
- "public void <init>()",
"public void <init>(com.yahoo.search.query.profile.config.QueryProfilesConfig)",
+ "public void <init>()",
"public void <init>(com.yahoo.search.query.profile.types.QueryProfileTypeRegistry)",
"public final void register(com.yahoo.search.query.profile.compiled.CompiledQueryProfile)",
"public com.yahoo.search.query.profile.types.QueryProfileTypeRegistry getTypeRegistry()",
@@ -6137,9 +6136,12 @@
"public"
],
"methods": [
- "public void <init>(java.lang.Object, java.lang.String, com.yahoo.search.query.profile.DimensionValues)",
+ "public void <init>(java.lang.Object, java.lang.String, boolean, boolean, com.yahoo.search.query.profile.types.QueryProfileType, com.yahoo.search.query.profile.DimensionValues)",
"public java.lang.Object value()",
"public java.lang.String source()",
+ "public boolean isUnoverridable()",
+ "public boolean isQueryProfile()",
+ "public com.yahoo.search.query.profile.types.QueryProfileType queryProfileType()",
"public com.yahoo.search.query.profile.compiled.ValueWithSource withValue(java.lang.Object)",
"public java.util.Optional variant()",
"public java.lang.String toString()"
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java
deleted file mode 100644
index eda8bf78b68..00000000000
--- a/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.search.query.profile;
-
-import com.yahoo.processing.request.CompoundName;
-import com.yahoo.search.query.profile.types.FieldDescription;
-import com.yahoo.search.query.profile.types.QueryProfileFieldType;
-import com.yahoo.search.query.profile.types.QueryProfileType;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author bratseth
- */
-final class AllReferencesQueryProfileVisitor extends PrefixQueryProfileVisitor {
-
- /** A map of query profile types */
- private Set<CompoundName> references = new HashSet<>();
-
- public AllReferencesQueryProfileVisitor(CompoundName prefix) {
- super(prefix);
- }
-
- @Override
- public void onValue(String name, Object value,
- DimensionBinding binding,
- QueryProfile owner,
- DimensionValues variant) {}
-
- @Override
- public void onQueryProfileInsidePrefix(QueryProfile profile,
- DimensionBinding binding,
- QueryProfile owner,
- DimensionValues variant) {
- references.add(currentPrefix);
- }
-
- /** Returns the values resulting from this visiting */
- public Set<CompoundName> getResult() { return references; }
-
- /** Returns false - we are not done until we have seen all */
- public boolean isDone() { return false; }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java
deleted file mode 100644
index 6bf17d70c70..00000000000
--- a/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.search.query.profile;
-
-import com.yahoo.processing.request.CompoundName;
-import com.yahoo.search.query.profile.types.FieldDescription;
-import com.yahoo.search.query.profile.types.QueryProfileFieldType;
-import com.yahoo.search.query.profile.types.QueryProfileType;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author bratseth
- */
-final class AllTypesQueryProfileVisitor extends PrefixQueryProfileVisitor {
-
- /** A map of query profile types */
- private Map<CompoundName, QueryProfileType> types = new HashMap<>();
-
- public AllTypesQueryProfileVisitor(CompoundName prefix) {
- super(prefix);
- }
-
- @Override
- public void onValue(String name, Object value,
- DimensionBinding binding,
- QueryProfile owner,
- DimensionValues variant) {}
-
-
- @Override
- public void onQueryProfileInsidePrefix(QueryProfile profile,
- DimensionBinding binding,
- QueryProfile owner,
- DimensionValues variant) {
- if (profile.getType() != null)
- addReachableTypes(currentPrefix, profile.getType());
- }
-
- private void addReachableTypes(CompoundName name, QueryProfileType type) {
- types.putIfAbsent(name, type); // Types visited earlier has precedence: profile.type overrides profile.inherited.type
- for (FieldDescription fieldDescription : type.fields().values()) {
- if ( ! (fieldDescription.getType() instanceof QueryProfileFieldType)) continue;
- QueryProfileFieldType fieldType = (QueryProfileFieldType)fieldDescription.getType();
- if (fieldType.getQueryProfileType() !=null) {
- addReachableTypes(name.append(fieldDescription.getName()), fieldType.getQueryProfileType());
- }
- }
- }
-
- /** Returns the values resulting from this visiting */
- public Map<CompoundName, QueryProfileType> getResult() { return types; }
-
- /** Returns false - we are not done until we have seen all */
- public boolean isDone() { return false; }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java
deleted file mode 100644
index 4bae6823500..00000000000
--- a/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.search.query.profile;
-
-import com.yahoo.processing.request.CompoundName;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * @author bratseth
- */
-final class AllUnoverridableQueryProfileVisitor extends PrefixQueryProfileVisitor {
-
- /** A map of query profile types */
- private Set<CompoundName> unoverridables = new HashSet<>();
-
- public AllUnoverridableQueryProfileVisitor(CompoundName prefix) {
- super(prefix);
- }
-
- @Override
- public void onValue(String name, Object value,
- DimensionBinding binding,
- QueryProfile owner,
- DimensionValues variant) {
- addUnoverridable(name, currentPrefix.append(name), binding, owner);
- }
-
- @Override
- public void onQueryProfileInsidePrefix(QueryProfile profile,
- DimensionBinding binding,
- QueryProfile owner,
- DimensionValues variant) {
- addUnoverridable(currentPrefix.last(), currentPrefix, binding, owner);
- }
-
- private void addUnoverridable(String localName,
- CompoundName fullName,
- DimensionBinding binding,
- QueryProfile owner) {
- if (owner == null) return;
-
- Boolean isOverridable = owner.isLocalOverridable(localName, binding);
- if (isOverridable != null && ! isOverridable)
- unoverridables.add(fullName);
- }
-
- /** Returns the values resulting from this visiting */
- public Set<CompoundName> getResult() { return unoverridables; }
-
- /** Returns false - we are not done until we have seen all */
- public boolean isDone() { return false; }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java
index f27500085e1..2b61dc4c0a6 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java
@@ -3,6 +3,9 @@ package com.yahoo.search.query.profile;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.query.profile.compiled.ValueWithSource;
+import com.yahoo.search.query.profile.types.FieldDescription;
+import com.yahoo.search.query.profile.types.QueryProfileFieldType;
+import com.yahoo.search.query.profile.types.QueryProfileType;
import java.util.Collections;
import java.util.HashMap;
@@ -26,7 +29,7 @@ final class AllValuesQueryProfileVisitor extends PrefixQueryProfileVisitor {
DimensionBinding binding,
QueryProfile owner,
DimensionValues variant) {
- putValue(localName, value, owner, variant);
+ putValue(localName, value, null, owner, variant, binding);
}
@Override
@@ -34,17 +37,25 @@ final class AllValuesQueryProfileVisitor extends PrefixQueryProfileVisitor {
DimensionBinding binding,
QueryProfile owner,
DimensionValues variant) {
- putValue("", profile.getValue(), owner, variant);
+ putValue("", profile.getValue(), profile, owner, variant, binding);
}
- private void putValue(String key, Object value, QueryProfile owner, DimensionValues variant) {
- if (value == null) return;
+ private void putValue(String key,
+ Object value,
+ QueryProfile profile,
+ QueryProfile owner,
+ DimensionValues variant,
+ DimensionBinding binding) {
CompoundName fullName = currentPrefix.append(key);
- if (fullName.isEmpty()) return; // Avoid putting a non-leaf (subtree) root in the list
if (values.containsKey(fullName.toString())) return; // The first value encountered has priority
+ Boolean isOverridable = owner != null ? owner.isLocalOverridable(key, binding) : null;
+
values.put(fullName.toString(), new ValueWithSource(value,
owner == null ? "anonymous" : owner.getSource(),
+ isOverridable != null && ! isOverridable,
+ profile != null,
+ profile == null ? null : profile.getType(),
variant));
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java
index 0cbfdc5dca0..e0edf9f9894 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java
@@ -162,7 +162,7 @@ public class DimensionBinding {
combined.add(d2.get(d2Index++));
}
else {
- return null; // no independent and no agreement
+ return null; // not independent and no agreement
}
}
if (d1Index < d1.size())
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java
index ab0f129f1e9..b6b03d37da8 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java
@@ -265,37 +265,6 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
}
/**
- * Lists types reachable from this, indexed by the prefix having that type.
- * If this is itself typed, this' type will be included with an empty prefix
- */
- public Map<CompoundName, QueryProfileType> listTypes(CompoundName prefix, Map<String, String> context) {
- DimensionBinding dimensionBinding = DimensionBinding.createFrom(getDimensions(), context);
- AllTypesQueryProfileVisitor visitor = new AllTypesQueryProfileVisitor(prefix);
- accept(visitor, dimensionBinding, null);
- return visitor.getResult();
- }
-
- /**
- * Lists references reachable from this.
- */
- Set<CompoundName> listReferences(CompoundName prefix, Map<String, String> context) {
- DimensionBinding dimensionBinding = DimensionBinding.createFrom(getDimensions(),context);
- AllReferencesQueryProfileVisitor visitor = new AllReferencesQueryProfileVisitor(prefix);
- accept(visitor,dimensionBinding,null);
- return visitor.getResult();
- }
-
- /**
- * Lists every entry (value or reference) reachable from this which is not overridable
- */
- Set<CompoundName> listUnoverridable(CompoundName prefix, Map<String, String> context) {
- DimensionBinding dimensionBinding = DimensionBinding.createFrom(getDimensions(),context);
- AllUnoverridableQueryProfileVisitor visitor = new AllUnoverridableQueryProfileVisitor(prefix);
- accept(visitor, dimensionBinding, null);
- return visitor.getResult();
- }
-
- /**
* Returns a value from this query profile by resolving the given name:
* <ul>
* <li>The name up to the first dot is the value looked up in the value of this profile
@@ -557,6 +526,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
QueryProfileVisitor visitor,
DimensionBinding dimensionBinding,
QueryProfile owner) {
+ //System.out.println(" visiting " + this);
visitor.onQueryProfile(this, dimensionBinding, owner, null);
if (visitor.isDone()) return;
@@ -570,6 +540,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
if (visitor.visitInherited())
visitInherited(allowContent, visitor, dimensionBinding, owner);
+ //System.out.println(" done visiting " + this);
}
protected void visitVariants(boolean allowContent, QueryProfileVisitor visitor, DimensionBinding dimensionBinding) {
@@ -759,7 +730,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
* Sets the overridability of a field in this profile,
* this overrides the corresponding setting in the type (if any)
*/
- private void setOverridable(CompoundName fieldName,boolean overridable,DimensionBinding dimensionBinding) {
+ private void setOverridable(CompoundName fieldName, boolean overridable, DimensionBinding dimensionBinding) {
QueryProfile parent = lookupParentExact(fieldName, true, dimensionBinding);
if (parent.overridable == null)
parent.overridable = new HashMap<>();
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java
index f1fc90dee09..5dacd347c2c 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java
@@ -12,6 +12,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
* Compile a set of query profiles into compiled profiles.
@@ -24,9 +25,8 @@ public class QueryProfileCompiler {
public static CompiledQueryProfileRegistry compile(QueryProfileRegistry input) {
CompiledQueryProfileRegistry output = new CompiledQueryProfileRegistry(input.getTypeRegistry());
- for (QueryProfile inputProfile : input.allComponents()) {
+ for (QueryProfile inputProfile : input.allComponents())
output.register(compile(inputProfile, output));
- }
return output;
}
@@ -40,18 +40,20 @@ public class QueryProfileCompiler {
// Resolve values for each existing variant and combine into a single data structure
Set<DimensionBindingForPath> variants = collectVariants(CompoundName.empty, in, DimensionBinding.nullBinding);
variants.add(new DimensionBindingForPath(DimensionBinding.nullBinding, CompoundName.empty)); // if this contains no variants
- log.fine(() -> "Compiling " + in.toString() + " having " + variants.size() + " variants");
+ log.fine(() -> "Compiling " + in + " having " + variants.size() + " variants");
+
for (DimensionBindingForPath variant : variants) {
log.finer(() -> " Compiling variant " + variant);
for (Map.Entry<String, ValueWithSource> entry : in.visitValues(variant.path(), variant.binding().getContext()).valuesWithSource().entrySet()) {
- values.put(variant.path().append(entry.getKey()), variant.binding(), entry.getValue());
+ CompoundName fullName = variant.path().append(entry.getKey());
+ values.put(fullName, variant.binding(), entry.getValue());
+ if (entry.getValue().isUnoverridable())
+ unoverridables.put(fullName, variant.binding(), Boolean.TRUE);
+ if (entry.getValue().isQueryProfile())
+ references.put(fullName, variant.binding(), Boolean.TRUE);
+ if (entry.getValue().queryProfileType() != null)
+ types.put(fullName, variant.binding(), entry.getValue().queryProfileType());
}
- for (Map.Entry<CompoundName, QueryProfileType> entry : in.listTypes(variant.path(), variant.binding().getContext()).entrySet())
- types.put(variant.path().append(entry.getKey()), variant.binding(), entry.getValue());
- for (CompoundName reference : in.listReferences(variant.path(), variant.binding().getContext()))
- references.put(variant.path().append(reference), variant.binding(), Boolean.TRUE); // Used as a set; value is ignored
- for (CompoundName name : in.listUnoverridable(variant.path(), variant.binding().getContext()))
- unoverridables.put(variant.path().append(name), variant.binding(), Boolean.TRUE); // Used as a set; value is ignored
}
return new CompiledQueryProfile(in.getId(), in.getType(),
@@ -100,6 +102,7 @@ public class QueryProfileCompiler {
*/
private static Set<DimensionBindingForPath> wildcardExpanded(Set<DimensionBindingForPath> variants) {
Set<DimensionBindingForPath> expanded = new HashSet<>();
+
for (var variant : variants) {
if (hasWildcardBeforeEnd(variant.binding()))
expanded.addAll(wildcardExpanded(variant, variants));
@@ -120,10 +123,10 @@ public class QueryProfileCompiler {
Set<DimensionBindingForPath> expanded = new HashSet<>();
for (var variant : variants) {
if (variant.binding().isNull()) continue;
+ if ( ! variant.path().hasPrefix(variantToExpand.path())) continue;
DimensionBinding combined = variantToExpand.binding().combineWith(variant.binding());
- if ( ! combined.isInvalid() ) {
+ if ( ! combined.isInvalid() )
expanded.add(new DimensionBindingForPath(combined, variantToExpand.path()));
- }
}
return expanded;
}
@@ -136,7 +139,7 @@ public class QueryProfileCompiler {
for (DimensionBindingForPath v1 : v1s) {
if (v1.binding().isNull()) continue;
for (DimensionBindingForPath v2 : v2s) {
- if (v1.binding().isNull()) continue;
+ if (v2.binding().isNull()) continue;
DimensionBinding combined = v1.binding().combineWith(v2.binding());
if ( combined.isInvalid() ) continue;
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java
index 0363b50815b..eb7a6d19d91 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java
@@ -62,7 +62,6 @@ public class QueryProfileRegistry extends ComponentRegistry<QueryProfile> {
int slashIndex=id.getName().lastIndexOf("/");
if (slashIndex<1) return null;
String parentName=id.getName().substring(0,slashIndex);
- if (parentName.equals("")) return null;
ComponentSpecification parentId=new ComponentSpecification(parentName,id.getVersionSpecification());
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java
index 8dedda800ea..4c4d6778d86 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java
@@ -30,7 +30,7 @@ public class QueryProfileVariants implements Freezable, Cloneable {
private Map<String,FieldValues> fieldValuesByName = new HashMap<>();
/** The inherited profiles for various dimensions settings - a set of fieldvalues of List&lt;QueryProfile&gt; */
- private FieldValues inheritedProfiles =new FieldValues();
+ private FieldValues inheritedProfiles = new FieldValues();
/**
* Field and inherited profiles sorted by specificity used for all-value visiting.
@@ -105,10 +105,14 @@ public class QueryProfileVariants implements Freezable, Cloneable {
if (contentName != null) {
if (type != null)
contentName = type.unalias(contentName);
+ //System.out.println(" accepting single value in " + this + " for local key " + contentName);
acceptSingleValue(contentName, allowContent, visitor, dimensionBinding); // Special cased for performance
+ //System.out.println(" done accepting single value in " + this + " for local key " + contentName);
}
else {
+ //System.out.println(" accepting all values in " + this);
acceptAllValues(allowContent, visitor, type, dimensionBinding);
+ //System.out.println(" done accepting all values in " + this);
}
}
@@ -144,7 +148,7 @@ public class QueryProfileVariants implements Freezable, Cloneable {
if (visitor.isDone()) return;
fieldIndex++;
}
- else if (inheritedProfileValue != null) { // Inherited is most specific at this point
+ else { // Inherited is most specific at this point
if (inheritedProfileValue.matches(dimensionBinding.getValues())) {
@SuppressWarnings("unchecked")
List<QueryProfile> inheritedProfileList = (List<QueryProfile>)inheritedProfileValue.getValue();
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java
index 1c7a7cf3e97..9be459ceeab 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/CompiledQueryProfile.java
@@ -159,6 +159,7 @@ public class CompiledQueryProfile extends AbstractComponent implements Cloneable
ValueWithSource valueWithSource = entry.getValue().get(context);
if (valueWithSource == null) continue;
+ if (valueWithSource.value() == null) continue;
valueWithSource = valueWithSource.withValue(substitute(valueWithSource.value(), context, substitution));
CompoundName suffixName = entry.getKey().rest(prefix.size());
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueWithSource.java b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueWithSource.java
index 925d20903c6..bc49e116c6e 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueWithSource.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueWithSource.java
@@ -2,6 +2,8 @@
package com.yahoo.search.query.profile.compiled;
import com.yahoo.search.query.profile.DimensionValues;
+import com.yahoo.search.query.profile.QueryProfile;
+import com.yahoo.search.query.profile.types.QueryProfileType;
import java.util.Optional;
@@ -14,24 +16,52 @@ public class ValueWithSource {
private final Object value;
- /** The source of the query profile having a value */
private final String source;
+ private final boolean isUnoverridable;
+
+ private final boolean isQueryProfile;
+
+ private final QueryProfileType type;
+
/** The dimension values specifying a variant in that profile, or null if it is not in a variant */
private final DimensionValues variant;
- public ValueWithSource(Object value, String source, DimensionValues variant) {
+ public ValueWithSource(Object value,
+ String source,
+ boolean isUnoverridable, boolean isQueryProfile, QueryProfileType type,
+ DimensionValues variant) {
this.value = value;
this.source = source;
+ this.isUnoverridable = isUnoverridable;
+ this.isQueryProfile = isQueryProfile;
+ this.type = type;
this.variant = variant;
}
+ /**
+ * Returns the value at this key, or null if none
+ * (in which case this is references a query profile which has no value set).
+ */
public Object value() { return value; }
+ /** Returns the source of the query profile having a value */
public String source() { return source; }
+ /** Returns true if this value cannot be overridden in queries */
+ public boolean isUnoverridable() { return isUnoverridable; }
+
+ /**
+ * Returns true if this key references a query profile (i.e a non-leaf).
+ * In this case the value may or may not be null, as non-leafs may have values.
+ */
+ public boolean isQueryProfile() { return isQueryProfile; }
+
+ /** Returns tye type of this if it refers to a query profile (not a leaf value), and it has a type */
+ public QueryProfileType queryProfileType() { return type; }
+
public ValueWithSource withValue(Object value) {
- return new ValueWithSource(value, source, variant);
+ return new ValueWithSource(value, source, isUnoverridable, isQueryProfile, type, variant);
}
/** Returns the variant having this value, or empty if it's not in a variant */
diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java
index 0485b4dbb62..06434da2478 100644
--- a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java
@@ -3,7 +3,6 @@ package com.yahoo.search.query.profile.config.test;
import com.yahoo.jdisc.http.HttpRequest.Method;
import com.yahoo.container.jdisc.HttpRequest;
-import com.yahoo.processing.execution.Execution;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.yolean.Exceptions;
import com.yahoo.search.Query;