diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2021-10-30 16:31:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-30 16:31:38 +0200 |
commit | 1da6754a571bb380cc32d77b7aa76fe5ebaa24b0 (patch) | |
tree | 127022f9f9fe999f2db5666312d19d2be39ece82 /container-search | |
parent | d8970d73872e5386f36aaa73e2dc6b0e881069bf (diff) | |
parent | c702f4874ea9f0cb263a3e54471eef5bb1c71d8c (diff) |
Merge pull request #19792 from vespa-engine/bratseth/stable-query-profile-idsv7.492.78
Bratseth/stable query profile ids
Diffstat (limited to 'container-search')
14 files changed, 103 insertions, 30 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json index 8ebb11cc8c5..6694a37469b 100644 --- a/container-search/abi-spec.json +++ b/container-search/abi-spec.json @@ -5840,8 +5840,8 @@ "public" ], "methods": [ - "protected void <init>()", - "protected void <init>(java.lang.String)", + "protected void <init>(com.yahoo.search.query.profile.QueryProfileRegistry)", + "protected void <init>(java.lang.String, com.yahoo.search.query.profile.QueryProfileRegistry)", "protected java.lang.Object checkAndConvertAssignment(java.lang.String, java.lang.Object, com.yahoo.search.query.profile.QueryProfileRegistry)", "protected com.yahoo.search.query.profile.QueryProfile createSubProfile(java.lang.String, com.yahoo.search.query.profile.DimensionBinding)", "public com.yahoo.search.query.profile.OverridableQueryProfile clone()", @@ -5865,7 +5865,9 @@ "public void <init>(com.yahoo.component.ComponentId)", "public void <init>(java.lang.String)", "public void <init>(com.yahoo.component.ComponentId, java.lang.String)", + "public void <init>(com.yahoo.component.ComponentId, java.lang.String, com.yahoo.search.query.profile.QueryProfileRegistry)", "public java.lang.String getSource()", + "protected final com.yahoo.search.query.profile.QueryProfileRegistry getOwner()", "public com.yahoo.search.query.profile.types.QueryProfileType getType()", "public void setType(com.yahoo.search.query.profile.types.QueryProfileType)", "public com.yahoo.search.query.profile.QueryProfileVariants getVariants()", @@ -5923,7 +5925,9 @@ "public bridge synthetic com.yahoo.component.AbstractComponent clone()", "public bridge synthetic java.lang.Object clone()" ], - "fields": [] + "fields": [ + "public final com.yahoo.search.query.profile.QueryProfileRegistry owner" + ] }, "com.yahoo.search.query.profile.QueryProfileCompiler": { "superClass": "java.lang.Object", @@ -5973,7 +5977,8 @@ "public com.yahoo.search.query.profile.types.QueryProfileTypeRegistry getTypeRegistry()", "public com.yahoo.search.query.profile.QueryProfile findQueryProfile(java.lang.String)", "public void freeze()", - "public com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry compile()" + "public com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry compile()", + "public com.yahoo.component.ComponentId createAnonymousId(java.lang.String)" ], "fields": [] }, @@ -6498,7 +6503,8 @@ "public void register(com.yahoo.search.query.profile.types.QueryProfileType)", "public boolean hasApplicationTypes()", "public void freeze()", - "public static com.yahoo.search.query.profile.types.QueryProfileTypeRegistry emptyFrozen()" + "public static com.yahoo.search.query.profile.types.QueryProfileTypeRegistry emptyFrozen()", + "public com.yahoo.component.ComponentId createAnonymousId(java.lang.String)" ], "fields": [] }, diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java index 08bdca78ee6..8f22c6902c3 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java @@ -2,20 +2,17 @@ package com.yahoo.search.query.profile; import com.yahoo.processing.request.CompoundName; -import com.yahoo.protect.Validator; import java.util.HashMap; import java.util.List; import java.util.Map; /** - * <p>A wrapper of a query profile where overrides to the values in the referenced - * profile can be set.</p> - * - * <p>This is used to allow configured overrides (in a particular referencing profile) of a referenced query profile. - * - * <p>Properties which are defined as not overridable in the type (if any) of the referenced query profile - * cannot be set.</p> + * A wrapper of a query profile where overrides to the values in the referenced + * profile can be set. + * This is used to allow configured overrides (in a particular referencing profile) of a referenced query profile. + * Properties which are defined as not overridable in the type (if any) of the referenced query profile + * cannot be set. * * @author bratseth */ @@ -31,7 +28,7 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple * @param backingProfile the backing profile, which is assumed read only, never null */ public BackedOverridableQueryProfile(QueryProfile backingProfile) { - Validator.ensureNotNull("An overridable query profile must be backed by a real query profile", backingProfile); + super(backingProfile.getOwner()); setType(backingProfile.getType()); this.backingProfile = backingProfile; } @@ -66,7 +63,7 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple if (backing instanceof QueryProfile) return new BackedOverridableQueryProfile((QueryProfile)backing); else - return new OverridableQueryProfile(); // Nothing is set in this branch, so nothing to override, but need override checking + return new OverridableQueryProfile(getOwner()); // Nothing is set in this branch, so nothing to override, but need override checking } /** Returns a clone of this which can be independently overridden, but which refers to the same backing profile */ diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java index b8de533dfbe..ac0712eeb63 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java @@ -16,12 +16,12 @@ public class OverridableQueryProfile extends QueryProfile { private static final String simpleClassName = OverridableQueryProfile.class.getSimpleName(); /** Creates an unbacked overridable query profile */ - protected OverridableQueryProfile() { - this(""); + protected OverridableQueryProfile(QueryProfileRegistry owner) { + this("", owner); } - protected OverridableQueryProfile(String sourceName) { - super(ComponentId.createAnonymousComponentId(simpleClassName), sourceName); + protected OverridableQueryProfile(String sourceName, QueryProfileRegistry owner) { + super(createAnonymousId(owner), sourceName, owner); } @Override @@ -35,7 +35,8 @@ public class OverridableQueryProfile extends QueryProfile { @Override protected QueryProfile createSubProfile(String name, DimensionBinding binding) { - return new OverridableQueryProfile(getSource()); // Nothing is set in this branch, so nothing to override, but need override checking + // Nothing is set in this branch, so nothing to override, but need override checking + return new OverridableQueryProfile(getSource(), getOwner()); } /** Returns a clone of this which can be independently overridden */ @@ -43,7 +44,7 @@ public class OverridableQueryProfile extends QueryProfile { public OverridableQueryProfile clone() { if (isFrozen()) return this; OverridableQueryProfile clone = (OverridableQueryProfile)super.clone(); - clone.initId(ComponentId.createAnonymousComponentId(simpleClassName)); + clone.initId(createAnonymousId(getOwner())); return clone; } @@ -52,4 +53,9 @@ public class OverridableQueryProfile extends QueryProfile { return "an overridable query profile with no backing"; } + private static ComponentId createAnonymousId(QueryProfileRegistry owner) { + return owner != null ? owner.createAnonymousId(simpleClassName) + : ComponentId.createAnonymousComponentId(simpleClassName); + } + } 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 ee7d44f457f..c30a78da57d 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 @@ -45,6 +45,9 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable /** The name of the source of this (a file) */ private final String source; + /** The query profile registry owning this, or null if none (which will only happen in tests) */ + public final QueryProfileRegistry owner; + /** Defines the permissible content of this, or null if any content is permissible */ private QueryProfileType type = null; @@ -84,8 +87,13 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable } public QueryProfile(ComponentId id, String sourceName) { + this(id, sourceName, null); + } + + public QueryProfile(ComponentId id, String sourceName, QueryProfileRegistry owner) { super(id); this.source = sourceName; + this.owner = owner; if ( ! id.isAnonymous()) validateName(id.getName()); } @@ -96,6 +104,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable public String getSource() { return source; } + protected final QueryProfileRegistry getOwner() { return owner; } + /** Returns the type of this or null if it has no type */ public QueryProfileType getType() { return type; } @@ -144,6 +154,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() { @@ -390,7 +401,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * Switches this from write-only to read-only mode. * This profile can never be modified again after this method returns. * Calling this on an already frozen profile has no effect. - * <p> + * * Calling this will also freeze any profiles inherited and referenced by this. */ // TODO: Remove/simplify as query profiles are not used at query time @@ -624,7 +635,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable QueryProfile newProfile = (QueryProfile)newValue; if ( ! (existingValue instanceof QueryProfile)) { if ( ! isModifiable(newProfile)) { - newProfile = new BackedOverridableQueryProfile(newProfile); // Make the query profile reference overridable + // Make the query profile reference overridable + newProfile = new BackedOverridableQueryProfile(newProfile); } newProfile.value = existingValue; return newProfile; @@ -652,7 +664,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable } } - private static QueryProfile combineProfiles(QueryProfile newProfile,QueryProfile existingProfile) { + private static QueryProfile combineProfiles(QueryProfile newProfile, QueryProfile existingProfile) { QueryProfile returnValue = null; QueryProfile existingModifiable; @@ -720,7 +732,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * This default implementation returns an empty profile. */ protected QueryProfile createSubProfile(String name, DimensionBinding dimensionBinding) { - return new QueryProfile(ComponentId.createAnonymousComponentId(name), source); + var id = owner != null ? owner.createAnonymousId(name) : ComponentId.createAnonymousComponentId(name); + return new QueryProfile(id, source, owner); } /** Do a variant-aware content lookup in this */ 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 83b3cd8c4d0..1910078058a 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 @@ -1,12 +1,15 @@ // Copyright Yahoo. 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.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry; import com.yahoo.search.query.profile.types.QueryProfileType; import com.yahoo.search.query.profile.types.QueryProfileTypeRegistry; +import java.util.concurrent.atomic.AtomicInteger; + /** * A set of query profiles. This also holds the query profile types as a dependent registry * @@ -14,7 +17,9 @@ import com.yahoo.search.query.profile.types.QueryProfileTypeRegistry; */ public class QueryProfileRegistry extends ComponentRegistry<QueryProfile> { - private QueryProfileTypeRegistry queryProfileTypeRegistry = new QueryProfileTypeRegistry(); + private int nextAnonymousId = 0; + + private final QueryProfileTypeRegistry queryProfileTypeRegistry = new QueryProfileTypeRegistry(); /** Register this type by its id */ public void register(QueryProfile profile) { @@ -83,4 +88,8 @@ public class QueryProfileRegistry extends ComponentRegistry<QueryProfile> { public CompiledQueryProfileRegistry compile() { return QueryProfileCompiler.compile(this); } + public ComponentId createAnonymousId(String name) { + return ComponentId.newAnonymous(name + "_" + (nextAnonymousId++)); + } + } 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 f840885f2e4..ceeed9d9167 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 @@ -74,7 +74,7 @@ public class QueryProfileConfigurer implements ConfigSubscriber.SingleSubscriber } private static void createProfile(QueryProfilesConfig.Queryprofile config, QueryProfileRegistry registry) { - QueryProfile profile = new QueryProfile(new ComponentId(config.id()), config.id()); + QueryProfile profile = new QueryProfile(new ComponentId(config.id()), config.id(), registry); try { String typeId = config.type(); if (typeId != null && ! typeId.isEmpty()) 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 555d3a8e6b7..c94987ce88e 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 @@ -135,7 +135,7 @@ public class QueryProfileXMLReader { ComponentId id = new ComponentId(idString); validateFileNameToId(reader.getName(), id, "query profile"); - QueryProfile queryProfile = new QueryProfile(id, reader.getName()); + QueryProfile queryProfile = new QueryProfile(id, reader.getName(), registry); String typeId = root.getAttribute("type"); if (typeId != null && ! typeId.equals("")) { QueryProfileType type = registry.getType(typeId); diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java b/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java index c9fcb854771..8b6470996d5 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java @@ -321,13 +321,13 @@ public class QueryProfileType extends FreezableSimpleComponent { // found in registry but not already added in *this* type (getField also checks parents): extend it if (type != null && ! fields.containsKey(name)) { - type = new QueryProfileType(ComponentId.createAnonymousComponentId(type.getIdString()), + type = new QueryProfileType(registry.createAnonymousId(type.getIdString()), new HashMap<>(), List.of(type)); } if (type == null) { // create it - type = new QueryProfileType(ComponentId.createAnonymousComponentId(name)); + type = new QueryProfileType(registry.createAnonymousId(name)); } if (fieldDescription == null) { diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileTypeRegistry.java b/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileTypeRegistry.java index 58a1ae7ad14..201f246b30c 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileTypeRegistry.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileTypeRegistry.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.query.profile.types; +import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.search.Query; import com.yahoo.search.query.profile.QueryProfileRegistry; @@ -12,6 +13,8 @@ import com.yahoo.search.query.profile.QueryProfileRegistry; */ public class QueryProfileTypeRegistry extends ComponentRegistry<QueryProfileType> { + private int nextAnonymousId = 0; + private final int nativeProfileCount; public QueryProfileTypeRegistry() { @@ -42,4 +45,8 @@ public class QueryProfileTypeRegistry extends ComponentRegistry<QueryProfileType return registry; } + public ComponentId createAnonymousId(String name) { + return ComponentId.newAnonymous(name + "_" + (nextAnonymousId++)); + } + } 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 e04835c01b2..c47e1e5b23c 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 @@ -449,6 +449,24 @@ public class XmlReadingTestCase { query = new Query(HttpRequest.createTestRequest("?query=test&profileRef=ref:MyProfile2", Method.GET), registry.getComponent("default")); assertEquals("MyProfile2", query.properties().get("profileRef.name")); } + + } + + @Test + public void testAnonymousIdsAreStableBetweenImports() { + QueryProfileRegistry registry1 = new QueryProfileXMLReader().read("src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance"); + var childIn1 = registry1.findQueryProfile("child"); + var childTypeIn1 = registry1.getType("childType"); + + QueryProfileRegistry registry2 = new QueryProfileXMLReader().read("src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance"); + var childIn2 = registry2.findQueryProfile("child"); + var childTypeIn2 = registry2.getType("childType"); + + assertEquals(((QueryProfile)childIn1.lookup("a", Map.of())).getId().stringValue(), + ((QueryProfile)childIn2.lookup("a", Map.of())).getId().stringValue()); + + assertEquals(childTypeIn1.getType("a").getId().stringValue(), + childTypeIn2.getType("a").getId().stringValue()); } @Test diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml new file mode 100644 index 00000000000..20186c440df --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml @@ -0,0 +1,5 @@ +<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<query-profile id="child" inherits="parent" type="childType"> + <field name="a.b.c">a.b.c-child</field> +</query-profile> + diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml new file mode 100644 index 00000000000..21a19eda24f --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml @@ -0,0 +1,5 @@ +<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<query-profile id="parent" type="parentType"> + <field name="a.b">a.b-parent</field> + <field name="a.b.c">a.b.c-parent</field> +</query-profile> diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/childType.xml b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/childType.xml new file mode 100644 index 00000000000..18665d195b9 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/childType.xml @@ -0,0 +1,4 @@ +<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<query-profile-type id="childType" inherits="parentType"> + <field name="a.b.c" type="string"/> +</query-profile-type> diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/parentType.xml b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/parentType.xml new file mode 100644 index 00000000000..771c373df12 --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/parentType.xml @@ -0,0 +1,3 @@ +<!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<query-profile-type id="parentType"> +</query-profile-type> |