aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java140
1 files changed, 140 insertions, 0 deletions
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
new file mode 100644
index 00000000000..10435c4c6b5
--- /dev/null
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/DimensionValues.java
@@ -0,0 +1,140 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.query.profile;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An immutable set of dimension values.
+ * Note that this may contain more or fewer values than needed given a set of dimensions.
+ * Any missing values are treated as null.
+ */
+public class DimensionValues implements Comparable<DimensionValues> {
+
+ private final String[] values;
+
+ public static final DimensionValues empty=new DimensionValues(new String[] {});
+
+ public static DimensionValues createFrom(String[] values) {
+ if (values==null || values.length==0 || containsAllNulls(values)) return empty;
+ return new DimensionValues(values);
+ }
+
+ /**
+ * Creates a set of dimension values, where the input array <b>must</b> be of
+ * the right size, and where no copying is done.
+ *
+ * @param values the dimension values. This need not be normalized to the right size.
+ * 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);
+ }
+
+ /** 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)))
+ return false;
+ return true;
+ }
+
+ private final boolean matches(String conditionString,String checkString) {
+ if (conditionString==null) return true;
+ return conditionString.equals(checkString);
+ }
+
+ /**
+ * Implements the sort order of this which is based on specificity
+ * where dimensions to the left are more significant:
+ * -1 is returned if this is more specific than other,
+ * 1 is returned if other is more specific than this,
+ * 0 is returned if none is more specific than the other.
+ * <p>
+ * <b>Note:</b> This ordering is not consistent with equals - it returns 0 when the same dimensions
+ * are <i>set</i>, regardless of what they are set <i>to</i>.
+ */
+ @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)
+ return -1;
+ if (get(i)==null && other.get(i)!=null)
+ return 1;
+ }
+ return 0;
+ }
+
+ /** Helper method which uses compareTo to return whether this is most specific */
+ public boolean isMoreSpecificThan(DimensionValues other) {
+ return this.compareTo(other)<0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ 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;
+ }
+ else {
+ if ( ! get(i).equals(other.get(i))) return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 0;
+ int i = 0;
+ for (String value : values) {
+ i++;
+ if (value != null)
+ hashCode += value.hashCode() * i;
+ }
+ return hashCode;
+ }
+
+ @Override
+ public String toString() { return Arrays.toString(values); }
+
+ public boolean isEmpty() {
+ return this==empty;
+ }
+
+ private static boolean containsAllNulls(String[] values) {
+ for (String value : values)
+ if (value!=null) return false;
+ return true;
+ }
+
+ public Map<String,String> asContext(List<String> dimensions) {
+ Map<String,String> context=new HashMap<>();
+ if (dimensions==null) return context;
+ for (int i=0; i<dimensions.size(); i++) {
+ context.put(dimensions.get(i),get(i));
+ }
+ return context;
+ }
+
+ /** Returns the string at the given index, <b>or null if it has no value at this index.</b> */
+ public String get(int index) {
+ if (index>=values.length) return null;
+ return values[index];
+ }
+
+ /** Returns the number of values in this (some of which may be null) */
+ public int size() { return values.length; }
+
+ /** Returns copy of the values in this in an array */
+ public String[] getValues() {
+ return Arrays.copyOf(values,values.length);
+ }
+
+}