aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2021-10-30 16:31:38 +0200
committerGitHub <noreply@github.com>2021-10-30 16:31:38 +0200
commit1da6754a571bb380cc32d77b7aa76fe5ebaa24b0 (patch)
tree127022f9f9fe999f2db5666312d19d2be39ece82
parentd8970d73872e5386f36aaa73e2dc6b0e881069bf (diff)
parentc702f4874ea9f0cb263a3e54471eef5bb1c71d8c (diff)
Merge pull request #19792 from vespa-engine/bratseth/stable-query-profile-idsv7.492.78
Bratseth/stable query profile ids
-rw-r--r--component/abi-spec.json3
-rw-r--r--component/src/main/java/com/yahoo/component/AbstractComponent.java2
-rw-r--r--component/src/main/java/com/yahoo/component/ComponentId.java94
-rw-r--r--component/src/main/java/com/yahoo/component/provider/ComponentRegistry.java4
-rw-r--r--config-model/src/test/derived/neuralnet/query-profiles.cfg8
-rw-r--r--container-search/abi-spec.json16
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java17
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/OverridableQueryProfile.java18
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java21
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileRegistry.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileConfigurer.java2
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/config/QueryProfileXMLReader.java2
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileType.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/types/QueryProfileTypeRegistry.java7
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java18
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/child.xml5
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/parent.xml5
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/childType.xml4
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/typedinheritance/types/parentType.xml3
19 files changed, 164 insertions, 80 deletions
diff --git a/component/abi-spec.json b/component/abi-spec.json
index 0e33fde3c5a..4e89b0e717c 100644
--- a/component/abi-spec.json
+++ b/component/abi-spec.json
@@ -55,9 +55,9 @@
"final"
],
"methods": [
+ "public void <init>(java.lang.String)",
"public void <init>(java.lang.String, com.yahoo.component.Version, com.yahoo.component.ComponentId)",
"public void <init>(java.lang.String, com.yahoo.component.Version)",
- "public void <init>(java.lang.String)",
"public com.yahoo.component.ComponentId nestInNamespace(com.yahoo.component.ComponentId)",
"public java.lang.String getName()",
"public com.yahoo.component.Version getVersion()",
@@ -75,6 +75,7 @@
"public java.lang.String toFileName()",
"public static com.yahoo.component.ComponentId fromFileName(java.lang.String)",
"public static void resetGlobalCountersForTests()",
+ "public static com.yahoo.component.ComponentId newAnonymous(java.lang.String)",
"public bridge synthetic int compareTo(java.lang.Object)"
],
"fields": []
diff --git a/component/src/main/java/com/yahoo/component/AbstractComponent.java b/component/src/main/java/com/yahoo/component/AbstractComponent.java
index 254ef0e5db9..3fbae31a743 100644
--- a/component/src/main/java/com/yahoo/component/AbstractComponent.java
+++ b/component/src/main/java/com/yahoo/component/AbstractComponent.java
@@ -60,7 +60,7 @@ public class AbstractComponent implements Component, Deconstructable {
return id;
}
- //This should only happen in tests, so thread safety should not be an issue.
+ // This should only happen in tests, so thread safety should not be an issue.
private void setTestId() {
id = ComponentId.createAnonymousComponentId("test_" + getClass().getName());
}
diff --git a/component/src/main/java/com/yahoo/component/ComponentId.java b/component/src/main/java/com/yahoo/component/ComponentId.java
index a19c70895ba..7320d24b57c 100644
--- a/component/src/main/java/com/yahoo/component/ComponentId.java
+++ b/component/src/main/java/com/yahoo/component/ComponentId.java
@@ -13,31 +13,17 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public final class ComponentId implements Comparable<ComponentId> {
- private final class VersionHandler implements Spec.VersionHandler<Version> {
-
- @Override
- public Version emptyVersion() {
- return Version.emptyVersion;
- }
-
- @Override
- public int compare(Version v1, Version v2) {
- return v1.compareTo(v2);
- }
- }
-
private final Spec<Version> spec;
private final boolean anonymous;
- private final static class Counter {
- private int count = 0;
- public int getAndIncrement() { return count++; }
- }
+
+ private static AtomicInteger threadIdCounter = new AtomicInteger(0);
+
private static ThreadLocal<Counter> threadLocalUniqueId = new ThreadLocal<Counter>() {
@Override protected Counter initialValue() {
return new Counter();
}
};
- private static AtomicInteger threadIdCounter = new AtomicInteger(0);
+
private static ThreadLocal<String> threadId = new ThreadLocal<String>() {
@Override protected String initialValue() {
return new String("_" + threadIdCounter.getAndIncrement() + "_");
@@ -47,18 +33,17 @@ public final class ComponentId implements Comparable<ComponentId> {
/** Precomputed string value */
private final String stringValue;
- private ComponentId(String name, Version version, ComponentId namespace, boolean anonymous) {
- if (anonymous) {
- name = createAnonymousName(name);
- }
- spec = new Spec<>(new VersionHandler(), name, version, namespace);
- this.anonymous = anonymous;
-
- stringValue = spec.createStringValue();
+ /**
+ * Creates a component id from the id string form: name(:version)?(@namespace)?,
+ * where version has the form 1(.2(.3(.identifier)?)?)?
+ * and namespace is a component id
+ */
+ public ComponentId(String id) {
+ this(new SpecSplitter(id));
}
- private String createAnonymousName(String name) {
- return new StringBuilder(name).append(threadId.get()).append(threadLocalUniqueId.get().getAndIncrement()).toString();
+ private ComponentId(SpecSplitter splitter) {
+ this(splitter.name, Version.fromString(splitter.version), splitter.namespace);
}
public ComponentId(String name, Version version, ComponentId namespace) {
@@ -70,17 +55,10 @@ public final class ComponentId implements Comparable<ComponentId> {
this(name, version, null);
}
- /**
- * Creates a component id from the id string form: name(:version)?(@namespace)?,
- * where version has the form 1(.2(.3(.identifier)?)?)?
- * and namespace is a component id
- */
- public ComponentId(String id) {
- this(new SpecSplitter(id));
- }
-
- private ComponentId(SpecSplitter splitter) {
- this(splitter.name, Version.fromString(splitter.version), splitter.namespace);
+ private ComponentId(String id, Version version, ComponentId namespace, boolean anonymous) {
+ this.spec = new Spec<>(new VersionHandler(), id, version, namespace);
+ this.anonymous = anonymous;
+ this.stringValue = spec.createStringValue();
}
public ComponentId nestInNamespace(ComponentId namespace) {
@@ -116,12 +94,13 @@ public final class ComponentId implements Comparable<ComponentId> {
return spec.toString();
}
+ @Override
public boolean equals(Object o) {
- if (o==this) return true;
+ if (o == this) return true;
if ( ! (o instanceof ComponentId)) return false;
ComponentId c = (ComponentId) o;
- if (isAnonymous() || c.isAnonymous())
+ if (isAnonymous() || c.isAnonymous()) // TODO: Stop doing this
return false;
return c.stringValue().equals(stringValue);
@@ -150,7 +129,7 @@ public final class ComponentId implements Comparable<ComponentId> {
/** Creates a componentId that is unique for this run-time instance */
public static ComponentId createAnonymousComponentId(String baseName) {
- return new ComponentId(baseName, null, null, true);
+ return new ComponentId(createAnonymousId(baseName), null, null, true);
}
public boolean isAnonymous() {
@@ -232,4 +211,35 @@ public final class ComponentId implements Comparable<ComponentId> {
threadLocalUniqueId.set(new Counter());
}
+ private static String createAnonymousId(String name) {
+ return name + threadId.get() + threadLocalUniqueId.get().getAndIncrement();
+ }
+
+ /** Creates a component id with the given value, marked as anonymous */
+ public static ComponentId newAnonymous(String spec) {
+ var splitter = new SpecSplitter(spec);
+ return new ComponentId(splitter.name, Version.fromString(splitter.version), splitter.namespace, true);
+ }
+
+ private final class VersionHandler implements Spec.VersionHandler<Version> {
+
+ @Override
+ public Version emptyVersion() {
+ return Version.emptyVersion;
+ }
+
+ @Override
+ public int compare(Version v1, Version v2) {
+ return v1.compareTo(v2);
+ }
+
+ }
+
+ private final static class Counter {
+
+ private int count = 0;
+ public int getAndIncrement() { return count++; }
+
+ }
+
}
diff --git a/component/src/main/java/com/yahoo/component/provider/ComponentRegistry.java b/component/src/main/java/com/yahoo/component/provider/ComponentRegistry.java
index 9aa677737d6..ec6f21e4f53 100644
--- a/component/src/main/java/com/yahoo/component/provider/ComponentRegistry.java
+++ b/component/src/main/java/com/yahoo/component/provider/ComponentRegistry.java
@@ -28,10 +28,10 @@ import java.util.Set;
public class ComponentRegistry<COMPONENT> {
/** All versions of all components, indexed by name and namespace */
- private Map<ComponentId, Map<String, Map<Version, COMPONENT>>> componentsByNameByNamespace = new LinkedHashMap<>();
+ private final Map<ComponentId, Map<String, Map<Version, COMPONENT>>> componentsByNameByNamespace = new LinkedHashMap<>();
/** All versions of all components indexed by id */
- private Map<ComponentId, COMPONENT> componentsById =new LinkedHashMap<>();
+ private final Map<ComponentId, COMPONENT> componentsById =new LinkedHashMap<>();
/** True when this cannot be changed any more */
private boolean frozen = false;
diff --git a/config-model/src/test/derived/neuralnet/query-profiles.cfg b/config-model/src/test/derived/neuralnet/query-profiles.cfg
index 817640a89fd..94246ccd96b 100644
--- a/config-model/src/test/derived/neuralnet/query-profiles.cfg
+++ b/config-model/src/test/derived/neuralnet/query-profiles.cfg
@@ -5,20 +5,20 @@ queryprofiletype[].strict false
queryprofiletype[].matchaspath false
queryprofiletype[].inherit[] "native"
queryprofiletype[].field[].name "ranking"
-queryprofiletype[].field[].type "query-profile:ranking_0_0"
+queryprofiletype[].field[].type "query-profile:ranking_0"
queryprofiletype[].field[].overridable true
queryprofiletype[].field[].mandatory false
queryprofiletype[].field[].alias ""
-queryprofiletype[].id "ranking_0_0"
+queryprofiletype[].id "ranking_0"
queryprofiletype[].strict false
queryprofiletype[].matchaspath false
queryprofiletype[].inherit[] "ranking"
queryprofiletype[].field[].name "features"
-queryprofiletype[].field[].type "query-profile:features_0_1"
+queryprofiletype[].field[].type "query-profile:features_1"
queryprofiletype[].field[].overridable true
queryprofiletype[].field[].mandatory false
queryprofiletype[].field[].alias "rankfeature"
-queryprofiletype[].id "features_0_1"
+queryprofiletype[].id "features_1"
queryprofiletype[].strict false
queryprofiletype[].matchaspath false
queryprofiletype[].field[].name "query(W_0)"
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>