diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2019-10-28 11:17:02 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2019-10-28 11:17:02 +0100 |
commit | a1ea620f6e1aaa13b0ba916377bfa1d2c749b3f7 (patch) | |
tree | d4d5e03eb2dac36492cf633544de2ea787b2c3d5 /container-search/src/main | |
parent | b18c69dd2233bdc1d791eedcafafa17ff635075e (diff) |
Note value source when visiting
Diffstat (limited to 'container-search/src/main')
13 files changed, 296 insertions, 185 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java index d2c2017a49a..eda8bf78b68 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/AllReferencesQueryProfileVisitor.java @@ -24,10 +24,16 @@ final class AllReferencesQueryProfileVisitor extends PrefixQueryProfileVisitor { } @Override - public void onValue(String name, Object value, DimensionBinding binding, QueryProfile owner) {} + public void onValue(String name, Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) {} @Override - public void onQueryProfileInsidePrefix(QueryProfile profile, DimensionBinding binding, QueryProfile owner) { + public void onQueryProfileInsidePrefix(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { references.add(currentPrefix); } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java index 4b83b716635..6bf17d70c70 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/AllTypesQueryProfileVisitor.java @@ -22,11 +22,17 @@ final class AllTypesQueryProfileVisitor extends PrefixQueryProfileVisitor { } @Override - public void onValue(String name, Object value, DimensionBinding binding, QueryProfile owner) {} + public void onValue(String name, Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) {} @Override - public void onQueryProfileInsidePrefix(QueryProfile profile, DimensionBinding binding, QueryProfile owner) { + public void onQueryProfileInsidePrefix(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { if (profile.getType() != null) addReachableTypes(currentPrefix, profile.getType()); } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java index 3b297834ddd..4bae6823500 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/AllUnoverridableQueryProfileVisitor.java @@ -19,16 +19,25 @@ final class AllUnoverridableQueryProfileVisitor extends PrefixQueryProfileVisito } @Override - public void onValue(String name, Object value, DimensionBinding binding, QueryProfile owner) { + public void onValue(String name, Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { addUnoverridable(name, currentPrefix.append(name), binding, owner); } @Override - public void onQueryProfileInsidePrefix(QueryProfile profile, DimensionBinding binding, QueryProfile owner) { + public void onQueryProfileInsidePrefix(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { addUnoverridable(currentPrefix.last(), currentPrefix, binding, owner); } - private void addUnoverridable(String localName, CompoundName fullName, DimensionBinding binding, QueryProfile owner) { + private void addUnoverridable(String localName, + CompoundName fullName, + DimensionBinding binding, + QueryProfile owner) { if (owner == null) return; Boolean isOverridable = owner.isLocalOverridable(localName, binding); 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 e56dabc71d7..d2e0f64f968 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 @@ -2,8 +2,8 @@ package com.yahoo.search.query.profile; import com.yahoo.processing.request.CompoundName; +import com.yahoo.search.query.profile.compiled.ValueSource; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -12,7 +12,8 @@ import java.util.Map; */ final class AllValuesQueryProfileVisitor extends PrefixQueryProfileVisitor { - private Map<String,Object> values=new HashMap<>(); + private Map<String, Object> values = new HashMap<>(); + private Map<String, ValueSource> sources = new HashMap<>(); /* Lists all values starting at prefix */ public AllValuesQueryProfileVisitor(CompoundName prefix) { @@ -20,21 +21,30 @@ final class AllValuesQueryProfileVisitor extends PrefixQueryProfileVisitor { } @Override - public void onValue(String localName, Object value, DimensionBinding binding, QueryProfile owner) { - putValue(localName, value, values); + public void onValue(String localName, + Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { + putValue(localName, value, owner, variant); } @Override - public void onQueryProfileInsidePrefix(QueryProfile profile, DimensionBinding binding, QueryProfile owner) { - putValue("", profile.getValue(), values); + public void onQueryProfileInsidePrefix(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { + putValue("", profile.getValue(), owner, variant); } - private final void putValue(String key, Object value, Map<String, Object> values) { + private void putValue(String key, Object value, QueryProfile owner, DimensionValues variant) { if (value == null) return; CompoundName fullName = currentPrefix.append(key); if (fullName.isEmpty()) return; // Avoid putting a non-leaf (subtree) root in the list if (values.containsKey(fullName.toString())) return; // The first value encountered has priority + values.put(fullName.toString(), value); + sources.put(fullName.toString(), new ValueSource(owner, variant)); } /** Returns the values resulting from this visiting */ diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java index 1a36f4917d9..b70474371d4 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java @@ -32,20 +32,20 @@ public class DimensionValues implements Comparable<DimensionValues> { * The input array is copied by this. */ private DimensionValues(String[] values) { - if (values==null) throw new NullPointerException("Dimension values cannot be null"); - this.values=Arrays.copyOf(values,values.length); + if (values == null) throw new NullPointerException("Dimension values cannot be null"); + this.values=Arrays.copyOf(values, values.length); } /** Returns true if this is has the same value every place it has a value as the givenValues. */ public boolean matches(DimensionValues givenValues) { - for (int i=0; i<this.size() || i<givenValues.size() ; i++) - if ( ! matches(this.get(i),givenValues.get(i))) + for (int i = 0; i < this.size() || i < givenValues.size() ; i++) + if ( ! matches(this.get(i), givenValues.get(i))) return false; return true; } - private final boolean matches(String conditionString,String checkString) { - if (conditionString==null) return true; + private final boolean matches(String conditionString, String checkString) { + if (conditionString == null) return true; return conditionString.equals(checkString); } @@ -61,10 +61,10 @@ public class DimensionValues implements Comparable<DimensionValues> { */ @Override public int compareTo(DimensionValues other) { - for (int i=0; i<this.size() || i<other.size(); i++) { - if (get(i)!=null && other.get(i)==null) + for (int i=0; i < this.size() || i < other.size(); i++) { + if (get(i) != null && other.get(i) == null) return -1; - if (get(i)==null && other.get(i)!=null) + if (get(i) == null && other.get(i) != null) return 1; } return 0; @@ -77,12 +77,12 @@ public class DimensionValues implements Comparable<DimensionValues> { @Override public boolean equals(Object o) { - if (this==o) return true; + if (this == o) return true; if ( ! (o instanceof DimensionValues)) return false; - DimensionValues other=(DimensionValues)o; - for (int i=0; i<this.size() || i<other.size(); i++) { - if (get(i)==null) { - if (other.get(i)!=null) return false; + DimensionValues other = (DimensionValues)o; + for (int i = 0; i < this.size() || i < other.size(); i++) { + if (get(i) == null) { + if (other.get(i) != null) return false; } else { if ( ! get(i).equals(other.get(i))) return false; @@ -112,7 +112,7 @@ public class DimensionValues implements Comparable<DimensionValues> { private static boolean containsAllNulls(String[] values) { for (String value : values) - if (value!=null) return false; + if (value != null) return false; return true; } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/FieldDescriptionQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/FieldDescriptionQueryProfileVisitor.java index 8a71b04c3b2..1d0bd2dbf53 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/FieldDescriptionQueryProfileVisitor.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/FieldDescriptionQueryProfileVisitor.java @@ -46,14 +46,21 @@ final class FieldDescriptionQueryProfileVisitor extends QueryProfileVisitor { } @Override - public void onValue(String name,Object value, DimensionBinding binding, QueryProfile owner) { + public void onValue(String name, + Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { } @Override - public void onQueryProfile(QueryProfile profile, DimensionBinding binding, QueryProfile owner) { + public void onQueryProfile(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { if (enteringContent) return; // not at leaf query profile if (profile.getType() == null) return; - result = profile.getType().getField(name.get(name.size()-1)); + result = profile.getType().getField(name.get(name.size() - 1)); } @Override 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 e47b4bc2bb4..690a48f8124 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 @@ -25,12 +25,18 @@ abstract class PrefixQueryProfileVisitor extends QueryProfileVisitor { } @Override - public final void onQueryProfile(QueryProfile profile, DimensionBinding binding, QueryProfile owner) { + public final void onQueryProfile(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { if (prefixComponentIndex < prefix.size()) return; // Not in the prefix yet - onQueryProfileInsidePrefix(profile, binding, owner); + onQueryProfileInsidePrefix(profile, binding, owner, variant); } - protected abstract void onQueryProfileInsidePrefix(QueryProfile profile, DimensionBinding binding, QueryProfile owner); + protected abstract void onQueryProfileInsidePrefix(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant); @Override public final boolean enter(String name) { 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 f5f6b2d2550..7b3f43d75e5 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 @@ -238,7 +238,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable AllValuesQueryProfileVisitor visitor = new AllValuesQueryProfileVisitor(prefix); accept(visitor,dimensionBinding, null); - Map<String,Object> values = visitor.getResult(); + Map<String, Object> values = visitor.getResult(); if (substitution == null) return values; for (Map.Entry<String, Object> entry : values.entrySet()) { @@ -507,17 +507,24 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable return overridable.get(localName); } - protected Object lookup(CompoundName name, boolean allowQueryProfileResult, DimensionBinding dimensionBinding) { + protected Object lookup(CompoundName name, + boolean allowQueryProfileResult, + DimensionBinding dimensionBinding) { SingleValueQueryProfileVisitor visitor = new SingleValueQueryProfileVisitor(name.asList(), allowQueryProfileResult); accept(visitor, dimensionBinding, null); return visitor.getResult(); } - protected final void accept(QueryProfileVisitor visitor,DimensionBinding dimensionBinding, QueryProfile owner) { + protected final void accept(QueryProfileVisitor visitor, + DimensionBinding dimensionBinding, + QueryProfile owner) { acceptAndEnter("", visitor, dimensionBinding, owner); } - void acceptAndEnter(String key, QueryProfileVisitor visitor,DimensionBinding dimensionBinding, QueryProfile owner) { + void acceptAndEnter(String key, + QueryProfileVisitor visitor, + DimensionBinding dimensionBinding, + QueryProfile owner) { boolean allowContent = visitor.enter(key); accept(allowContent, visitor, dimensionBinding, owner); if (allowContent) @@ -531,11 +538,14 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable * @param visitor the visitor * @param dimensionBinding the dimension binding to use */ - final void accept(boolean allowContent,QueryProfileVisitor visitor, DimensionBinding dimensionBinding, QueryProfile owner) { - visitor.onQueryProfile(this, dimensionBinding, owner); + final void accept(boolean allowContent, + QueryProfileVisitor visitor, + DimensionBinding dimensionBinding, + QueryProfile owner) { + visitor.onQueryProfile(this, dimensionBinding, owner, null); if (visitor.isDone()) return; - visitVariants(allowContent,visitor,dimensionBinding); + visitVariants(allowContent, visitor, dimensionBinding); if (visitor.isDone()) return; if (allowContent) { @@ -547,31 +557,37 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable visitInherited(allowContent, visitor, dimensionBinding, owner); } - protected void visitVariants(boolean allowContent,QueryProfileVisitor visitor,DimensionBinding dimensionBinding) { + protected void visitVariants(boolean allowContent, QueryProfileVisitor visitor, DimensionBinding dimensionBinding) { if (getVariants() != null) getVariants().accept(allowContent, getType(), visitor, dimensionBinding); } - protected void visitInherited(boolean allowContent,QueryProfileVisitor visitor,DimensionBinding dimensionBinding, QueryProfile owner) { + protected void visitInherited(boolean allowContent, + QueryProfileVisitor visitor, + DimensionBinding dimensionBinding, + QueryProfile owner) { if (inherited == null) return; for (QueryProfile inheritedProfile : inherited) { - inheritedProfile.accept(allowContent, visitor, dimensionBinding.createFor(inheritedProfile.getDimensions()), owner); + inheritedProfile.accept(allowContent, + visitor, + dimensionBinding.createFor(inheritedProfile.getDimensions()), + owner); if (visitor.isDone()) return; } } - private void visitContent(QueryProfileVisitor visitor,DimensionBinding dimensionBinding) { + private void visitContent(QueryProfileVisitor visitor, DimensionBinding dimensionBinding) { String contentKey = visitor.getLocalKey(); // Visit this' content if (contentKey != null) { // Get only the content of the current key if (type != null) contentKey = type.unalias(contentKey); - visitor.acceptValue(contentKey, getContent(contentKey), dimensionBinding, this); + visitor.acceptValue(contentKey, getContent(contentKey), dimensionBinding, this, null); } else { // get all content in this for (Map.Entry<String,Object> entry : getContent().entrySet()) { - visitor.acceptValue(entry.getKey(), entry.getValue(), dimensionBinding, this); + visitor.acceptValue(entry.getKey(), entry.getValue(), dimensionBinding, this, null); if (visitor.isDone()) return; } } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java index 17940c00926..3f70ff98373 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java @@ -14,18 +14,18 @@ import java.util.*; */ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVariant> { - private List<QueryProfile> inherited=null; + private List<QueryProfile> inherited = null; private DimensionValues dimensionValues; - private Map<String,Object> values; + private Map<String, Object> values; - private boolean frozen=false; + private boolean frozen = false; private QueryProfile owner; public QueryProfileVariant(DimensionValues dimensionValues, QueryProfile owner) { - this.dimensionValues=dimensionValues; + this.dimensionValues = dimensionValues; this.owner = owner; } @@ -36,11 +36,11 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa * if this is not frozen. */ public Map<String,Object> values() { - if (values==null) { + if (values == null) { if (frozen) return Collections.emptyMap(); else - values=new HashMap<>(); + values = new HashMap<>(); } return values; } @@ -50,18 +50,18 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa * if this is not frozen. */ public List<QueryProfile> inherited() { - if (inherited==null) { + if (inherited == null) { if (frozen) return Collections.emptyList(); else - inherited=new ArrayList<>(); + inherited = new ArrayList<>(); } return inherited; } public void set(String key, Object newValue) { - if (values==null) - values=new HashMap<>(); + if (values == null) + values = new HashMap<>(); Object oldValue = values.get(key); @@ -76,8 +76,8 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa } public void inherit(QueryProfile profile) { - if (inherited==null) - inherited=new ArrayList<>(1); + if (inherited == null) + inherited = new ArrayList<>(1); inherited.add(profile); } @@ -98,20 +98,23 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa } /** Accepts a visitor to the values of this */ - public void accept(boolean allowContent,QueryProfileType type,QueryProfileVisitor visitor, DimensionBinding dimensionBinding) { + public void accept(boolean allowContent, + QueryProfileType type, + QueryProfileVisitor visitor, + DimensionBinding dimensionBinding) { // Visit this if (allowContent) { - String key=visitor.getLocalKey(); - if (key!=null) { - if (type!=null) + String key = visitor.getLocalKey(); + if (key != null) { + if (type != null) type.unalias(key); - visitor.acceptValue(key, values().get(key), dimensionBinding, owner); + visitor.acceptValue(key, values().get(key), dimensionBinding, owner, dimensionValues); if (visitor.isDone()) return; } else { - for (Map.Entry<String,Object> entry : values().entrySet()) { - visitor.acceptValue(entry.getKey(), entry.getValue(), dimensionBinding, owner); + for (Map.Entry<String, Object> entry : values().entrySet()) { + visitor.acceptValue(entry.getKey(), entry.getValue(), dimensionBinding, owner, dimensionValues); if (visitor.isDone()) return; } } @@ -120,7 +123,7 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa // Visit inherited for (QueryProfile profile : inherited()) { if (visitor.visitInherited()) { - profile.accept(allowContent,visitor,dimensionBinding.createFor(profile.getDimensions()), owner); + profile.accept(allowContent, visitor, dimensionBinding.createFor(profile.getDimensions()), owner); } if (visitor.isDone()) return; } @@ -138,11 +141,11 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa public QueryProfileVariant clone() { if (frozen) return this; try { - QueryProfileVariant clone=(QueryProfileVariant)super.clone(); - if (this.inherited!=null) - clone.inherited=new ArrayList<>(this.inherited); // TODO: Deep clone is more correct, but probably does not matter in practice + QueryProfileVariant clone = (QueryProfileVariant)super.clone(); + if (this.inherited != null) + clone.inherited = new ArrayList<>(this.inherited); // TODO: Deep clone is more correct, but probably does not matter in practice - clone.values=CopyOnWriteContent.deepClone(this.values); + clone.values = CopyOnWriteContent.deepClone(this.values); return clone; } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java index 50db98d54d4..8dedda800ea 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariants.java @@ -24,19 +24,19 @@ import java.util.*; */ public class QueryProfileVariants implements Freezable, Cloneable { - private boolean frozen=false; + private boolean frozen = false; /** Properties indexed by name, to support fast lookup of single values */ - private Map<String,FieldValues> fieldValuesByName=new HashMap<>(); + private Map<String,FieldValues> fieldValuesByName = new HashMap<>(); /** The inherited profiles for various dimensions settings - a set of fieldvalues of List<QueryProfile> */ - private FieldValues inheritedProfiles=new FieldValues(); + private FieldValues inheritedProfiles =new FieldValues(); /** * Field and inherited profiles sorted by specificity used for all-value visiting. * This is the same as how the source data looks (apart from the sorting). */ - private List<QueryProfileVariant> variants=new ArrayList<>(); + private List<QueryProfileVariant> variants = new ArrayList<>(); /** * The names of the dimensions (which are possible properties in the context given on lookup) of this. @@ -94,54 +94,66 @@ public class QueryProfileVariants implements Freezable, Cloneable { } /** Visits the most specific match to the dimension binding of each variable (or the one named by the visitor) */ - void accept(boolean allowContent,QueryProfileType type,QueryProfileVisitor visitor,DimensionBinding dimensionBinding) { - String contentName=null; + void accept(boolean allowContent, + QueryProfileType type, + QueryProfileVisitor visitor, + DimensionBinding dimensionBinding) { + String contentName = null; if (allowContent) - contentName=visitor.getLocalKey(); + contentName = visitor.getLocalKey(); - if (contentName!=null) { - if (type!=null) - contentName=type.unalias(contentName); - acceptSingleValue(contentName,allowContent,visitor,dimensionBinding); // Special cased for performance + if (contentName != null) { + if (type != null) + contentName = type.unalias(contentName); + acceptSingleValue(contentName, allowContent, visitor, dimensionBinding); // Special cased for performance } else { - acceptAllValues(allowContent,visitor,type,dimensionBinding); + acceptAllValues(allowContent, visitor, type, dimensionBinding); } } - // PERF: 90% - void acceptSingleValue(String name,boolean allowContent,QueryProfileVisitor visitor,DimensionBinding dimensionBinding) { - FieldValues fieldValues=fieldValuesByName.get(name); - if (fieldValues==null || !allowContent) - fieldValues=new FieldValues(); + void acceptSingleValue(String name, + boolean allowContent, + QueryProfileVisitor visitor, + DimensionBinding dimensionBinding) { + FieldValues fieldValues = fieldValuesByName.get(name); + if (fieldValues == null || ! allowContent) + fieldValues = new FieldValues(); fieldValues.sort(); inheritedProfiles.sort(); - int inheritedIndex=0; - int fieldIndex=0; + int inheritedIndex = 0; + int fieldIndex = 0; // Go through both the fields and the inherited profiles at the same time and try the single must specific pick // from either of the lists at each step - while(fieldIndex<fieldValues.size() || inheritedIndex<inheritedProfiles.size()) { // PERF: 8% - fieldValues.size() + while(fieldIndex < fieldValues.size() || inheritedIndex < inheritedProfiles.size()) { // Get the next most specific from field and inherited - FieldValue fieldValue=fieldValues.getIfExists(fieldIndex); // PERF: 11% - getIfExists - FieldValue inheritedProfileValue=inheritedProfiles.getIfExists(inheritedIndex); // PERF: 11% - getIfExists + FieldValue fieldValue = fieldValues.getIfExists(fieldIndex); + FieldValue inheritedProfileValue = inheritedProfiles.getIfExists(inheritedIndex); // Try the most specific first, then the other - if (inheritedProfileValue==null || (fieldValue!=null && fieldValue.compareTo(inheritedProfileValue)<=0)) { // Field is most specific, or both are equally specific - if (fieldValue.matches(dimensionBinding.getValues())) { // PERF: 42% - matches, together with the other matches - visitor.acceptValue(name, fieldValue.getValue(), dimensionBinding, owner); + if (inheritedProfileValue == null || (fieldValue != null && fieldValue.compareTo(inheritedProfileValue) <= 0)) { // Field is most specific, or both are equally specific + if (fieldValue.matches(dimensionBinding.getValues())) { + visitor.acceptValue(name, + fieldValue.getValue(), + dimensionBinding, + owner, + fieldValue.getDimensionValues()); } if (visitor.isDone()) return; fieldIndex++; } - else if (inheritedProfileValue!=null) { // Inherited is most specific at this point - if (inheritedProfileValue.matches(dimensionBinding.getValues())) { // PERF: 42% - matches, together with the other matches + else if (inheritedProfileValue != null) { // Inherited is most specific at this point + if (inheritedProfileValue.matches(dimensionBinding.getValues())) { @SuppressWarnings("unchecked") - List<QueryProfile> inheritedProfileList=(List<QueryProfile>)inheritedProfileValue.getValue(); + List<QueryProfile> inheritedProfileList = (List<QueryProfile>)inheritedProfileValue.getValue(); for (QueryProfile inheritedProfile : inheritedProfileList) { if (visitor.visitInherited()) { - inheritedProfile.accept(allowContent,visitor,dimensionBinding.createFor(inheritedProfile.getDimensions()), owner); + inheritedProfile.accept(allowContent, + visitor, + dimensionBinding.createFor(inheritedProfile.getDimensions()), + owner); } if (visitor.isDone()) return; } @@ -152,12 +164,15 @@ public class QueryProfileVariants implements Freezable, Cloneable { } } - void acceptAllValues(boolean allowContent,QueryProfileVisitor visitor, QueryProfileType type,DimensionBinding dimensionBinding) { - if (!frozen) + void acceptAllValues(boolean allowContent, + QueryProfileVisitor visitor, + QueryProfileType type, + DimensionBinding dimensionBinding) { + if ( ! frozen) Collections.sort(variants); for (QueryProfileVariant variant : variants) { if (variant.matches(dimensionBinding.getValues())) - variant.accept(allowContent,type,visitor,dimensionBinding); + variant.accept(allowContent, type, visitor, dimensionBinding); if (visitor.isDone()) return; } } @@ -169,15 +184,15 @@ public class QueryProfileVariants implements Freezable, Cloneable { * @param dimensionBinding the dimension bindings to use in this */ public Object get(String name, QueryProfileType type, boolean allowQueryProfileResult, DimensionBinding dimensionBinding) { - SingleValueQueryProfileVisitor visitor=new SingleValueQueryProfileVisitor(Collections.singletonList(name),allowQueryProfileResult); + SingleValueQueryProfileVisitor visitor = new SingleValueQueryProfileVisitor(Collections.singletonList(name),allowQueryProfileResult); visitor.enter(""); - accept(true,type,visitor,dimensionBinding); + accept(true, type, visitor, dimensionBinding); visitor.leave(""); return visitor.getResult(); } /** Inherits a particular profile in a variant of this */ - public void inherit(QueryProfile profile,DimensionValues dimensionValues) { + public void inherit(QueryProfile profile, DimensionValues dimensionValues) { ensureNotFrozen(); // Update variant @@ -185,10 +200,10 @@ public class QueryProfileVariants implements Freezable, Cloneable { // Update per-variable optimized structure @SuppressWarnings("unchecked") - List<QueryProfile> inheritedAtDimensionValues=(List<QueryProfile>)inheritedProfiles.getExact(dimensionValues); - if (inheritedAtDimensionValues==null) { - inheritedAtDimensionValues=new ArrayList<>(); - inheritedProfiles.put(dimensionValues,inheritedAtDimensionValues); + List<QueryProfile> inheritedAtDimensionValues = (List<QueryProfile>)inheritedProfiles.getExact(dimensionValues); + if (inheritedAtDimensionValues == null) { + inheritedAtDimensionValues = new ArrayList<>(); + inheritedProfiles.put(dimensionValues, inheritedAtDimensionValues); } inheritedAtDimensionValues.add(profile); } @@ -197,33 +212,25 @@ public class QueryProfileVariants implements Freezable, Cloneable { * Sets a value to this * * @param fieldName the name of the field to set. This cannot be a compound (dotted) name - * @param binding the dimension values for which this value applies. - * The dimensions must be canonicalized, and ownership is transferred to this. - * @param value the value to set - */ - /** - * Sets a value to this - * - * @param fieldName the name of the field to set. This cannot be a compound (dotted) name * @param dimensionValues the dimension values for which this value applies * @param value the value to set */ - public void set(String fieldName,DimensionValues dimensionValues,Object value) { + public void set(String fieldName, DimensionValues dimensionValues, Object value) { ensureNotFrozen(); // Update variant - getVariant(dimensionValues,true).set(fieldName,value); + getVariant(dimensionValues, true).set(fieldName, value); // Update per-variable optimized structure - FieldValues fieldValues=fieldValuesByName.get(fieldName); - if (fieldValues==null) { - fieldValues=new FieldValues(); - fieldValuesByName.put(fieldName,fieldValues); + FieldValues fieldValues = fieldValuesByName.get(fieldName); + if (fieldValues == null) { + fieldValues = new FieldValues(); + fieldValuesByName.put(fieldName, fieldValues); } - Object combinedValue=QueryProfile.combineValues(value,fieldValues.getExact(dimensionValues)); - if (combinedValue!=null) - fieldValues.put(dimensionValues,combinedValue); + Object combinedValue = QueryProfile.combineValues(value, fieldValues.getExact(dimensionValues)); + if (combinedValue != null) + fieldValues.put(dimensionValues, combinedValue); } /** @@ -236,7 +243,7 @@ public class QueryProfileVariants implements Freezable, Cloneable { public List<String> getDimensions() { return dimensions; } /** Returns the map of field values of this indexed by field name. */ - public Map<String,FieldValues> getFieldValues() { return fieldValuesByName; } + public Map<String, FieldValues> getFieldValues() { return fieldValuesByName; } /** Returns the profiles inherited from various variants of this */ public FieldValues getInherited() { return inheritedProfiles; } @@ -253,16 +260,16 @@ public class QueryProfileVariants implements Freezable, Cloneable { public QueryProfileVariants clone() { try { if (frozen) return this; - QueryProfileVariants clone=(QueryProfileVariants)super.clone(); - clone.inheritedProfiles=inheritedProfiles.clone(); + QueryProfileVariants clone = (QueryProfileVariants)super.clone(); + clone.inheritedProfiles = inheritedProfiles.clone(); - clone.variants=new ArrayList<>(); + clone.variants = new ArrayList<>(); for (QueryProfileVariant variant : variants) clone.variants.add(variant.clone()); - clone.fieldValuesByName=new HashMap<>(); - for (Map.Entry<String,FieldValues> entry : fieldValuesByName.entrySet()) - clone.fieldValuesByName.put(entry.getKey(),entry.getValue().clone(entry.getKey(),clone.variants)); + clone.fieldValuesByName = new HashMap<>(); + for (Map.Entry<String, FieldValues> entry : fieldValuesByName.entrySet()) + clone.fieldValuesByName.put(entry.getKey(), entry.getValue().clone(entry.getKey(), clone.variants)); return clone; } @@ -285,14 +292,14 @@ public class QueryProfileVariants implements Freezable, Cloneable { * @param create whether or not to create the variant if missing * @return the profile variant, or null if not found and create is false */ - public QueryProfileVariant getVariant(DimensionValues dimensionValues,boolean create) { + public QueryProfileVariant getVariant(DimensionValues dimensionValues, boolean create) { for (QueryProfileVariant profileVariant : variants) if (profileVariant.getDimensionValues().equals(dimensionValues)) return profileVariant; // Not found - if (!create) return null; - QueryProfileVariant variant=new QueryProfileVariant(dimensionValues, owner); + if ( ! create) return null; + QueryProfileVariant variant = new QueryProfileVariant(dimensionValues, owner); variants.add(variant); return variant; } @@ -301,7 +308,7 @@ public class QueryProfileVariants implements Freezable, Cloneable { private List<FieldValue> resolutionList=null; - private boolean frozen=false; + private boolean frozen = false; @Override public void freeze() { @@ -317,20 +324,20 @@ public class QueryProfileVariants implements Freezable, Cloneable { return frozen; } - public void put(DimensionValues dimensionValues,Object value) { + public void put(DimensionValues dimensionValues, Object value) { ensureNotFrozen(); - if (resolutionList==null) resolutionList=new ArrayList<>(); - FieldValue fieldValue=getExactFieldValue(dimensionValues); - if (fieldValue!=null) // Replace + if (resolutionList == null) resolutionList = new ArrayList<>(); + FieldValue fieldValue = getExactFieldValue(dimensionValues); + if (fieldValue != null) // Replace fieldValue.setValue(value); else - resolutionList.add(new FieldValue(dimensionValues,value)); + resolutionList.add(new FieldValue(dimensionValues, value)); } /** Returns the value having exactly the given dimensions, or null if none */ public Object getExact(DimensionValues dimensionValues) { - FieldValue value=getExactFieldValue(dimensionValues); - if (value==null) return null; + FieldValue value = getExactFieldValue(dimensionValues); + if (value == null) return null; return value.getValue(); } @@ -344,24 +351,24 @@ public class QueryProfileVariants implements Freezable, Cloneable { /** Returns the field values (values for various dimensions) for this field as a read-only list (never null) */ public List<FieldValue> asList() { - if (resolutionList==null) return Collections.emptyList(); + if (resolutionList == null) return Collections.emptyList(); return resolutionList; } public FieldValue getIfExists(int index) { - if (index>=size()) return null; + if (index >= size()) return null; return resolutionList.get(index); } public void sort() { if (frozen) return ; // sorted already - if (resolutionList!=null) + if (resolutionList != null) Collections.sort(resolutionList); } /** Same as asList().size() */ public int size() { - if (resolutionList==null) return 0; + if (resolutionList == null) return 0; return resolutionList.size(); } @@ -375,12 +382,12 @@ public class QueryProfileVariants implements Freezable, Cloneable { public FieldValues clone(String fieldName,List<QueryProfileVariant> clonedVariants) { try { if (frozen) return this; - FieldValues clone=(FieldValues)super.clone(); + FieldValues clone = (FieldValues)super.clone(); - if (resolutionList!=null) { - clone.resolutionList=new ArrayList<>(resolutionList.size()); + if (resolutionList != null) { + clone.resolutionList = new ArrayList<>(resolutionList.size()); for (FieldValue value : resolutionList) - clone.resolutionList.add(value.clone(fieldName,clonedVariants)); + clone.resolutionList.add(value.clone(fieldName, clonedVariants)); } return clone; @@ -394,10 +401,10 @@ public class QueryProfileVariants implements Freezable, Cloneable { public FieldValues clone() { try { if (frozen) return this; - FieldValues clone=(FieldValues)super.clone(); + FieldValues clone = (FieldValues)super.clone(); - if (resolutionList!=null) { - clone.resolutionList=new ArrayList<>(resolutionList.size()); + if (resolutionList != null) { + clone.resolutionList = new ArrayList<>(resolutionList.size()); for (FieldValue value : resolutionList) clone.resolutionList.add(value.clone()); } @@ -416,9 +423,9 @@ public class QueryProfileVariants implements Freezable, Cloneable { private DimensionValues dimensionValues; private Object value; - public FieldValue(DimensionValues dimensionValues,Object value) { - this.dimensionValues=dimensionValues; - this.value=value; + public FieldValue(DimensionValues dimensionValues, Object value) { + this.dimensionValues = dimensionValues; + this.value = value; } /** @@ -453,9 +460,9 @@ public class QueryProfileVariants implements Freezable, Cloneable { /** Clone by filling in the value from the given variants */ public FieldValue clone(String fieldName,List<QueryProfileVariant> clonedVariants) { try { - FieldValue clone=(FieldValue)super.clone(); + FieldValue clone = (FieldValue)super.clone(); if (this.value instanceof QueryProfile) - clone.value=lookupInVariants(fieldName,dimensionValues,clonedVariants); + clone.value = lookupInVariants(fieldName, dimensionValues, clonedVariants); // Otherwise the value is immutable, so keep it as-is return clone; } @@ -466,8 +473,8 @@ public class QueryProfileVariants implements Freezable, Cloneable { public FieldValue clone() { try { - FieldValue clone=(FieldValue)super.clone(); - clone.value=QueryProfile.cloneIfNecessary(this.value); + FieldValue clone = (FieldValue)super.clone(); + clone.value = QueryProfile.cloneIfNecessary(this.value); return clone; } catch (CloneNotSupportedException e) { @@ -475,7 +482,7 @@ public class QueryProfileVariants implements Freezable, Cloneable { } } - private Object lookupInVariants(String fieldName,DimensionValues dimensionValues,List<QueryProfileVariant> variants) { + private Object lookupInVariants(String fieldName, DimensionValues dimensionValues, List<QueryProfileVariant> variants) { for (QueryProfileVariant variant : variants) { if ( ! variant.getDimensionValues().equals(dimensionValues)) continue; return variant.values().get(fieldName); diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java index 5494e8f931d..f6ffeb777a5 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java @@ -48,8 +48,13 @@ abstract class QueryProfileVisitor { * @param value the value * @param binding the binding this holds for * @param owner the query profile having this value, or null only when profile is the root profile + * @param variant the variant having this value, or null if it is not in a variant */ - public abstract void onValue(String localName, Object value, DimensionBinding binding, QueryProfile owner); + public abstract void onValue(String localName, + Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant); /** * Called when a query profile is encountered. @@ -57,8 +62,12 @@ abstract class QueryProfileVisitor { * @param profile the query profile reference encountered * @param binding the binding this holds for * @param owner the profile making this reference, or null only when profile is the root profile + * @param variant the variant having this value, or null if it is not in a variant */ - public abstract void onQueryProfile(QueryProfile profile, DimensionBinding binding, QueryProfile owner); + public abstract void onQueryProfile(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant); /** Returns whether this visitor is done visiting what it needed to visit at this point */ public abstract boolean isDone(); @@ -72,15 +81,23 @@ abstract class QueryProfileVisitor { */ public abstract String getLocalKey(); - /** Calls onValue or onQueryProfile on this and visits the content if it's a profile */ - final void acceptValue(String key, Object value, DimensionBinding dimensionBinding, QueryProfile owner) { - if (value==null) return; + /** + * Calls onValue or onQueryProfile on this and visits the content if it's a profile + * + * @param variant the variant having this value, or null if it is not in a variant + */ + final void acceptValue(String key, + Object value, + DimensionBinding dimensionBinding, + QueryProfile owner, + DimensionValues variant) { + if (value == null) return; if (value instanceof QueryProfile) { - QueryProfile queryProfileValue=(QueryProfile)value; + QueryProfile queryProfileValue = (QueryProfile)value; queryProfileValue.acceptAndEnter(key, this, dimensionBinding.createFor(queryProfileValue.getDimensions()), owner); } else { - onValue(key, value, dimensionBinding, owner); + onValue(key, value, dimensionBinding, owner, variant); } } diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/SingleValueQueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/SingleValueQueryProfileVisitor.java index 3bee56f7276..a0734f56e9a 100644 --- a/container-search/src/main/java/com/yahoo/search/query/profile/SingleValueQueryProfileVisitor.java +++ b/container-search/src/main/java/com/yahoo/search/query/profile/SingleValueQueryProfileVisitor.java @@ -15,19 +15,19 @@ import java.util.List; final class SingleValueQueryProfileVisitor extends QueryProfileVisitor { /** The value found, or null if none */ - private Object value=null; + private Object value = null; private final List<String> name; - private int nameIndex=-1; + private int nameIndex = -1; private final boolean allowQueryProfileResult; - private boolean enteringContent=true; + private boolean enteringContent = true; - public SingleValueQueryProfileVisitor(List<String> name,boolean allowQueryProfileResult) { - this.name=name; - this.allowQueryProfileResult=allowQueryProfileResult; + public SingleValueQueryProfileVisitor(List<String> name, boolean allowQueryProfileResult) { + this.name = name; + this.allowQueryProfileResult = allowQueryProfileResult; } @Override @@ -37,12 +37,12 @@ final class SingleValueQueryProfileVisitor extends QueryProfileVisitor { @Override public boolean enter(String name) { - if (nameIndex+1<this.name.size()) { + if (nameIndex+1 < this.name.size()) { nameIndex++; - enteringContent=true; + enteringContent = true; } else { - enteringContent=false; + enteringContent = false; } return enteringContent; } @@ -53,13 +53,19 @@ final class SingleValueQueryProfileVisitor extends QueryProfileVisitor { } @Override - public void onValue(String key,Object value, DimensionBinding binding, QueryProfile owner) { - if (nameIndex==name.size()-1) - this.value=value; + public void onValue(String key,Object value, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { + if (nameIndex == name.size()-1) + this.value = value; } @Override - public void onQueryProfile(QueryProfile profile,DimensionBinding binding, QueryProfile owner) { + public void onQueryProfile(QueryProfile profile, + DimensionBinding binding, + QueryProfile owner, + DimensionValues variant) { if (enteringContent) return; // still waiting for content if (allowQueryProfileResult) this.value = profile; diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueSource.java b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueSource.java new file mode 100644 index 00000000000..17326efb220 --- /dev/null +++ b/container-search/src/main/java/com/yahoo/search/query/profile/compiled/ValueSource.java @@ -0,0 +1,18 @@ +// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.query.profile.compiled; + +import com.yahoo.search.query.profile.DimensionValues; +import com.yahoo.search.query.profile.QueryProfile; + +/** + * The source of a value in a compiled query profile + * + * @author bratseth + */ +public class ValueSource { + + public ValueSource(QueryProfile owner, DimensionValues variant) { + + } + +} |