diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java |
Publish
Diffstat (limited to 'config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java')
-rw-r--r-- | config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java new file mode 100644 index 00000000000..cc57a58ed47 --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java @@ -0,0 +1,276 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search; + +import com.yahoo.search.query.profile.BackedOverridableQueryProfile; +import com.yahoo.search.query.profile.QueryProfile; +import com.yahoo.search.query.profile.QueryProfileRegistry; +import com.yahoo.search.query.profile.SubstituteString; +import com.yahoo.search.query.profile.types.FieldDescription; +import com.yahoo.search.query.profile.types.QueryProfileType; +import com.yahoo.search.query.profile.config.QueryProfilesConfig; + +import java.io.Serializable; +import java.util.*; +import java.util.Map.Entry; + +/** + * Owns the query profiles and query profile types to be handed to the qrs nodes. + * Owned by a container cluster + * + * @author bratseth + */ +public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer { + + private QueryProfileRegistry registry; + + /** + * Creates a new set of query profiles for which the config can be returned at request + * + * @param registry the registry containing the query profiles and types of this. + * The given registry cannot be frozen on calling this. + */ + public QueryProfiles(QueryProfileRegistry registry) { + this.registry = registry; + } + + public QueryProfiles() { + this.registry = new QueryProfileRegistry(); + } + + public QueryProfileRegistry getRegistry() { + return registry; + } + + @Override + public void getConfig(QueryProfilesConfig.Builder builder) { + for (QueryProfile profile : registry.allComponents()) { + builder.queryprofile(createConfig(profile)); + } + for (QueryProfileType profileType : registry.getTypeRegistry().allComponents()) { + if ( ! profileType.isBuiltin()) + builder.queryprofiletype(createConfig(profileType)); + } + } + + private QueryProfilesConfig.Queryprofile.Builder createConfig(QueryProfile profile) { + QueryProfilesConfig.Queryprofile.Builder qB = new QueryProfilesConfig.Queryprofile.Builder(); + qB.id(profile.getId().stringValue()); + if (profile.getType() != null) + qB.type(profile.getType().getId().stringValue()); + for (QueryProfile inherited : profile.inherited()) + qB.inherit(inherited.getId().stringValue()); + + if (profile.getVariants()!=null) { + for (String dimension : profile.getVariants().getDimensions()) + qB.dimensions(dimension); + } + addFieldChildren(qB, profile, ""); + addVariants(qB, profile); + return qB; + } + + private void addFieldChildren(QueryProfilesConfig.Queryprofile.Builder qpB, QueryProfile profile, String namePrefix) { + List<Map.Entry<String,Object>> content=new ArrayList<>(profile.declaredContent().entrySet()); + Collections.sort(content,new MapEntryKeyComparator()); + if (profile.getValue()!=null) { // Add "prefix with dot removed"=value: + QueryProfilesConfig.Queryprofile.Property.Builder propB = new QueryProfilesConfig.Queryprofile.Property.Builder(); + String fullName = namePrefix.substring(0, namePrefix.length() - 1); + Object value = profile.getValue(); + if (value instanceof SubstituteString) + value=value.toString(); // Send only types understood by configBuilder downwards + propB.name(fullName); + if (value!=null) propB.value(value.toString()); + qpB.property(propB); + } + for (Map.Entry<String,Object> field : content) { + addField(qpB, profile, field, namePrefix); + } + } + + private void addVariantFieldChildren(QueryProfilesConfig.Queryprofile.Queryprofilevariant.Builder qpB, + QueryProfile profile, String namePrefix) { + List<Map.Entry<String,Object>> content=new ArrayList<>(profile.declaredContent().entrySet()); + Collections.sort(content,new MapEntryKeyComparator()); + if (profile.getValue()!=null) { // Add "prefix with dot removed"=value: + QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property.Builder propB = new QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property.Builder(); + String fullName = namePrefix.substring(0, namePrefix.length() - 1); + Object value = profile.getValue(); + if (value instanceof SubstituteString) + value=value.toString(); // Send only types understood by configBuilder downwards + propB.name(fullName); + if (value!=null) propB.value(value.toString()); + qpB.property(propB); + } + for (Map.Entry<String,Object> field : content) { + addVariantField(qpB, field, namePrefix); + } + } + + private void addField(QueryProfilesConfig.Queryprofile.Builder qpB, + QueryProfile profile, Entry<String, Object> field, String namePrefix) { + String fullName=namePrefix + field.getKey(); + if (field.getValue() instanceof QueryProfile) { + QueryProfile subProfile=(QueryProfile)field.getValue(); + if ( ! subProfile.isExplicit()) { // Implicitly defined profile - add content + addFieldChildren(qpB, subProfile,fullName + "."); + } + else { // Reference to an id'ed profile - output reference plus any local overrides + QueryProfilesConfig.Queryprofile.Reference.Builder refB = new QueryProfilesConfig.Queryprofile.Reference.Builder(); + createReferenceFieldConfig(refB, profile, fullName, field.getKey(), ((BackedOverridableQueryProfile) subProfile).getBacking().getId().stringValue()); + qpB.reference(refB); + addFieldChildren(qpB, subProfile,fullName + "."); + } + } + else { // a primitive + qpB.property(createPropertyFieldConfig(profile, fullName, field.getKey(), field.getValue())); + } + } + + private void addVariantField(QueryProfilesConfig.Queryprofile.Queryprofilevariant.Builder qpB, + Entry<String, Object> field, String namePrefix) { + String fullName=namePrefix + field.getKey(); + if (field.getValue() instanceof QueryProfile) { + QueryProfile subProfile=(QueryProfile)field.getValue(); + if ( ! subProfile.isExplicit()) { // Implicitly defined profile - add content + addVariantFieldChildren(qpB, subProfile,fullName + "."); + } + else { // Reference to an id'ed profile - output reference plus any local overrides + QueryProfilesConfig.Queryprofile.Queryprofilevariant.Reference.Builder refB = new QueryProfilesConfig.Queryprofile.Queryprofilevariant.Reference.Builder(); + createVariantReferenceFieldConfig(refB, fullName, ((BackedOverridableQueryProfile) subProfile).getBacking().getId().stringValue()); + qpB.reference(refB); + addVariantFieldChildren(qpB, subProfile,fullName + "."); + } + } + else { // a primitive + qpB.property(createVariantPropertyFieldConfig(fullName, field.getValue())); + } + } + + private void addVariants(QueryProfilesConfig.Queryprofile.Builder qB, QueryProfile profile) { + if (profile.getVariants()==null) return; + DeclaredQueryProfileVariants declaredVariants=new DeclaredQueryProfileVariants(profile); + for (DeclaredQueryProfileVariants.VariantQueryProfile variant : declaredVariants.getVariantQueryProfiles().values()) { + QueryProfilesConfig.Queryprofile.Queryprofilevariant.Builder varB = new QueryProfilesConfig.Queryprofile.Queryprofilevariant.Builder(); + for (String dimensionValue : variant.getDimensionValues()) { + if (dimensionValue==null) + dimensionValue="*"; + varB.fordimensionvalues(dimensionValue); + } + for (QueryProfile inherited : variant.inherited()) + varB.inherit(inherited.getId().stringValue()); + + List<Map.Entry<String,Object>> content=new ArrayList<>(variant.getValues().entrySet()); + Collections.sort(content,new MapEntryKeyComparator()); + for (Map.Entry<String,Object> value : content) { + addVariantField(varB, value,""); + } + qB.queryprofilevariant(varB); + } + } + + private void createReferenceFieldConfig(QueryProfilesConfig.Queryprofile.Reference.Builder refB, QueryProfile profile, + String fullName, String localName, String stringValue) { + refB.name(fullName); + if (stringValue!=null) refB.value(stringValue); + Boolean overridable=null; + if (profile!=null) + overridable=profile.isDeclaredOverridable(localName, null); + if (overridable!=null) + refB.overridable(""+overridable); + } + + private void createVariantReferenceFieldConfig(QueryProfilesConfig.Queryprofile.Queryprofilevariant.Reference.Builder refB, + String fullName, String stringValue) { + refB.name(fullName); + if (stringValue!=null) refB.value(stringValue); + } + + private QueryProfilesConfig.Queryprofile.Property.Builder createPropertyFieldConfig( + QueryProfile profile, String fullName, String localName, Object value) { + QueryProfilesConfig.Queryprofile.Property.Builder propB = new QueryProfilesConfig.Queryprofile.Property.Builder(); + Boolean overridable=null; + if (value instanceof SubstituteString) + value=value.toString(); // Send only types understood by configBuilder downwards + propB.name(fullName); + if (value!=null) propB.value(value.toString()); + if (profile!=null) + overridable=profile.isDeclaredOverridable(localName, null); + if (overridable!=null) + propB.overridable(""+overridable); + return propB; + } + + private QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property.Builder createVariantPropertyFieldConfig( + String fullName, Object value) { + QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property.Builder propB = new QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property.Builder(); + if (value instanceof SubstituteString) + value=value.toString(); // Send only types understood by configBuilder downwards + propB.name(fullName); + if (value!=null) propB.value(value.toString()); + return propB; + } + + private QueryProfilesConfig.Queryprofiletype.Builder createConfig(QueryProfileType profileType) { + QueryProfilesConfig.Queryprofiletype.Builder qtB = new QueryProfilesConfig.Queryprofiletype.Builder(); + qtB.id(profileType.getId().stringValue()); + if (profileType.isDeclaredStrict()) + qtB.strict(true); + if (profileType.getDeclaredMatchAsPath()) + qtB.matchaspath(true); + for (QueryProfileType inherited : profileType.inherited()) + qtB.inherit(inherited.getId().stringValue()); + List<FieldDescription> fields=new ArrayList<>(profileType.declaredFields().values()); + Collections.sort(fields); + for (FieldDescription field : fields) + qtB.field(createConfig(field)); + return qtB; + } + + private QueryProfilesConfig.Queryprofiletype.Field.Builder createConfig(FieldDescription field) { + QueryProfilesConfig.Queryprofiletype.Field.Builder fB = new QueryProfilesConfig.Queryprofiletype.Field.Builder(); + fB. + name(field.getName()). + type(field.getType().stringValue()); + if ( ! field.isOverridable()) + fB.overridable(false); + if (field.isMandatory()) + fB.mandatory(true); + String aliases=toSpaceSeparatedString(field.getAliases()); + if (!aliases.isEmpty()) + fB.alias(aliases); + return fB; + } + + public String toSpaceSeparatedString(List<String> list) { + StringBuilder b=new StringBuilder(); + for (Iterator<String> i=list.iterator(); i.hasNext(); ) { + b.append(i.next()); + if (i.hasNext()) + b.append(" "); + } + return b.toString(); + } + + private static class MapEntryKeyComparator implements Comparator<Map.Entry<String,Object>> { + + public int compare(Map.Entry<String,Object> e1,Map.Entry<String,Object> e2) { + return e1.getKey().compareTo(e2.getKey()); + } + + public boolean equals(Object other) { + return other instanceof MapEntryKeyComparator; + } + + } + + /** + * The config produced by this + * @return query profiles config + */ + public QueryProfilesConfig getConfig() { + QueryProfilesConfig.Builder qB = new QueryProfilesConfig.Builder(); + getConfig(qB); + return new QueryProfilesConfig(qB); + } + +} |