diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2020-02-03 11:43:17 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2020-02-03 11:43:17 +0100 |
commit | 1ca13d729f054d8393d5b2c1633d15502f306d74 (patch) | |
tree | f63db3637995f3e7663705522a3a7d99f567e2e6 | |
parent | a400fa45e453f64ca90722713f5914cb281585e8 (diff) |
Resolve nested type references by description
9 files changed, 138 insertions, 60 deletions
diff --git a/component/src/main/java/com/yahoo/component/ComponentId.java b/component/src/main/java/com/yahoo/component/ComponentId.java index 05c710e3fc1..4613be09543 100644 --- a/component/src/main/java/com/yahoo/component/ComponentId.java +++ b/component/src/main/java/com/yahoo/component/ComponentId.java @@ -32,15 +32,15 @@ public final class ComponentId implements Comparable<ComponentId> { private int count = 0; public int getAndIncrement() { return count++; } } - private static ThreadLocal<Counter> gid = new ThreadLocal<Counter>() { + private static ThreadLocal<Counter> threadLocalUniqueId = new ThreadLocal<Counter>() { @Override protected Counter initialValue() { return new Counter(); } }; - private static AtomicInteger uniqueTid = new AtomicInteger(0); - private static ThreadLocal<String> tid = new ThreadLocal<String>() { + private static AtomicInteger threadIdCounter = new AtomicInteger(0); + private static ThreadLocal<String> threadId = new ThreadLocal<String>() { @Override protected String initialValue() { - return new String("_"+uniqueTid.getAndIncrement()+"_"); + return new String("_" + threadIdCounter.getAndIncrement() + "_"); } }; @@ -58,7 +58,7 @@ public final class ComponentId implements Comparable<ComponentId> { } private String createAnonymousName(String name) { - return new StringBuilder(name).append(tid.get()).append(gid.get().getAndIncrement()).toString(); + return new StringBuilder(name).append(threadId.get()).append(threadLocalUniqueId.get().getAndIncrement()).toString(); } public ComponentId(String name, Version version, ComponentId namespace) { @@ -148,10 +148,7 @@ public final class ComponentId implements Comparable<ComponentId> { return spec.compareTo(other.spec); } - /** - * Creates a componentId that is unique for this run-time instance - */ - // TODO: Check if we really need this. -JB + /** Creates a componentId that is unique for this run-time instance */ public static ComponentId createAnonymousComponentId(String baseName) { return new ComponentId(baseName, null, null, true); } @@ -196,27 +193,27 @@ public final class ComponentId implements Comparable<ComponentId> { * Creates an id from a file <b>first</b> name string encoded in the standard translation (see {@link #toFileName}). * <b>Note</b> that any file last name, like e.g ".xml" must be stripped off before handoff to this method. */ - public static ComponentId fromFileName(final String fileName) { + public static ComponentId fromFileName(String fileName) { // Initial assumptions - String id=fileName; - Version version =null; - ComponentId namespace=null; + String id = fileName; + Version version = null; + ComponentId namespace = null; // Split out namespace, if any - int at=id.indexOf("@"); - if (at>0) { - String newId=id.substring(0,at); - namespace=ComponentId.fromString(id.substring(at+1)); - id=newId; + int at = id.indexOf("@"); + if (at > 0) { + String newId = id.substring(0, at); + namespace = ComponentId.fromString(id.substring(at + 1)); + id = newId; } // Split out version, if any - int dash=id.lastIndexOf("-"); - if (dash>0) { - String newId=id.substring(0,dash); + int dash = id.lastIndexOf("-"); + if (dash > 0) { + String newId = id.substring(0, dash); try { - version=new Version(id.substring(dash+1)); - id=newId; + version = new Version(id.substring(dash + 1)); + id = newId; } catch (IllegalArgumentException e) { // don't interpret the text following the dash as a version @@ -229,4 +226,10 @@ public final class ComponentId implements Comparable<ComponentId> { return new ComponentId(id,version,namespace); } + /** WARNING: For testing only: Resets counters creating anonymous component ids for this thread. */ + public static void resetGlobalCountersForTests() { + threadId.set("_0_"); + threadLocalUniqueId.set(new Counter()); + } + } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/DerivedConfiguration.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/DerivedConfiguration.java index 245913d7822..bb409ab6632 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/DerivedConfiguration.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/DerivedConfiguration.java @@ -15,9 +15,11 @@ import com.yahoo.search.query.profile.QueryProfileRegistry; import com.yahoo.searchdefinition.RankProfileRegistry; import com.yahoo.searchdefinition.Search; import com.yahoo.searchdefinition.derived.validation.Validation; +import com.yahoo.vespa.model.container.search.QueryProfiles; import java.io.IOException; import java.io.Writer; +import java.util.logging.Level; /** * A set of all derived configuration of a search definition. Use this as a facade to individual configurations when @@ -44,7 +46,7 @@ public class DerivedConfiguration { * Creates a complete derived configuration from a search definition. * Only used in tests. * - * @param search The search to derive a configuration from. Derived objects will be snapshots, but this argument is + * @param search the search to derive a configuration from. Derived objects will be snapshots, but this argument is * live. Which means that this object will be inconsistent when the given search definition is later * modified. * @param rankProfileRegistry a {@link com.yahoo.searchdefinition.RankProfileRegistry} @@ -56,11 +58,11 @@ public class DerivedConfiguration { /** * Creates a complete derived configuration snapshot from a search definition. * - * @param search The search to derive a configuration from. Derived objects will be snapshots, but this + * @param search the search to derive a configuration from. Derived objects will be snapshots, but this * argument is live. Which means that this object will be inconsistent when the given * search definition is later modified. * @param deployLogger a {@link DeployLogger} for logging when doing operations on this - * @param deployProperties Properties set on deploy. + * @param deployProperties properties set on deploy * @param rankProfileRegistry a {@link com.yahoo.searchdefinition.RankProfileRegistry} * @param queryProfiles the query profiles of this application */ @@ -120,6 +122,10 @@ public class DerivedConfiguration { exportCfg(new DocumenttypesConfig(documentTypesCfg), toDirectory + "/" + "documenttypes.cfg"); } + public static void exportQueryProfiles(QueryProfileRegistry queryProfileRegistry, String toDirectory) throws IOException { + exportCfg(new QueryProfiles(queryProfileRegistry, (level, message) -> {}).getConfig(), toDirectory + "/" + "query-profiles.cfg"); + } + private static void exportCfg(ConfigInstance instance, String fileName) throws IOException { Writer writer = null; try { 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 index 0abb0803405..0a9618e7b08 100644 --- 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 @@ -232,8 +232,7 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer return propB; } - private QueryProfilesConfig.Queryprofile.Queryprofilevariant.Property.Builder createVariantPropertyFieldConfig( - String fullName, Object value) { + 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 @@ -251,7 +250,7 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer qtB.matchaspath(true); for (QueryProfileType inherited : profileType.inherited()) qtB.inherit(inherited.getId().stringValue()); - List<FieldDescription> fields=new ArrayList<>(profileType.declaredFields().values()); + List<FieldDescription> fields = new ArrayList<>(profileType.declaredFields().values()); Collections.sort(fields); for (FieldDescription field : fields) qtB.field(createConfig(field)); @@ -260,22 +259,20 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer 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()); + 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()) + 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(); ) { + StringBuilder b = new StringBuilder(); + for (Iterator<String> i = list.iterator(); i.hasNext(); ) { b.append(i.next()); if (i.hasNext()) b.append(" "); @@ -290,10 +287,7 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer } } - /** - * The config produced by this - * @return query profiles config - */ + /** Returns the config produced by this */ public QueryProfilesConfig getConfig() { QueryProfilesConfig.Builder qB = new QueryProfilesConfig.Builder(); getConfig(qB); diff --git a/config-model/src/test/derived/neuralnet/query-profiles.cfg b/config-model/src/test/derived/neuralnet/query-profiles.cfg new file mode 100644 index 00000000000..ed69df7895d --- /dev/null +++ b/config-model/src/test/derived/neuralnet/query-profiles.cfg @@ -0,0 +1,53 @@ +queryprofile[].id "default" +queryprofile[].type "DefaultQueryProfileType" +queryprofiletype[].id "DefaultQueryProfileType" +queryprofiletype[].strict false +queryprofiletype[].matchaspath false +queryprofiletype[].field[].name "ranking" +queryprofiletype[].field[].type "query-profile:ranking_0_0" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +queryprofiletype[].id "ranking_0_0" +queryprofiletype[].strict false +queryprofiletype[].matchaspath false +queryprofiletype[].inherit[] "ranking" +queryprofiletype[].field[].name "features" +queryprofiletype[].field[].type "query-profile:features_0_1" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "rankfeature" +queryprofiletype[].id "features_0_1" +queryprofiletype[].strict false +queryprofiletype[].matchaspath false +queryprofiletype[].field[].name "query(W_0)" +queryprofiletype[].field[].type "tensor(hidden[9],x[9])" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +queryprofiletype[].field[].name "query(W_1)" +queryprofiletype[].field[].type "tensor(hidden[9],out[9])" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +queryprofiletype[].field[].name "query(W_out)" +queryprofiletype[].field[].type "tensor(out[9])" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +queryprofiletype[].field[].name "query(b_0)" +queryprofiletype[].field[].type "tensor(hidden[9])" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +queryprofiletype[].field[].name "query(b_1)" +queryprofiletype[].field[].type "tensor(out[9])" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +queryprofiletype[].field[].name "query(b_out)" +queryprofiletype[].field[].type "tensor(out[1])" +queryprofiletype[].field[].overridable true +queryprofiletype[].field[].mandatory false +queryprofiletype[].field[].alias "" +enableGroupingSessionCache true diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/AbstractExportingTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/AbstractExportingTestCase.java index d67df3a5239..8ea53172200 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/AbstractExportingTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/AbstractExportingTestCase.java @@ -10,6 +10,8 @@ import com.yahoo.searchdefinition.parser.ParseException; import ai.vespa.rankingexpression.importer.configmodelview.ImportedMlModels; import com.yahoo.vespa.configmodel.producers.DocumentManager; import com.yahoo.vespa.configmodel.producers.DocumentTypes; +import com.yahoo.vespa.model.container.search.QueryProfiles; +import com.yahoo.vespa.model.test.utils.DeployLoggerStub; import java.io.File; import java.io.IOException; @@ -53,6 +55,7 @@ public abstract class AbstractExportingTestCase extends SearchDefinitionTestCase String path = exportConfig(name, config); DerivedConfiguration.exportDocuments(new DocumentManager().produce(builder.getModel(), new DocumentmanagerConfig.Builder()), path); DerivedConfiguration.exportDocuments(new DocumentTypes().produce(builder.getModel(), new DocumenttypesConfig.Builder()), path); + DerivedConfiguration.exportQueryProfiles(builder.getQueryProfileRegistry(), path); return config; } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/NeuralNetTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/NeuralNetTestCase.java index b299c7fa299..5229485c8f9 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/NeuralNetTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/NeuralNetTestCase.java @@ -6,11 +6,14 @@ import org.junit.Test; import java.io.IOException; +import com.yahoo.component.ComponentId; + public class NeuralNetTestCase extends AbstractExportingTestCase { @Test public void testNeuralNet() throws IOException, ParseException { - assertCorrectDeriving("neuralnet"); + ComponentId.resetGlobalCountersForTests(); + DerivedConfiguration c = assertCorrectDeriving("neuralnet"); } } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java index 5d4f39cecbf..05e3c4fe9a0 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java @@ -9,6 +9,7 @@ import com.yahoo.search.query.Properties; import com.yahoo.search.query.profile.compiled.CompiledQueryProfile; import com.yahoo.search.query.profile.compiled.DimensionalValue; 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.ArrayList; @@ -87,8 +88,10 @@ public class QueryProfileProperties extends Properties { // Check types if ( ! profile.getTypes().isEmpty()) { - for (int i = 0; i<name.size(); i++) { - QueryProfileType type = profile.getType(name.first(i), context); + QueryProfileType type = null; + for (int i = 0; i < name.size(); i++) { + if (type == null) // We're on the first iteration, or no type is explicitly specified + type = profile.getType(name.first(i), context); if (type == null) continue; String localName = name.get(i); FieldDescription fieldDescription = type.getField(localName); @@ -97,12 +100,19 @@ public class QueryProfileProperties extends Properties { // TODO: In addition to strictness, check legality along the way - if (i == name.size()-1 && fieldDescription != null) { // at the end of the path, check the assignment type - value = fieldDescription.getType().convertFrom(value, profile.getRegistry()); - if (value == null) - throw new IllegalArgumentException("'" + value + "' is not a " + - fieldDescription.getType().toInstanceDescription()); + if (fieldDescription != null) { + if (i == name.size() - 1) { // at the end of the path, check the assignment type + value = fieldDescription.getType().convertFrom(value, profile.getRegistry()); + if (value == null) + throw new IllegalArgumentException("'" + value + "' is not a " + + fieldDescription.getType().toInstanceDescription()); + } + else if (fieldDescription.getType() instanceof QueryProfileFieldType) { + // If a type is specified, use that instead of the type implied by the name + type = ((QueryProfileFieldType) fieldDescription.getType()).getQueryProfileType(); + } } + } } 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 2418e460f07..e9f7ff24d42 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 @@ -436,6 +436,12 @@ public class XmlReadingTestCase { assertNull(type2.getFieldType(new CompoundName("ranking.features.query(tensor_1)"))); assertEquals("tensor<float>(x[2])", type2.getFieldType(new CompoundName("ranking.features.query(tensor_2)")).stringValue()); assertEquals("tensor<float>(x[3])", type2.getFieldType(new CompoundName("ranking.features.query(tensor_3)")).stringValue()); + + Query queryProfile1 = new Query("?query=test&ranking.features.query(tensor_1)=[1.200]", registry.getComponent("profile1")); + assertEquals("Is received as a tensor tensor", "tensor<float>(x[1]):[1.2]", queryProfile1.properties().get("ranking.features.query(tensor_1)").toString()); + + Query queryProfile2 = new Query("?query=test&ranking.features.query(tensor_1)=[1.200]", registry.getComponent("profile2")); + assertEquals("Is received as a string", "[1.200]", queryProfile2.properties().get("ranking.features.query(tensor_1)").toString()); } } diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java index 8299e32b421..3c200debcaf 100644 --- a/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java @@ -447,25 +447,25 @@ public class QueryProfileTypeTestCase { */ @Test public void testTypedOverridingOfQueryProfileReferencesNonStrictThroughQueryNestedInAnUntypedProfile() { - QueryProfile topMap=new QueryProfile("topMap"); + QueryProfile topMap = new QueryProfile("topMap"); - QueryProfile subMap=new QueryProfile("topSubMap"); - topMap.set("subMap",subMap, registry); + QueryProfile subMap = new QueryProfile("topSubMap"); + topMap.set("subMap", subMap, registry); - QueryProfile test=new QueryProfile("test"); + QueryProfile test = new QueryProfile("test"); test.setType(type); - subMap.set("typeProfile",test, registry); + subMap.set("typeProfile", test, registry); - QueryProfile myUser=new QueryProfile("myUser"); + QueryProfile myUser = new QueryProfile("myUser"); myUser.setType(user); - myUser.set("myUserString","userValue1", registry); - myUser.set("myUserInteger",442, registry); - test.set("myUserQueryProfile",myUser, registry); + myUser.set("myUserString", "userValue1", registry); + myUser.set("myUserInteger", 442, registry); + test.set("myUserQueryProfile", myUser, registry); - QueryProfile newUser=new QueryProfile("newUser"); + QueryProfile newUser = new QueryProfile("newUser"); newUser.setType(user); - newUser.set("myUserString","newUserValue1", registry); - newUser.set("myUserInteger",845, registry); + newUser.set("myUserString", "newUserValue1", registry); + newUser.set("myUserInteger", 845, registry); registry.register(topMap); registry.register(subMap); |