aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2021-01-08 22:30:14 +0100
committerJon Marius Venstad <venstad@gmail.com>2021-01-08 22:30:14 +0100
commit76b84365234ce53cd6b2509947beed9ad2c28d4e (patch)
treed920876275f2d7d4861c2e9b658ee113716c77d5 /container-search/src/main/java/com/yahoo/search
parent4cd39189f1dcf1659fe689a1e6c12a504b63f4d0 (diff)
Cache CompoundName and Binding instances created during compilation
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java3
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/PrefixQueryProfileVisitor.java22
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java10
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileCompiler.java14
5 files changed, 33 insertions, 22 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java
index 68bf112133a..40e22e8bcb5 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/AllValuesQueryProfileVisitor.java
@@ -16,8 +16,8 @@ final class AllValuesQueryProfileVisitor extends PrefixQueryProfileVisitor {
private final Map<String, ValueWithSource> values = new HashMap<>();
/* Lists all values starting at prefix */
- public AllValuesQueryProfileVisitor(CompoundName prefix) {
- super(prefix);
+ public AllValuesQueryProfileVisitor(CompoundName prefix, Map<CompoundName, Map<String, CompoundName>> pathCache) {
+ super(prefix, pathCache);
}
@Override
@@ -43,7 +43,7 @@ final class AllValuesQueryProfileVisitor extends PrefixQueryProfileVisitor {
QueryProfile owner,
DimensionValues variant,
DimensionBinding binding) {
- CompoundName fullName = currentPrefix.append(key);
+ CompoundName fullName = cache.computeIfAbsent(currentPrefix, __ -> new HashMap<>()).computeIfAbsent(key, currentPrefix::append);
ValueWithSource existing = values.get(fullName.toString());
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java
index c6f3d923817..43462e8f327 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionBinding.java
@@ -4,6 +4,7 @@ package com.yahoo.search.query.profile;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* An immutable, binding of a list of dimensions to dimension values
@@ -203,7 +204,7 @@ public class DimensionBinding {
@Override
public int hashCode() {
- return dimensions.hashCode() + 17 * values.hashCode();
+ return Objects.hash(dimensions, values);
}
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/PrefixQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/PrefixQueryProfileVisitor.java
index 690a48f8124..c6c2eba0ea7 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/PrefixQueryProfileVisitor.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/PrefixQueryProfileVisitor.java
@@ -3,6 +3,11 @@ package com.yahoo.search.query.profile;
import com.yahoo.processing.request.CompoundName;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* A query profile visitor which keeps track of name prefixes and can skip values outside a given prefix
*
@@ -10,18 +15,22 @@ import com.yahoo.processing.request.CompoundName;
*/
abstract class PrefixQueryProfileVisitor extends QueryProfileVisitor {
+ protected final Map<CompoundName, Map<String, CompoundName>> cache;
+
/** Only call onValue/onQueryProfile for nodes having this prefix */
private final CompoundName prefix;
/** The current prefix, relative to prefix. */
protected CompoundName currentPrefix = CompoundName.empty;
+ private final Deque<CompoundName> currentPrefixes = new ArrayDeque<>();
private int prefixComponentIndex = -1;
- public PrefixQueryProfileVisitor(CompoundName prefix) {
+ public PrefixQueryProfileVisitor(CompoundName prefix, Map<CompoundName, Map<String, CompoundName>> cache) {
if (prefix == null)
prefix = CompoundName.empty;
this.prefix = prefix;
+ this.cache = cache;
}
@Override
@@ -40,18 +49,17 @@ abstract class PrefixQueryProfileVisitor extends QueryProfileVisitor {
@Override
public final boolean enter(String name) {
- prefixComponentIndex++;
- if (prefixComponentIndex-1 < prefix.size()) return true; // we're in the given prefix, which should not be included in the name
- currentPrefix = currentPrefix.append(name);
+ if (prefixComponentIndex++ < prefix.size()) return true; // we're in the given prefix, which should not be included in the name
+ currentPrefixes.push(currentPrefix);
+ currentPrefix = cache.computeIfAbsent(currentPrefix, __ -> new HashMap<>()).computeIfAbsent(name, currentPrefix::append);
return true;
}
@Override
public final void leave(String name) {
- prefixComponentIndex--;
- if (prefixComponentIndex < prefix.size()) return; // we're in the given prefix, which should not be included in the name
+ if (--prefixComponentIndex < prefix.size()) return; // we're in the given prefix, which should not be included in the name
if ( ! name.isEmpty() && ! currentPrefix.isEmpty())
- currentPrefix = currentPrefix.first(currentPrefix.size() - 1);
+ currentPrefix = currentPrefixes.pop();
}
/**
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 be4a683d9d2..1978740014c 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
@@ -18,7 +18,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -266,10 +265,13 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
}
AllValuesQueryProfileVisitor visitValues(CompoundName prefix, Map<String, String> context) {
- DimensionBinding dimensionBinding = DimensionBinding.createFrom(getDimensions(), context);
+ return visitValues(prefix, context, new HashMap<>());
+ }
- AllValuesQueryProfileVisitor visitor = new AllValuesQueryProfileVisitor(prefix);
- accept(visitor, dimensionBinding, null);
+ AllValuesQueryProfileVisitor visitValues(CompoundName prefix, Map<String, String> context,
+ Map<CompoundName, Map<String, CompoundName>> pathCache) {
+ AllValuesQueryProfileVisitor visitor = new AllValuesQueryProfileVisitor(prefix, pathCache);
+ accept(visitor, DimensionBinding.createFrom(getDimensions(), context), null);
return visitor;
}
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 b3fbc1525e6..24426b379e9 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
@@ -50,13 +50,13 @@ public class QueryProfileCompiler {
log.fine(() -> "Compiling " + in + " having " + variants.size() + " variants");
Map<CompoundName, Map<String, CompoundName>> pathCache = new HashMap<>();
- for (DimensionBindingForPath variant : variants) {
- log.finer(() -> " Compiling variant " + variant);
- // TODO jonmv: consider visiting with sets of bindings for each path
- for (Map.Entry<String, ValueWithSource> entry : in.visitValues(variant.path(), variant.binding().getContext()).valuesWithSource().entrySet()) {
- CompoundName fullName = pathCache.computeIfAbsent(variant.path, path -> new HashMap<>())
- .computeIfAbsent(entry.getKey(), variant.path::append);
- Binding variantBinding = Binding.createFrom(variant.binding());
+ Map<DimensionBinding, Binding> bindingCache = new HashMap<>();
+ for (var variant : variants) {
+ log.finer(() -> "Compiling variant " + variant);
+ Binding variantBinding = bindingCache.computeIfAbsent(variant.binding(), Binding::createFrom);
+ for (var entry : in.visitValues(variant.path(), variant.binding().getContext(), pathCache).valuesWithSource().entrySet()) {
+ CompoundName fullName = pathCache.computeIfAbsent(variant.path(), __ -> new HashMap<>())
+ .computeIfAbsent(entry.getKey(), variant.path()::append);
values.put(fullName, variantBinding, entry.getValue());
if (entry.getValue().isUnoverridable())
unoverridables.put(fullName, variantBinding, Boolean.TRUE);