summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2019-08-22 15:00:08 +0200
committerJon Bratseth <bratseth@verizonmedia.com>2019-08-22 15:00:08 +0200
commitd503773b68f9f89a5607749e822c9dcbeba12dfc (patch)
tree379669b34d477bf911b4155e365b56d60e22226f /container-search
parent5fb8e66dbd2d6e02a64a054e147ac7214943d563 (diff)
Handle inherited variants with different dimensions
Diffstat (limited to 'container-search')
-rw-r--r--container-search/abi-spec.json4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java35
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java18
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java56
-rw-r--r--container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java11
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/config/test/XmlReadingTestCase.java10
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java168
8 files changed, 192 insertions, 111 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index de811cc3053..6c68260df32 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -4153,6 +4153,7 @@
],
"methods": [
"public void <init>(com.yahoo.statistics.Statistics, com.yahoo.jdisc.Metric, java.util.concurrent.Executor, com.yahoo.container.logging.AccessLog, com.yahoo.search.query.profile.config.QueryProfilesConfig, com.yahoo.container.core.ContainerHttpConfig, com.yahoo.search.searchchain.ExecutionFactory)",
+ "public void <init>(com.yahoo.statistics.Statistics, com.yahoo.jdisc.Metric, java.util.concurrent.Executor, com.yahoo.container.logging.AccessLog, com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry, com.yahoo.search.searchchain.ExecutionFactory, boolean, java.util.Optional)",
"public void <init>(com.yahoo.container.core.ChainsConfig, com.yahoo.search.config.IndexInfoConfig, com.yahoo.container.QrSearchersConfig, com.yahoo.vespa.configdefinition.SpecialtokensConfig, com.yahoo.statistics.Statistics, com.yahoo.language.Linguistics, com.yahoo.jdisc.Metric, com.yahoo.component.provider.ComponentRegistry, java.util.concurrent.Executor, com.yahoo.container.logging.AccessLog, com.yahoo.search.query.profile.config.QueryProfilesConfig, com.yahoo.component.provider.ComponentRegistry, com.yahoo.container.core.ContainerHttpConfig)",
"public final com.yahoo.container.jdisc.HttpResponse handle(com.yahoo.container.jdisc.HttpRequest)",
"public com.yahoo.search.Result searchAndFill(com.yahoo.search.Query, com.yahoo.component.chain.Chain)",
@@ -7621,7 +7622,8 @@
"public com.yahoo.search.searchchain.Execution newExecution(com.yahoo.component.chain.Chain)",
"public com.yahoo.search.searchchain.SearchChainRegistry searchChainRegistry()",
"public com.yahoo.search.rendering.RendererRegistry rendererRegistry()",
- "public void deconstruct()"
+ "public void deconstruct()",
+ "public static com.yahoo.search.searchchain.ExecutionFactory empty()"
],
"fields": []
},
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java
index 5dcc533fb1f..f9cfe843eb3 100644
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/searcher/QuotingSearcher.java
@@ -98,6 +98,7 @@ public class QuotingSearcher extends Searcher {
setQuoteTable(new QuoteTable(config));
}
+ @Override
public Result search(Query query, Execution execution) {
Result result = execution.search(query);
execution.fill(result);
diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
index 45303a3c646..a79c0d84054 100644
--- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
+++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
@@ -122,23 +122,40 @@ public class SearchHandler extends LoggingRequestHandler {
QueryProfilesConfig queryProfileConfig,
ContainerHttpConfig containerHttpConfig,
ExecutionFactory executionFactory) {
+ this(statistics,
+ metric,
+ executor,
+ accessLog,
+ QueryProfileConfigurer.createFromConfig(queryProfileConfig).compile(),
+ executionFactory,
+ queryProfileConfig.enableGroupingSessionCache(),
+ containerHttpConfig.hostResponseHeaderKey().equals("") ?
+ Optional.empty() : Optional.of( containerHttpConfig.hostResponseHeaderKey()));
+ }
+
+ public SearchHandler(Statistics statistics,
+ Metric metric,
+ Executor executor,
+ AccessLog accessLog,
+ CompiledQueryProfileRegistry queryProfileRegistry,
+ ExecutionFactory executionFactory,
+ boolean enableGroupingSessionCache,
+ Optional<String> hostResponseHeaderKey) {
super(executor, accessLog, metric, true);
log.log(LogLevel.DEBUG, "SearchHandler.init " + System.identityHashCode(this));
- this.enableGroupingSessionCache = queryProfileConfig.enableGroupingSessionCache();
- QueryProfileRegistry queryProfileRegistry = QueryProfileConfigurer.createFromConfig(queryProfileConfig);
- this.queryProfileRegistry = queryProfileRegistry.compile();
+ this.enableGroupingSessionCache = enableGroupingSessionCache;
+ this.queryProfileRegistry = queryProfileRegistry;
this.executionFactory = executionFactory;
this.maxThreads = examineExecutor(executor);
searchConnections = new Value(SEARCH_CONNECTIONS, statistics,
new Value.Parameters().setLogRaw(true).setLogMax(true)
- .setLogMean(true).setLogMin(true)
- .setNameExtension(true)
- .setCallback(new MeanConnections()));
-
- this.hostResponseHeaderKey = containerHttpConfig.hostResponseHeaderKey().equals("") ?
- Optional.empty() : Optional.of( containerHttpConfig.hostResponseHeaderKey());
+ .setLogMean(true).setLogMin(true)
+ .setNameExtension(true)
+ .setCallback(new MeanConnections()));
+
+ this.hostResponseHeaderKey = hostResponseHeaderKey;
}
/** @deprecated use the other constructor */
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 0e6af6113b5..acca2d403be 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
@@ -330,21 +330,21 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
return node;
}
- final Object get(CompoundName name,DimensionBinding dimensionBinding) {
- return lookup(name,false,dimensionBinding);
+ final Object get(CompoundName name, DimensionBinding dimensionBinding) {
+ return lookup(name, false, dimensionBinding);
}
/**
* Returns the node at the position prescribed by the given name (without doing substitutions) -
* a primitive value, a substitutable string, a query profile, or null if not found.
*/
- public final Object lookup(String name, Map<String,String> context) {
+ public final Object lookup(String name, Map<String, String> context) {
return lookup(new CompoundName(name),true,DimensionBinding.createFrom(getDimensions(),context));
}
/** Sets a value in this or any nested profile using null as context */
public final void set(String name, Object value, QueryProfileRegistry registry) {
- set(name,value,(Map<String,String>)null, registry);
+ set(name, value, (Map<String, String>)null, registry);
}
/**
@@ -357,16 +357,16 @@ 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);
}
- public final void set(String name,Object value,String[] dimensionValues, QueryProfileRegistry registry) {
- set(name,value,DimensionValues.createFrom(dimensionValues), registry);
+ public final void set(String name, Object value, String[] dimensionValues, QueryProfileRegistry registry) {
+ set(name, value, DimensionValues.createFrom(dimensionValues), registry);
}
/**
@@ -382,7 +382,7 @@ 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(String name,Object value,DimensionValues dimensionValues, QueryProfileRegistry registry) {
+ public final void set(String name,Object value, DimensionValues dimensionValues, QueryProfileRegistry registry) {
set(new CompoundName(name), value, DimensionBinding.createFrom(getDimensions(), dimensionValues), registry);
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java
index a7cfaf84e98..f75d04a1311 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java
@@ -38,8 +38,7 @@ public class QueryProfileCompiler {
DimensionalMap.Builder<CompoundName, Object> unoverridables = new DimensionalMap.Builder<>();
// Resolve values for each existing variant and combine into a single data structure
- Set<DimensionBindingForPath> variants = new HashSet<>();
- collectVariants(CompoundName.empty, in, DimensionBinding.nullBinding, variants);
+ Set<DimensionBindingForPath> variants = collectVariants(CompoundName.empty, in, DimensionBinding.nullBinding);
variants.add(new DimensionBindingForPath(DimensionBinding.nullBinding, CompoundName.empty)); // if this contains no variants
if (log.isLoggable(Level.FINE))
log.fine("Compiling " + in.toString() + " having " + variants.size() + " variants");
@@ -67,41 +66,68 @@ public class QueryProfileCompiler {
*
* @param profile the profile we are collecting the variants of
* @param currentVariant the variant we must have to arrive at this point in the query profile graph
- * @param allVariants the set of all variants accumulated so far
*/
- private static void collectVariants(CompoundName path, QueryProfile profile, DimensionBinding currentVariant, Set<DimensionBindingForPath> allVariants) {
+ private static Set<DimensionBindingForPath> collectVariants(CompoundName path, QueryProfile profile, DimensionBinding currentVariant) {
+ Set<DimensionBindingForPath> variants = new HashSet<>();
+ variants.addAll(collectVariantsFromValues(path, profile.getContent(), currentVariant));
+ variants.addAll(collectVariantsInThis(path, profile, currentVariant));
+ if (profile instanceof BackedOverridableQueryProfile)
+ variants.addAll(collectVariantsInThis(path, ((BackedOverridableQueryProfile) profile).getBacking(), currentVariant));
+
+ Set<DimensionBindingForPath> parentVariants = new HashSet<>();
for (QueryProfile inheritedProfile : profile.inherited())
- collectVariants(path, inheritedProfile, currentVariant, allVariants);
+ parentVariants = collectVariants(path, inheritedProfile, currentVariant);
+ variants.addAll(parentVariants);
+ variants.addAll(combined(variants, parentVariants)); // parents and children may have different variant dimensions
+ return variants;
+ }
- collectVariantsFromValues(path, profile.getContent(), currentVariant, allVariants);
+ /** Generates a set of all the (legal) combinations of the variants in the given sets */
+ private static Set<DimensionBindingForPath> combined(Set<DimensionBindingForPath> v1s,
+ Set<DimensionBindingForPath> v2s) {
+ Set<DimensionBindingForPath> combinedVariants = new HashSet<>();
+ for (DimensionBindingForPath v1 : v1s) {
+ for (DimensionBindingForPath v2 : v2s) {
+ if ( ! v1.path().equals(v2.path())) continue;
- collectVariantsInThis(path, profile, currentVariant, allVariants);
- if (profile instanceof BackedOverridableQueryProfile)
- collectVariantsInThis(path, ((BackedOverridableQueryProfile) profile).getBacking(), currentVariant, allVariants);
+ DimensionBinding combined = v1.binding().combineWith(v2.binding);
+ if ( combined.isInvalid() ) continue;
+
+ combinedVariants.add(new DimensionBindingForPath(combined, v1.path()));
+ }
+ }
+ return combinedVariants;
}
- private static void collectVariantsInThis(CompoundName path, QueryProfile profile, DimensionBinding currentVariant, Set<DimensionBindingForPath> allVariants) {
+ private static Set<DimensionBindingForPath> collectVariantsInThis(CompoundName path, QueryProfile profile, DimensionBinding currentVariant) {
QueryProfileVariants profileVariants = profile.getVariants();
+ Set<DimensionBindingForPath> variants = new HashSet<>();
if (profileVariants != null) {
for (QueryProfileVariant variant : profile.getVariants().getVariants()) {
DimensionBinding combinedVariant =
DimensionBinding.createFrom(profile.getDimensions(), variant.getDimensionValues()).combineWith(currentVariant);
if (combinedVariant.isInvalid()) continue; // values at this point in the graph are unreachable
- collectVariantsFromValues(path, variant.values(), combinedVariant, allVariants);
+
+ variants.addAll(collectVariantsFromValues(path, variant.values(), combinedVariant));
for (QueryProfile variantInheritedProfile : variant.inherited())
- collectVariants(path, variantInheritedProfile, combinedVariant, allVariants);
+ variants.addAll(collectVariants(path, variantInheritedProfile, combinedVariant));
}
}
+ return variants;
}
- private static void collectVariantsFromValues(CompoundName path, Map<String, Object> values, DimensionBinding currentVariant, Set<DimensionBindingForPath> allVariants) {
+ private static Set<DimensionBindingForPath> collectVariantsFromValues(CompoundName path,
+ Map<String, Object> values,
+ DimensionBinding currentVariant) {
+ Set<DimensionBindingForPath> variants = new HashSet<>();
if ( ! values.isEmpty())
- allVariants.add(new DimensionBindingForPath(currentVariant, path)); // there are actual values for this variant
+ variants.add(new DimensionBindingForPath(currentVariant, path)); // there are actual values for this variant
for (Map.Entry<String, Object> entry : values.entrySet()) {
if (entry.getValue() instanceof QueryProfile)
- collectVariants(path.append(entry.getKey()), (QueryProfile)entry.getValue(), currentVariant, allVariants);
+ variants.addAll(collectVariants(path.append(entry.getKey()), (QueryProfile)entry.getValue(), currentVariant));
}
+ return variants;
}
private static class DimensionBindingForPath {
diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java b/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
index 470e74bb974..c619bf69e59 100644
--- a/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
+++ b/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
@@ -10,6 +10,7 @@ import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.container.QrSearchersConfig;
import com.yahoo.container.core.ChainsConfig;
import com.yahoo.language.Linguistics;
+import com.yahoo.language.simple.SimpleLinguistics;
import com.yahoo.prelude.IndexFacts;
import com.yahoo.prelude.IndexModel;
import com.yahoo.prelude.query.parser.SpecialTokenRegistry;
@@ -76,4 +77,14 @@ public class ExecutionFactory extends AbstractComponent {
rendererRegistry.deconstruct();
}
+ public static ExecutionFactory empty() {
+ return new ExecutionFactory(new ChainsConfig.Builder().build(),
+ new IndexInfoConfig.Builder().build(),
+ new QrSearchersConfig.Builder().build(),
+ new ComponentRegistry<>(),
+ new SpecialtokensConfig.Builder().build(),
+ new SimpleLinguistics(),
+ new ComponentRegistry<>());
+ }
+
}
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 bc4c8cbc298..02aa95be510 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
@@ -3,6 +3,7 @@ package com.yahoo.search.query.profile.config.test;
import com.yahoo.jdisc.http.HttpRequest.Method;
import com.yahoo.container.jdisc.HttpRequest;
+import com.yahoo.processing.execution.Execution;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.yolean.Exceptions;
import com.yahoo.search.Query;
@@ -18,7 +19,12 @@ import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
-import static org.junit.Assert.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* @author bratseth
@@ -31,7 +37,7 @@ public class XmlReadingTestCase {
new QueryProfileXMLReader().read("src/test/java/com/yahoo/search/query/profile/config/test/validxml");
CompiledQueryProfileRegistry cRegistry= registry.compile();
- QueryProfileType rootType=registry.getType("rootType");
+ QueryProfileType rootType = registry.getType("rootType");
assertEquals(1,rootType.inherited().size());
assertEquals("native",rootType.inherited().get(0).getId().getName());
assertTrue(rootType.isStrict());
diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java
index 11dc1313f82..b14e73d156d 100644
--- a/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java
@@ -26,60 +26,78 @@ public class QueryProfileVariantsTestCase {
@Test
public void testSimple() {
- QueryProfile profile=new QueryProfile("a");
+ QueryProfile profile = new QueryProfile("a");
profile.set("a","a.deflt", null);
profile.setDimensions(new String[] {"x","y","z"});
- profile.set("a","a.1.*.*",new String[] {"x1",null,null}, null);
- profile.set("a","a.1.*.1",new String[] {"x1",null,"z1"}, null);
- profile.set("a","a.1.*.5",new String[] {"x1",null,"z5"}, null);
- profile.set("a","a.1.1.*",new String[] {"x1","y1",null}, null);
- profile.set("a","a.1.5.*",new String[] {"x1","y5",null}, null);
- profile.set("a","a.1.1.1",new String[] {"x1","y1","z1"}, null);
- profile.set("a","a.2.1.1",new String[] {"x2","y1","z1"}, null);
- profile.set("a","a.1.2.2",new String[] {"x1","y2","z2"}, null);
- profile.set("a","a.1.2.3",new String[] {"x1","y2","z3"}, null);
- profile.set("a","a.2.*.*",new String[] {"x2" }, null); // Same as ,null,null
+ profile.set("a","a.1.*.*", new String[] {"x1",null,null}, null);
+ profile.set("a","a.1.*.1", new String[] {"x1",null,"z1"}, null);
+ profile.set("a","a.1.*.5", new String[] {"x1",null,"z5"}, null);
+ profile.set("a","a.1.1.*", new String[] {"x1","y1",null}, null);
+ profile.set("a","a.1.5.*", new String[] {"x1","y5",null}, null);
+ profile.set("a","a.1.1.1", new String[] {"x1","y1","z1"}, null);
+ profile.set("a","a.2.1.1", new String[] {"x2","y1","z1"}, null);
+ profile.set("a","a.1.2.2", new String[] {"x1","y2","z2"}, null);
+ profile.set("a","a.1.2.3", new String[] {"x1","y2","z3"}, null);
+ profile.set("a","a.2.*.*", new String[] {"x2" }, null); // Same as ,null,null
CompiledQueryProfile cprofile = profile.compile(null);
// Perfect matches
- assertGet("a.deflt","a",new String[] {null,null,null}, profile, cprofile);
- assertGet("a.1.*.*","a",new String[] {"x1",null,null}, profile, cprofile);
- assertGet("a.1.1.*","a",new String[] {"x1","y1",null}, profile, cprofile);
- assertGet("a.1.5.*","a",new String[] {"x1","y5",null}, profile, cprofile);
- assertGet("a.1.*.1","a",new String[] {"x1",null,"z1"}, profile, cprofile);
- assertGet("a.1.*.5","a",new String[] {"x1",null,"z5"}, profile, cprofile);
- assertGet("a.1.1.1","a",new String[] {"x1","y1","z1"}, profile, cprofile);
- assertGet("a.2.1.1","a",new String[] {"x2","y1","z1"}, profile, cprofile);
- assertGet("a.1.2.2","a",new String[] {"x1","y2","z2"}, profile, cprofile);
- assertGet("a.1.2.3","a",new String[] {"x1","y2","z3"}, profile, cprofile);
- assertGet("a.2.*.*","a",new String[] {"x2",null,null}, profile, cprofile);
+ assertGet("a.deflt","a", new String[] {null,null,null}, profile, cprofile);
+ assertGet("a.1.*.*","a", new String[] {"x1",null,null}, profile, cprofile);
+ assertGet("a.1.1.*","a", new String[] {"x1","y1",null}, profile, cprofile);
+ assertGet("a.1.5.*","a", new String[] {"x1","y5",null}, profile, cprofile);
+ assertGet("a.1.*.1","a", new String[] {"x1",null,"z1"}, profile, cprofile);
+ assertGet("a.1.*.5","a", new String[] {"x1",null,"z5"}, profile, cprofile);
+ assertGet("a.1.1.1","a", new String[] {"x1","y1","z1"}, profile, cprofile);
+ assertGet("a.2.1.1","a", new String[] {"x2","y1","z1"}, profile, cprofile);
+ assertGet("a.1.2.2","a", new String[] {"x1","y2","z2"}, profile, cprofile);
+ assertGet("a.1.2.3","a", new String[] {"x1","y2","z3"}, profile, cprofile);
+ assertGet("a.2.*.*","a", new String[] {"x2",null,null}, profile, cprofile);
// Wildcard matches
- assertGet("a.deflt","a",new String[] {"x?","y?","z?"}, profile, cprofile);
- assertGet("a.deflt","a",new String[] {"x?","y1","z1"}, profile, cprofile);
- assertGet("a.1.*.*","a",new String[] {"x1","y?","z?"}, profile, cprofile);
- assertGet("a.1.*.*","a",new String[] {"x1","y?","z?"}, profile, cprofile);
- assertGet("a.1.1.*","a",new String[] {"x1","y1","z?"}, profile, cprofile);
- assertGet("a.1.*.1","a",new String[] {"x1","y?","z1"}, profile, cprofile);
- assertGet("a.1.5.*","a",new String[] {"x1","y5","z?"}, profile, cprofile);
- assertGet("a.1.*.5","a",new String[] {"x1","y?","z5"}, profile, cprofile);
- assertGet("a.1.5.*","a",new String[] {"x1","y5","z5"}, profile, cprofile); // Left dimension gets precedence
- assertGet("a.2.*.*","a",new String[] {"x2","y?","z?"}, profile, cprofile);
+ assertGet("a.deflt","a", new String[] {"x?","y?","z?"}, profile, cprofile);
+ assertGet("a.deflt","a", new String[] {"x?","y1","z1"}, profile, cprofile);
+ assertGet("a.1.*.*","a", new String[] {"x1","y?","z?"}, profile, cprofile);
+ assertGet("a.1.*.*","a", new String[] {"x1","y?","z?"}, profile, cprofile);
+ assertGet("a.1.1.*","a", new String[] {"x1","y1","z?"}, profile, cprofile);
+ assertGet("a.1.*.1","a", new String[] {"x1","y?","z1"}, profile, cprofile);
+ assertGet("a.1.5.*","a", new String[] {"x1","y5","z?"}, profile, cprofile);
+ assertGet("a.1.*.5","a", new String[] {"x1","y?","z5"}, profile, cprofile);
+ assertGet("a.1.5.*","a", new String[] {"x1","y5","z5"}, profile, cprofile); // Left dimension gets precedence
+ assertGet("a.2.*.*","a", new String[] {"x2","y?","z?"}, profile, cprofile);
+ }
+
+ @Test
+ public void testInheritedVariants() {
+ QueryProfile parent = new QueryProfile("parent");
+ parent.setDimensions(new String[] { "parentDim" });
+ parent.set("property", "defaultValue", null);
+ parent.set("property", "variantValue", new String[] {"V2" }, null);
+
+ QueryProfile child = new QueryProfile("child");
+ child.addInherited(parent);
+ child.setDimensions(new String[] { "childDim" });
+ child.set("otherProperty", "otherPropertyValue", new String[] { "V1" }, null);
+
+ CompiledQueryProfile cchild = child.compile(null);
+ assertEquals("defaultValue", new Query("?query=test", cchild).properties().get("property"));
+ assertEquals("variantValue", new Query("?parentDim=V2", cchild).properties().get("property"));
+ assertEquals("variantValue", new Query("?parentDim=V2&childDim=V1", cchild).properties().get("property"));
}
@Test
public void testVariantsOfInlineCompound() {
- QueryProfile profile=new QueryProfile("test");
+ QueryProfile profile = new QueryProfile("test");
profile.setDimensions(new String[] {"x"});
- profile.set("a.b","a.b", null);
- profile.set("a.b","a.b.x1",new String[] {"x1"}, null);
- profile.set("a.b","a.b.x2",new String[] {"x2"}, null);
+ profile.set("a.b", "a.b", null);
+ profile.set("a.b", "a.b.x1", new String[] {"x1"}, null);
+ profile.set("a.b", "a.b.x2", new String[] {"x2"}, null);
CompiledQueryProfile cprofile = profile.compile(null);
- assertEquals("a.b",cprofile.get("a.b"));
- assertEquals("a.b.x1",cprofile.get("a.b", toMap("x=x1")));
- assertEquals("a.b.x2",cprofile.get("a.b", toMap("x=x2")));
+ assertEquals("a.b", cprofile.get("a.b"));
+ assertEquals("a.b.x1", cprofile.get("a.b", toMap("x=x1")));
+ assertEquals("a.b.x2", cprofile.get("a.b", toMap("x=x2")));
}
@Test
@@ -105,7 +123,7 @@ public class QueryProfileVariantsTestCase {
@Test
public void testVariantsOfExplicitCompound() {
- QueryProfile a1=new QueryProfile("a1");
+ QueryProfile a1 = new QueryProfile("a1");
a1.set("b","a.b", null);
QueryProfile profile=new QueryProfile("test");
@@ -116,50 +134,50 @@ public class QueryProfileVariantsTestCase {
CompiledQueryProfile cprofile = profile.compile(null);
- assertEquals("a.b",cprofile.get("a.b"));
- assertEquals("a.b.x1",cprofile.get("a.b", toMap("x=x1")));
- assertEquals("a.b.x2",cprofile.get("a.b", toMap("x=x2")));
+ assertEquals("a.b", cprofile.get("a.b"));
+ assertEquals("a.b.x1", cprofile.get("a.b", toMap("x=x1")));
+ assertEquals("a.b.x2", cprofile.get("a.b", toMap("x=x2")));
}
@Test
public void testCompound() {
// Configuration phase
- QueryProfile profile=new QueryProfile("test");
+ QueryProfile profile = new QueryProfile("test");
profile.setDimensions(new String[] {"x","y"});
- QueryProfile a1=new QueryProfile("a1");
- a1.set("b","a1.b.default", null);
- a1.set("c","a1.c.default", null);
- a1.set("d","a1.d.default", null);
- a1.set("e","a1.e.default", null);
+ QueryProfile a1 = new QueryProfile("a1");
+ a1.set("b", "a1.b.default", null);
+ a1.set("c", "a1.c.default", null);
+ a1.set("d", "a1.d.default", null);
+ a1.set("e", "a1.e.default", null);
- QueryProfile a2=new QueryProfile("a2");
- a2.set("b","a2.b.default", null);
- a2.set("c","a2.c.default", null);
- a2.set("d","a2.d.default", null);
- a2.set("e","a2.e.default", null);
+ QueryProfile a2 = new QueryProfile("a2");
+ a2.set("b", "a2.b.default", null);
+ a2.set("c", "a2.c.default", null);
+ a2.set("d", "a2.d.default", null);
+ a2.set("e", "a2.e.default", null);
profile.set("a",a1, null); // Must set profile references before overrides
- profile.set("a.b","a.b.default-override", null);
- profile.set("a.c","a.c.default-override", null);
- profile.set("a.d","a.d.default-override", null);
- profile.set("a.g","a.g.default-override", null);
+ profile.set("a.b", "a.b.default-override", null);
+ profile.set("a.c", "a.c.default-override", null);
+ profile.set("a.d", "a.d.default-override", null);
+ profile.set("a.g", "a.g.default-override", null);
- String[] d1=new String[] { "x1","y1" };
- profile.set("a",a1,d1, null);
- profile.set("a.b","x1.y1.a.b.default-override",d1, null);
- profile.set("a.c","x1.y1.a.c.default-override",d1, null);
- profile.set("a.g","x1.y1.a.g.default-override",d1, null); // This value is never manifest because the runtime override overrides all variants
+ String[] d1 = new String[] { "x1","y1" };
+ profile.set("a", a1, d1, null);
+ profile.set("a.b", "x1.y1.a.b.default-override", d1, null);
+ profile.set("a.c", "x1.y1.a.c.default-override", d1, null);
+ profile.set("a.g", "x1.y1.a.g.default-override", d1, null); // This value is never manifest because the runtime override overrides all variants
- String[] d2=new String[] { "x1","y2" };
- profile.set("a.b","x1.y2.a.b.default-override",d2, null);
- profile.set("a.c","x1.y2.a.c.default-override",d2, null);
+ String[] d2 = new String[] { "x1","y2" };
+ profile.set("a.b","x1.y2.a.b.default-override", d2, null);
+ profile.set("a.c","x1.y2.a.c.default-override", d2, null);
- String[] d3=new String[] { "x2","y1" };
- profile.set("a",a2,d3, null);
- profile.set("a.b","x2.y1.a.b.default-override",d3, null);
- profile.set("a.c","x2.y1.a.c.default-override",d3, null);
+ String[] d3 = new String[] { "x2","y1" };
+ profile.set("a", a2, d3, null);
+ profile.set("a.b", "x2.y1.a.b.default-override", d3, null);
+ profile.set("a.c", "x2.y1.a.c.default-override", d3, null);
// Runtime phase - four simultaneous requests using different variants makes their own overrides
@@ -172,8 +190,8 @@ public class QueryProfileVariantsTestCase {
d1RuntimeProfile.set("a.g", "a.g.d1.runtime-override", toMap("x=x1", "y=y1"));
QueryProfileProperties d2RuntimeProfile = new QueryProfileProperties(profile.compile(null));
- d2RuntimeProfile.set("a.f", "a.f.d2.runtime-override",toMap("x=x1", "y=y2"));
- d2RuntimeProfile.set("a.g", "a.g.d2.runtime-override",toMap("x=x1", "y=y2"));
+ d2RuntimeProfile.set("a.f", "a.f.d2.runtime-override", toMap("x=x1", "y=y2"));
+ d2RuntimeProfile.set("a.g", "a.g.d2.runtime-override", toMap("x=x1", "y=y2"));
QueryProfileProperties d3RuntimeProfile = new QueryProfileProperties(profile.compile(null));
d3RuntimeProfile.set("a.f", "a.f.d3.runtime-override", toMap("x=x2", "y=y1"));
@@ -246,9 +264,9 @@ public class QueryProfileVariantsTestCase {
CompiledQueryProfile cchild = child.compile(null);
- assertEquals("a.default",cchild.get("a"));
- assertEquals("a.x1.y1",cchild.get("a", toMap("x=x1","y=y1")));
- assertEquals("a.x1.y2",cchild.get("a", toMap("x=x1","y=y2")));
+ assertEquals("a.default", cchild.get("a"));
+ assertEquals("a.x1.y1", cchild.get("a", toMap("x=x1","y=y1")));
+ assertEquals("a.x1.y2", cchild.get("a", toMap("x=x1","y=y2")));
}
@Test