diff options
author | Jon Bratseth <bratseth@gmail.com> | 2020-11-10 23:32:31 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2020-11-10 23:32:31 +0100 |
commit | 094be744d6706e02c7299ac1c92b49a0b13a24c5 (patch) | |
tree | 297d1df9650694c26fc11aceff5444ed445e9096 /container-search/src/main/java/com/yahoo/search | |
parent | 0c68b00b2d3a9ddc191ed1733ba2f8699d1c3dc1 (diff) |
Support setting specific variants unoverridable
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search')
5 files changed, 74 insertions, 21 deletions
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 d0a42e8a1f9..be4a683d9d2 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 @@ -147,7 +147,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * Returns the content fields declared in this (i.e not including those inherited) as a read-only map. * @throws IllegalStateException if this is frozen */ - public Map<String,Object> declaredContent() { + public Map<String, Object> declaredContent() { ensureNotFrozen(); return content.unmodifiableMap(); } @@ -203,6 +203,14 @@ 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) + */ + public final void setOverridable(String fieldName, boolean overridable, DimensionValues dimensionValues) { + setOverridable(new CompoundName(fieldName), overridable, DimensionBinding.createFrom(getDimensions(), dimensionValues)); + } + + /** * Return all objects that start with the given prefix path using no context. Use "" to list all. * <p> * For example, if {a.d => "a.d-value" ,a.e => "a.e-value", b.d => "b.d-value", then calling listValues("a") @@ -234,7 +242,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * For example, if {a.d => "a.d-value" ,a.e => "a.e-value", b.d => "b.d-value", then calling listValues("a") * will return {"d" => "a.d-value","e" => "a.e-value"} */ - public final Map<String, Object> listValues(CompoundName prefix, Map<String,String> context) { + public final Map<String, Object> listValues(CompoundName prefix, Map<String, String> context) { return listValues(prefix, context, null); } @@ -341,11 +349,11 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * @throws IllegalArgumentException if the given name is illegal given the types of this or any nested query profile * @throws IllegalStateException if this query profile is frozen */ - public final void set(CompoundName name, Object value, Map<String,String> context, QueryProfileRegistry registry) { + public final void set(CompoundName name, Object value, Map<String, String> context, QueryProfileRegistry registry) { set(name, value, DimensionBinding.createFrom(getDimensions(), context), registry); } - public final void set(String name, Object value, Map<String,String> context, QueryProfileRegistry registry) { + public final void set(String name, Object value, Map<String, String> context, QueryProfileRegistry registry) { set(new CompoundName(name), value, DimensionBinding.createFrom(getDimensions(), context), registry); } @@ -479,9 +487,14 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable */ Boolean isLocalOverridable(String localName, DimensionBinding binding) { if (localLookup(localName, binding) == null) return null; // Not set + if ( ! binding.isNull() && getVariants() != null) { + Boolean variantIsOverriable = getVariants().isOverridable(localName, binding.getValues()); + if (variantIsOverriable != null) + return variantIsOverriable; + } Boolean isLocalInstanceOverridable = isLocalInstanceOverridable(localName); if (isLocalInstanceOverridable != null) - return isLocalInstanceOverridable.booleanValue(); + return isLocalInstanceOverridable; if (type != null) return type.isOverridable(localName); return true; } @@ -731,9 +744,14 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable */ private void setOverridable(CompoundName fieldName, boolean overridable, DimensionBinding dimensionBinding) { QueryProfile parent = lookupParentExact(fieldName, true, dimensionBinding); - if (parent.overridable == null) - parent.overridable = new HashMap<>(); - parent.overridable.put(fieldName.last(), overridable); + if (dimensionBinding.isNull()) { + if (parent.overridable == null) + parent.overridable = new HashMap<>(); + parent.overridable.put(fieldName.last(), overridable); + } + else { + variants.setOverridable(fieldName.last(), overridable, dimensionBinding.getValues()); + } } /** Sets a value to a (possibly non-local) node. */ diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java index a33ee33b652..f6c43eab8a0 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java @@ -20,6 +20,8 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa private Map<String, Object> values; + private final Map<String, Boolean> overridable = new HashMap<>(); + private boolean frozen = false; private final QueryProfile owner; @@ -71,6 +73,14 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa return combinedOrNull; } + public void setOverridable(String key, boolean overridable) { + this.overridable.put(key, overridable); + } + + public Boolean isOverridable(String key) { + return overridable.get(key); + } + public void inherit(QueryProfile profile) { if (inherited == null) inherited = new ArrayList<>(1); 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 062b9d8c6e4..431947b0816 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 @@ -27,7 +27,7 @@ public class QueryProfileVariants implements Freezable, Cloneable { private boolean frozen = false; /** Properties indexed by name, to support fast lookup of single values */ - private Map<String,FieldValues> fieldValuesByName = new HashMap<>(); + private Map<String, FieldValues> fieldValuesByName = new HashMap<>(); /** The inherited profiles for various dimensions settings - a set of fieldvalues of List<QueryProfile> */ private FieldValues inheritedProfiles = new FieldValues(); @@ -233,6 +233,19 @@ public class QueryProfileVariants implements Freezable, Cloneable { } /** + * Makes a value unoverridable in a given context. + */ + public void setOverridable(String fieldName, boolean overridable, DimensionValues dimensionValues) { + getVariant(dimensionValues, true).setOverridable(fieldName, overridable); + } + + public Boolean isOverridable(String fieldName, DimensionValues dimensionValues) { + QueryProfileVariant variant = getVariant(dimensionValues, false); + if (variant == null) return null; + return variant.isOverridable(fieldName); + } + + /** * Returns the dimensions over which the virtual profiles in this may return different values. * Each dimension is a name for which a key-value may be supplied in the context properties * on lookup time to influence the value returned. diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java index d3c232f84c5..423348454d0 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java @@ -121,16 +121,20 @@ public class QueryProfileConfigurer implements ConfigSubscriber.SingleSubscriber QueryProfile referenced = registry.getComponent(referenceConfig.value()); if (referenced == null) throw new IllegalArgumentException("Query profile '" + referenceConfig.value() + "' referenced as '" + - referenceConfig.name() + "' in " + profile + " was not found"); + referenceConfig.name() + "' in " + profile + " was not found"); profile.set(referenceConfig.name(), referenced, registry); if (referenceConfig.overridable() != null && !referenceConfig.overridable().isEmpty()) - profile.setOverridable(referenceConfig.name(), BooleanParser.parseBoolean(referenceConfig.overridable()), null); + profile.setOverridable(referenceConfig.name(), + BooleanParser.parseBoolean(referenceConfig.overridable()), + DimensionValues.empty); } for (QueryProfilesConfig.Queryprofile.Property propertyConfig : config.property()) { profile.set(propertyConfig.name(), propertyConfig.value(), registry); if (propertyConfig.overridable() != null && ! propertyConfig.overridable().isEmpty()) - profile.setOverridable(propertyConfig.name(), BooleanParser.parseBoolean(propertyConfig.overridable()), null); + profile.setOverridable(propertyConfig.name(), + BooleanParser.parseBoolean(propertyConfig.overridable()), + DimensionValues.empty); } for (QueryProfilesConfig.Queryprofile.Queryprofilevariant variantConfig : config.queryprofilevariant()) { @@ -152,15 +156,24 @@ public class QueryProfileConfigurer implements ConfigSubscriber.SingleSubscriber } for (QueryProfilesConfig.Queryprofile.Queryprofilevariant.Reference referenceConfig : variantConfig.reference()) { - QueryProfile referenced=registry.getComponent(referenceConfig.value()); + QueryProfile referenced = registry.getComponent(referenceConfig.value()); if (referenced == null) throw new IllegalArgumentException("Query profile '" + referenceConfig.value() + "' referenced as '" + - referenceConfig.name() + "' in " + profile + " for '" + forDimensionValues + "' was not found"); + referenceConfig.name() + "' in " + profile + + " for '" + forDimensionValues + "' was not found"); profile.set(referenceConfig.name(), referenced, forDimensionValues, registry); + if ( ! referenceConfig.overridable().isEmpty()) + profile.setOverridable(referenceConfig.name(), + Boolean.parseBoolean(referenceConfig.overridable()), + forDimensionValues); } for (QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property propertyConfig : variantConfig.property()) { profile.set(propertyConfig.name(), propertyConfig.value(), forDimensionValues, registry); + if ( ! propertyConfig.overridable().isEmpty()) + profile.setOverridable(propertyConfig.name(), + Boolean.parseBoolean(propertyConfig.overridable()), + forDimensionValues); } } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java index db6d0560c5f..a64f2087d1f 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java @@ -41,7 +41,7 @@ public class QueryProfileXMLReader { try { File dir = new File(directory); if ( ! dir.isDirectory() ) throw new IllegalArgumentException("Could not read query profiles: '" + - directory + "' is not a valid directory."); + directory + "' is not a valid directory."); for (File file : sortFiles(dir)) { if ( ! file.getName().endsWith(".xml")) continue; @@ -235,7 +235,7 @@ public class QueryProfileXMLReader { QueryProfile profile = registry.getComponent(new ComponentSpecification(element.getAttribute("id")).toId()); try { readInherited(element, profile, registry,null, profile.toString()); - readFields(element, profile, registry,null, profile.toString()); + readFields(element, profile, registry,DimensionValues.empty, profile.toString()); readVariants(element, profile, registry); } catch (RuntimeException e) { @@ -268,10 +268,9 @@ public class QueryProfileXMLReader { if (name == null || name.equals("")) throw new IllegalArgumentException("A field in " + sourceDescription + " has no 'name' attribute"); try { - Boolean overridable = getBooleanAttribute("overridable",null,field); + Boolean overridable = getBooleanAttribute("overridable", null, field); if (overridable != null) - profile.setOverridable(name, overridable, null); - + profile.setOverridable(name, overridable, dimensionValues.asContext(profile.getDimensions())); Object fieldValue = readFieldValue(field, name, sourceDescription, registry); if (fieldValue instanceof QueryProfile) references.add(new KeyValue(name, fieldValue)); @@ -358,8 +357,8 @@ public class QueryProfileXMLReader { private static class KeyValue { - private String key; - private Object value; + private final String key; + private final Object value; public KeyValue(String key, Object value) { this.key = key; |