summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2021-10-28 10:50:27 +0200
committerGitHub <noreply@github.com>2021-10-28 10:50:27 +0200
commit2f00a56c2a58a8de99556ad3a3aad391de64bb47 (patch)
tree4eea431dfa53fb3f0e0a62fc2eb18b4fd882cb35 /container-search/src/main/java/com/yahoo
parent07d6c5fa43fedfa7aff33230a5f1a514745b0556 (diff)
parent9819c5eed296c748fb90a05fffe12ae90fffcfaa (diff)
Merge pull request #19747 from vespa-engine/bratset/items-equality
Bratset/items equality
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/Location.java139
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/AndItem.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/AndSegmentItem.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/BlockItem.java16
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/CompositeIndexedItem.java13
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java77
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/CompositeTaggableItem.java6
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/ExactStringItem.java4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java14
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/HasIndexItem.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/Highlight.java22
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/IndexedSegmentItem.java7
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/IntItem.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/Item.java67
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/ItemHelper.java32
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/MarkerWordItem.java13
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NearItem.java15
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java22
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NotItem.java20
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/NullItem.java20
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/ONearItem.java1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/OrItem.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java16
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java22
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PredicateQueryItem.java129
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PrefixItem.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PureWeightedInteger.java18
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PureWeightedItem.java12
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/PureWeightedString.java18
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/RangeItem.java1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/RankItem.java2
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java14
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SegmentItem.java65
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SimpleIndexedItem.java3
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/Substring.java20
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SubstringItem.java4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/SuffixItem.java4
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/TaggableItem.java1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/TaggableSegmentItem.java11
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/TermItem.java26
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/TermType.java14
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/UriItem.java16
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/WandItem.java16
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java9
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/WeightedSetItem.java30
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/WordAlternativesItem.java72
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/query/WordItem.java21
49 files changed, 657 insertions, 393 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/Location.java b/container-search/src/main/java/com/yahoo/prelude/Location.java
index d3c4daab9a0..c686e869536 100644
--- a/container-search/src/main/java/com/yahoo/prelude/Location.java
+++ b/container-search/src/main/java/com/yahoo/prelude/Location.java
@@ -8,11 +8,12 @@ import java.util.StringTokenizer;
/**
* Location data for a geographical query.
+ * This is mutable and clonable. It's identifty is decided by its content.
*
* @author Steinar Knutsen
* @author arnej27959
*/
-public class Location {
+public class Location implements Cloneable {
// 1 or 2
private int dimensions = 0;
@@ -34,67 +35,46 @@ public class Location {
private String attribute;
- public boolean equals(Object other) {
- if (! (other instanceof Location)) return false;
- Location l = (Location)other;
- return dimensions == l.dimensions
- && renderCircle == l.renderCircle
- && renderRectangle == l.renderRectangle
- && this.aspect == l.aspect
- && this.x1 == l.x1
- && this.x2 == l.x2
- && this.y1 == l.y1
- && this.y2 == l.y2
- && this.x == l.x
- && this.y == l.y
- && this.r == l.r;
- }
-
public boolean hasDimensions() {
return dimensions != 0;
}
+
public void setDimensions(int d) {
- if (hasDimensions() && dimensions != d) {
- throw new IllegalArgumentException("already has dimensions="+dimensions+", cannot change it to "+d);
- }
- if (d == 2) {
+ if (hasDimensions() && dimensions != d)
+ throw new IllegalStateException("already has dimensions " + dimensions + ", cannot change to " + d);
+ if (d == 2)
dimensions = d;
- } else {
- throw new IllegalArgumentException("Illegal location, dimensions must be 2, but was: "+d);
- }
+ else
+ throw new IllegalArgumentException("Illegal location, dimensions must be 2, but was: " + d);
}
+
public int getDimensions() {
return dimensions;
}
// input data are degrees n/e (if positive) or s/w (if negative)
- public void setBoundingBox(double n, double s,
- double e, double w)
- {
+ public void setBoundingBox(double n, double s, double e, double w) {
setDimensions(2);
- if (hasBoundingBox()) {
- throw new IllegalArgumentException("can only set bounding box once");
- }
+ if (hasBoundingBox())
+ throw new IllegalStateException("Can only set bounding box once");
int px1 = (int) (Math.round(w * 1000000));
int px2 = (int) (Math.round(e * 1000000));
int py1 = (int) (Math.round(s * 1000000));
int py2 = (int) (Math.round(n * 1000000));
- if (px1 > px2) {
- throw new IllegalArgumentException("cannot have w > e");
- }
+ if (px1 > px2)
+ throw new IllegalArgumentException("Cannot have w > e");
this.x1 = px1;
this.x2 = px2;
- if (py1 > py2) {
- throw new IllegalArgumentException("cannot have s > n");
- }
+ if (py1 > py2)
+ throw new IllegalArgumentException("Cannot have s > n");
this.y1 = py1;
this.y2 = py2;
renderRectangle = true;
}
private void adjustAspect() {
- //calculate aspect based on latitude (elevation angle)
- //no need to "optimize" for special cases, exactly 0, 30, 45, 60, or 90 degrees won't be input anyway
+ // calculate aspect based on latitude (elevation angle)
+ // no need to "optimize" for special cases, exactly 0, 30, 45, 60, or 90 degrees won't be input anyway
double degrees = (double) y / 1000000d;
if (degrees <= -90.0 || degrees >= +90.0) {
this.aspect = 0;
@@ -107,21 +87,17 @@ public class Location {
public void setGeoCircle(double ns, double ew, double radius_in_degrees) {
setDimensions(2);
- if (isGeoCircle()) {
- throw new IllegalArgumentException("can only set geo circle once");
- }
+ if (isGeoCircle())
+ throw new IllegalStateException("Can only set geo circle once");
int px = (int) (ew * 1000000);
int py = (int) (ns * 1000000);
int pr = (int) (radius_in_degrees * 1000000);
- if (ew < -180.1 || ew > +180.1) {
+ if (ew < -180.1 || ew > +180.1)
throw new IllegalArgumentException("e/w location must be in range [-180,+180]");
- }
- if (ns < -90.1 || ns > +90.1) {
+ if (ns < -90.1 || ns > +90.1)
throw new IllegalArgumentException("n/s location must be in range [-90,+90]");
- }
- if (radius_in_degrees < 0) {
+ if (radius_in_degrees < 0)
pr = -1;
- }
this.x = px;
this.y = py;
this.r = pr;
@@ -131,12 +107,10 @@ public class Location {
public void setXyCircle(int px, int py, int radius_in_units) {
setDimensions(2);
- if (isGeoCircle()) {
- throw new IllegalArgumentException("can only set geo circle once");
- }
- if (radius_in_units < 0) {
+ if (isGeoCircle())
+ throw new IllegalStateException("can only set geo circle once");
+ if (radius_in_units < 0)
radius_in_units = -1;
- }
this.x = px;
this.y = py;
this.r = radius_in_units;
@@ -145,9 +119,8 @@ public class Location {
private void parseRectangle(String rectangle) {
int endof = rectangle.indexOf(']');
- if (endof == -1) {
- throw new IllegalArgumentException("Illegal location syntax: "+rectangle);
- }
+ if (endof == -1)
+ throw new IllegalArgumentException("Illegal location syntax: " + rectangle);
String rectPart = rectangle.substring(1,endof);
StringTokenizer tokens = new StringTokenizer(rectPart, ",");
setDimensions(Integer.parseInt(tokens.nextToken()));
@@ -155,21 +128,18 @@ public class Location {
this.y1 = Integer.parseInt(tokens.nextToken());
this.x2 = Integer.parseInt(tokens.nextToken());
this.y2 = Integer.parseInt(tokens.nextToken());
- if (tokens.hasMoreTokens()) {
- throw new IllegalArgumentException("Illegal location syntax: "+rectangle);
- }
+ if (tokens.hasMoreTokens())
+ throw new IllegalArgumentException("Illegal location syntax: " + rectangle);
renderRectangle = true;
String theRest = rectangle.substring(endof+1).trim();
- if (theRest.length() >= 15 && theRest.charAt(0) == '(') {
+ if (theRest.length() >= 15 && theRest.charAt(0) == '(')
parseCircle(theRest);
- }
}
private void parseCircle(String circle) {
int endof = circle.indexOf(')');
- if (endof == -1) {
- throw new IllegalArgumentException("Illegal location syntax: "+circle);
- }
+ if (endof == -1)
+ throw new IllegalArgumentException("Illegal location syntax: " + circle);
String circlePart = circle.substring(1,endof);
StringTokenizer tokens = new StringTokenizer(circlePart, ",");
setDimensions(Integer.parseInt(tokens.nextToken()));
@@ -187,18 +157,18 @@ public class Location {
try {
aspect = Long.parseLong(aspectToken);
} catch (NumberFormatException nfe) {
- throw new IllegalArgumentException("Aspect "+aspectToken+" for location must be an integer or 'CalcLatLon' for automatic aspect calculation.", nfe);
- }
- if (aspect > 4294967295L || aspect < 0) {
- throw new IllegalArgumentException("Aspect "+aspect+" for location parameter must be less than 4294967296 (2^32)");
+ throw new IllegalArgumentException("Aspect "+aspectToken+" for location must be an integer or " +
+ "'CalcLatLon' for automatic aspect calculation.", nfe);
}
+ if (aspect > 4294967295L || aspect < 0)
+ throw new IllegalArgumentException("Aspect " + aspect + " for location parameter must be " +
+ "less than 4294967296 (2^32)");
}
}
renderCircle = true;
String theRest = circle.substring(endof+1).trim();
- if (theRest.length() > 5 && theRest.charAt(0) == '[') {
+ if (theRest.length() > 5 && theRest.charAt(0) == '[')
parseRectangle(theRest);
- }
}
public Location() {}
@@ -225,9 +195,11 @@ public class Location {
}
}
+ @Override
public String toString() {
return render(false);
}
+
public String backendString() {
return render(true);
}
@@ -284,6 +256,35 @@ public class Location {
}
}
+ @Override
+ public Location clone() {
+ try {
+ return (Location) super.clone();
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) return true;
+ if (! (other instanceof Location)) return false;
+ Location l = (Location)other;
+ return dimensions == l.dimensions
+ && renderCircle == l.renderCircle
+ && renderRectangle == l.renderRectangle
+ && this.aspect == l.aspect
+ && this.x1 == l.x1
+ && this.x2 == l.x2
+ && this.y1 == l.y1
+ && this.y2 == l.y2
+ && this.x == l.x
+ && this.y == l.y
+ && this.r == l.r;
+ }
+
+ @Override
public int hashCode() {
return toString().hashCode();
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/AndItem.java b/container-search/src/main/java/com/yahoo/prelude/query/AndItem.java
index d1a05556093..ef571794383 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/AndItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/AndItem.java
@@ -9,10 +9,12 @@ package com.yahoo.prelude.query;
*/
public class AndItem extends CompositeItem {
+ @Override
public ItemType getItemType() {
return ItemType.AND;
}
+ @Override
public String getName() {
return "AND";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/AndSegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/AndSegmentItem.java
index 2c73ffa772b..ba8e40bd5e0 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/AndSegmentItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/AndSegmentItem.java
@@ -50,8 +50,6 @@ public class AndSegmentItem extends SegmentItem implements BlockItem {
}
}
- // TODO: Is it necessary to override equals?
-
public void setWeight(int w) {
for (Iterator<Item> i = getItemIterator(); i.hasNext();) {
i.next().setWeight(w);
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/BlockItem.java b/container-search/src/main/java/com/yahoo/prelude/query/BlockItem.java
index c2fd207f548..377ed74f672 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/BlockItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/BlockItem.java
@@ -9,28 +9,24 @@ package com.yahoo.prelude.query;
*/
public interface BlockItem extends HasIndexItem {
- /**
- * The untransformed raw text from the user serving as base for
- * this item.
- */
+ /** The untransformed raw text from the user serving as base for this item. */
String getRawWord();
/** Returns the substring which is the origin of this item, or null if none */
- public Substring getOrigin();
+ Substring getOrigin();
/** Returns the value of this term as a string */
- public abstract String stringValue();
+ String stringValue();
/**
- * Is this block of text conceptually from the user query?
+ * Returns whether this block of text originates from a user and should therefore
+ * receive the normal processing applied to raw text (such as stemming).
*/
boolean isFromQuery();
boolean isStemmed();
- /**
- * Does this item represent "usual words"?
- */
+ /** Returns whether this item represents normal text */
boolean isWords();
/**
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/CompositeIndexedItem.java b/container-search/src/main/java/com/yahoo/prelude/query/CompositeIndexedItem.java
index 14fd7a33232..55adc3cba8d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/CompositeIndexedItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/CompositeIndexedItem.java
@@ -37,9 +37,8 @@ public abstract class CompositeIndexedItem extends CompositeTaggableItem impleme
/** Sets the name of the index to search */
public void setIndexName(String index) {
- if (index == null) {
+ if (index == null)
index = "";
- }
this.index = index;
}
@@ -51,17 +50,15 @@ public abstract class CompositeIndexedItem extends CompositeTaggableItem impleme
}
}
+ @Override
public boolean equals(Object object) {
- if (!super.equals(object)) {
- return false;
- }
+ if (!super.equals(object)) return false;
IndexedItem other = (IndexedItem) object; // Ensured by superclass
- if (!this.index.equals(other.getIndexName())) {
- return false;
- }
+ if (!this.index.equals(other.getIndexName())) return false;
return true;
}
+ @Override
public int hashCode() {
return super.hashCode() + 31 * index.hashCode();
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java
index 71d090736fe..aaa4d33c6dc 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/CompositeItem.java
@@ -74,9 +74,8 @@ public abstract class CompositeItem extends Item {
* @throws IndexOutOfBoundsException if the index is out of range
*/
public void addItem(int index, Item item) {
- if (index > subitems.size() || index < 0) {
+ if (index > subitems.size() || index < 0)
throw new IndexOutOfBoundsException("Could not add a subitem at position " + index + " to " + this);
- }
adding(item);
subitems.add(index, item);
}
@@ -97,7 +96,7 @@ public abstract class CompositeItem extends Item {
}
/**
- * Replaces the item at the given index
+ * Replaces the item at the given index.
*
* @param index the (0-base) index of the item to replace
* @param item the new item
@@ -118,7 +117,7 @@ public abstract class CompositeItem extends Item {
/**
* Returns the index of a subitem
*
- * @param item The child item to find the index of
+ * @param item the child item to find the index of
* @return the 0-base index of the child or -1 if there is no such child
*/
public int getItemIndex(Item item) {
@@ -218,6 +217,7 @@ public abstract class CompositeItem extends Item {
}
/** Returns a deep copy of this item */
+ @Override
public CompositeItem clone() {
CompositeItem copy = (CompositeItem) super.clone();
@@ -271,12 +271,11 @@ public abstract class CompositeItem extends Item {
return -1;
}
+ @Override
public int hashCode() {
int code = getName().hashCode() + subitems.size() * 17;
-
- for (int i = 0; i < subitems.size() && i <= 5; i++) {
+ for (int i = 0; i < subitems.size() && i <= 5; i++)
code += subitems.get(i).hashCode();
- }
return code;
}
@@ -284,17 +283,12 @@ public abstract class CompositeItem extends Item {
* Returns whether this item is of the same class and
* contains the same state as the given item
*/
+ @Override
public boolean equals(Object object) {
- if (!super.equals(object)) {
- return false;
- }
+ if (!super.equals(object)) return false;
CompositeItem other = (CompositeItem) object; // Ensured by superclass
-
- if (!this.subitems.equals(other.subitems)) {
- return false;
- }
-
+ if ( ! this.subitems.equals(other.subitems)) return false;
return true;
}
@@ -306,12 +300,30 @@ public abstract class CompositeItem extends Item {
return false;
}
+ @Override
+ public int getTermCount() {
+ int terms = 0;
+ for (Item item : subitems) {
+ terms += item.getTermCount();
+ }
+ return terms;
+ }
+
+ /**
+ * Will return its single child if itself can safely be omitted.
+ *
+ * @return a valid Item or empty Optional if it can not be done
+ */
+ public Optional<Item> extractSingleChild() {
+ return getItemCount() == 1 ? Optional.of(getItem(0)) : Optional.empty();
+ }
+
/** Handles mutator calls correctly */
private static class ListIteratorWrapper implements ListIterator<Item> {
- private CompositeItem owner;
+ private final CompositeItem owner;
- private ListIterator<Item> wrapped;
+ private final ListIterator<Item> wrapped;
private Item current = null;
@@ -320,47 +332,54 @@ public abstract class CompositeItem extends Item {
wrapped = owner.subitems.listIterator();
}
+ @Override
public boolean hasNext() {
return wrapped.hasNext();
}
+ @Override
public Item next() {
current = wrapped.next();
return current;
}
+ @Override
public boolean hasPrevious() {
return wrapped.hasPrevious();
}
+ @Override
public Item previous() {
- Item current = wrapped.previous();
-
+ current = wrapped.previous();
return current;
}
+ @Override
public int nextIndex() {
return wrapped.nextIndex();
}
+ @Override
public int previousIndex() {
return wrapped.previousIndex();
}
+ @Override
public void remove() {
owner.removing(current);
wrapped.remove();
}
+ @Override
public void set(Item o) {
Item newItem = o;
-
owner.removing(current);
owner.adding(newItem);
current = newItem;
wrapped.set(newItem);
}
+ @Override
public void add(Item o) {
Item newItem = o;
@@ -371,22 +390,4 @@ public abstract class CompositeItem extends Item {
}
- @Override
- public int getTermCount() {
- int terms = 0;
- for (Item item : subitems) {
- terms += item.getTermCount();
- }
- return terms;
- }
-
- /**
- * Will return its single child if itself can safely be omitted.
- *
- * @return a valid Item or empty Optional if it can not be done
- */
- public Optional<Item> extractSingleChild() {
- return getItemCount() == 1 ? Optional.of(getItem(0)) : Optional.empty();
- }
-
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/CompositeTaggableItem.java b/container-search/src/main/java/com/yahoo/prelude/query/CompositeTaggableItem.java
index 46867c2af81..4d1cf1101b5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/CompositeTaggableItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/CompositeTaggableItem.java
@@ -3,7 +3,7 @@ package com.yahoo.prelude.query;
/**
* Common implementation for Item classes implementing the TaggableItem interface.
- * Note that this file exist in 3 copies that should be kept in sync:
+ * Note that this file exists in 3 copies that should be kept in sync:
*
* CompositeTaggableItem.java
* SimpleTaggableItem.java
@@ -28,8 +28,8 @@ public abstract class CompositeTaggableItem extends CompositeItem implements Tag
/** See {@link TaggableItem#setConnectivity} */
public void setConnectivity(Item item, double connectivity) {
if (!(item instanceof TaggableItem)) {
- throw new IllegalArgumentException("setConnectivity item must be taggable, was: "
- + item.getClass() + " [" + item + "]");
+ throw new IllegalArgumentException("setConnectivity item must be taggable, was: " +
+ item.getClass() + " [" + item + "]");
}
setHasUniqueID(true);
item.setHasUniqueID(true);
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/ExactStringItem.java b/container-search/src/main/java/com/yahoo/prelude/query/ExactStringItem.java
index e313d4e1fe8..cdd1025f3b3 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/ExactStringItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/ExactStringItem.java
@@ -17,15 +17,19 @@ public class ExactStringItem extends WordItem {
super(substring, isFromQuery);
}
+ @Override
public ItemType getItemType() {
return ItemType.EXACT;
}
+ @Override
public String getName() {
return "EXACTSTRING";
}
+ @Override
public String stringValue() {
return getWord();
}
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java b/container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java
index fd1449d5851..712dbbfc489 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/GeoLocationItem.java
@@ -2,23 +2,22 @@
package com.yahoo.prelude.query;
-import com.google.common.annotations.Beta;
import com.yahoo.prelude.Location;
import java.nio.ByteBuffer;
/**
* This represents a geo-location in the query tree.
* Used for closeness(fieldname) and distance(fieldname) rank features.
+ *
* @author arnej
*/
-@Beta
public class GeoLocationItem extends TermItem {
private Location location;
/**
* Construct from a Location, which must be geo circle with an attribute set.
- **/
+ */
public GeoLocationItem(Location location) {
this(location, location.getAttribute());
if (! location.hasAttribute()) {
@@ -30,7 +29,7 @@ public class GeoLocationItem extends TermItem {
* Construct from a Location and a field name.
* The Location must be a geo circle.
* If the Location has an attribute set, it must match the field name.
- **/
+ */
public GeoLocationItem(Location location, String fieldName) {
super(fieldName, false);
if (location.hasAttribute() && ! location.getAttribute().equals(fieldName)) {
@@ -91,6 +90,13 @@ public class GeoLocationItem extends TermItem {
}
@Override
+ public GeoLocationItem clone() {
+ var clone = (GeoLocationItem)super.clone();
+ clone.location = this.location.clone();
+ return clone;
+ }
+
+ @Override
public String getIndexedString() {
return location.toString();
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/HasIndexItem.java b/container-search/src/main/java/com/yahoo/prelude/query/HasIndexItem.java
index b137fbcb947..aececf51584 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/HasIndexItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/HasIndexItem.java
@@ -4,7 +4,7 @@ package com.yahoo.prelude.query;
/**
* An interface for items where it is useful to access an index name.
*
- * @author Steinar Knutsen
+ * @author Steinar Knutsen
*/
public interface HasIndexItem {
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/Highlight.java b/container-search/src/main/java/com/yahoo/prelude/query/Highlight.java
index 44d9d10b603..f393e7601b5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/Highlight.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/Highlight.java
@@ -6,6 +6,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import static com.yahoo.language.LinguisticsCase.toLowerCase;
@@ -16,9 +17,7 @@ import static com.yahoo.language.LinguisticsCase.toLowerCase;
*/
public class Highlight implements Cloneable {
- /**
- * The name of the property map which contains extra highlight terms
- */
+ /** The name of the property map which contains extra highlight terms */
public static final String HIGHLIGHTTERMS = "highlightterms";
private Map<String, AndItem> highlightItems = new LinkedHashMap<>();
@@ -39,8 +38,8 @@ public class Highlight implements Cloneable {
/**
* Add custom highlight term
*
- * @param field Field name
- * @param item Term to be highlighted
+ * @param field the field name
+ * @param item the term to be highlighted
*/
public void addHighlightTerm(String field, String item) {
addHighlightItem(field, new WordItem(toLowerCase(item), field, true));
@@ -49,23 +48,18 @@ public class Highlight implements Cloneable {
/**
* Add custom highlight phrase
*
- * @param field Field name
- * @param phrase List of terms to be highlighted as a phrase
+ * @param field the field name
+ * @param phrase the list of terms to be highlighted as a phrase
*/
public void addHighlightPhrase(String field, List<String> phrase) {
PhraseItem pi = new PhraseItem();
pi.setIndexName(field);
- for (String s : phrase) {
+ for (String s : phrase)
pi.addItem(new WordItem(toLowerCase(s), field, true));
- }
addHighlightItem(field, pi);
}
- /**
- * Returns the modifiable map of highlight items (never null)
- *
- * @return Map of highlight items
- */
+ /** Returns the modifiable map of highlight items (never null) */
public Map<String, AndItem> getHighlightItems() {
return highlightItems;
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/IndexedSegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/IndexedSegmentItem.java
index 1594c6357e2..aaace3043ba 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/IndexedSegmentItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/IndexedSegmentItem.java
@@ -4,6 +4,7 @@ package com.yahoo.prelude.query;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
* Common implementation for Item classes implementing the IndexedItem interface.
@@ -60,16 +61,14 @@ public abstract class IndexedSegmentItem extends TaggableSegmentItem implements
@Override
public boolean equals(Object object) {
if ( ! super.equals(object)) return false;
-
- IndexedItem other = (IndexedItem) object; // Ensured by superclass
+ IndexedItem other = (IndexedItem) object;
if ( ! this.index.equals(other.getIndexName())) return false;
-
return true;
}
@Override
public int hashCode() {
- return super.hashCode() + 31 * index.hashCode();
+ return Objects.hash(super.hashCode(), index);
}
public abstract String getIndexedString();
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/IntItem.java b/container-search/src/main/java/com/yahoo/prelude/query/IntItem.java
index da2c3e6fa51..5664ecfb3d2 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/IntItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/IntItem.java
@@ -4,6 +4,7 @@ package com.yahoo.prelude.query;
import java.math.BigInteger;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
@@ -224,7 +225,7 @@ public class IntItem extends TermItem {
@Override
public int hashCode() {
- return super.hashCode() + 199 * expression.hashCode();
+ return Objects.hash(super.hashCode(), expression);
}
@Override
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/Item.java b/container-search/src/main/java/com/yahoo/prelude/query/Item.java
index 24cfa3a1c5b..47efed323a9 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/Item.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/Item.java
@@ -15,15 +15,12 @@ import java.util.Optional;
/**
- * <p>A term of the query language. As "term" is also the common term (sorry)
- * for a literal to be found (or not) in a search index, the term <i>item</i>
- * is used for <i>query language</i> terms.</p>
- *
- * <p>The query is represented as a composite tree of
- * Item subclasses. This allow arbitrary complex combinations of ands,
- * nots, phrases and so on.</p>
- *
- * <p>Items are in general mutable and not thread safe.</p>
+ * An item in the tree which defines which documents will match a query.
+ * Item subclasses can be composed freely to create arbitrary complex matching trees.
+ * Items are in general mutable and not thread safe.
+ * They can be deeply cloned by calling clone().
+ * Their identity is defined by their content
+ * (i.e the field value of two items decide if they are equal).
*
* @author bratseth
* @author havardpe
@@ -73,11 +70,6 @@ public abstract class Item implements Cloneable {
}
- public static final int DEFAULT_WEIGHT = 100;
-
- /** The relative importance of this term in the query. Default is 100 */
- private int weight = DEFAULT_WEIGHT;
-
/**
* The definitions in Item.ItemCreator must match the ones in
* searchlib/src/searchlib/parsequery/parse.h
@@ -95,6 +87,11 @@ public abstract class Item implements Cloneable {
}
+ public static final int DEFAULT_WEIGHT = 100;
+
+ /** The relative importance of this term in the query. Default is 100 */
+ private int weight = DEFAULT_WEIGHT;
+
private boolean fromSpecialToken = false;
private ItemCreator creator = ItemCreator.ORIG;
@@ -390,34 +387,32 @@ public abstract class Item implements Cloneable {
}
}
- /**
- * Returns whether this item is of the same class and
- * contains the same state as the given item
- */
+ /** Returns whether this item is of the same class and contains the same state as the given item. */
@Override
- public boolean equals(Object object) {
- if (object == null) {
- return false;
- }
- if (object.getClass() != this.getClass()) {
- return false;
- } // Fails on different c.l.'s
-
- Item other = (Item) object;
-
- if (this.creator != other.creator) {
- return false;
- }
- if (this.weight != other.weight) {
- return false;
- }
-
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (o == this) return true;
+ if (o.getClass() != this.getClass()) return false;
+ Item other = (Item)o;
+ if (this.weight != other.weight) return false;
+ if (this.fromSpecialToken != other.fromSpecialToken) return false;
+ if (this.creator != other.creator) return false;
+ if ( ! Objects.equals(this.annotations, other.annotations)) return false;
+ if (this.isRanked != other.isRanked) return false;
+ if (this.usePositionData != other.usePositionData) return false;
+ if ( ! Objects.equals(this.label, other.label)) return false;
+ if (this.uniqueID != other.uniqueID) return false;
+ if ( ! Objects.equals(this.connectedItem, other.connectedItem)) return false;
+ if (this.connectivity != other.connectivity) return false;
+ if (this.significance != other.significance) return false;
+ if (this.language != other.language) return false;
return true;
}
@Override
public int hashCode() {
- return weight * 29 + creator.code;
+ return Objects.hash(weight, fromSpecialToken, creator, annotations, isRanked, usePositionData, label,
+ uniqueID, connectedItem, connectivity, significance, language);
}
protected boolean hasUniqueID() {
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/ItemHelper.java b/container-search/src/main/java/com/yahoo/prelude/query/ItemHelper.java
index 1deb3ed1d3c..3c50a87cbe6 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/ItemHelper.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/ItemHelper.java
@@ -11,38 +11,6 @@ import java.util.List;
*/
public class ItemHelper {
- /*
- We could have exchanged the following 3 functions with this
- But this introspection is a bit too much of a hack, so we'll leave it with this.
-
-
- public static <T extends CompositeItem> T ensureIsItem(Item unknown,Class<T> tClass) {
-
- if(unknown != null && tClass.isInstance(unknown)) {
- return (T) unknown;
- }
- T item;
-
- try {
- Constructor<T> n = tClass.getConstructor();
- item = n.newInstance();
- } catch (NoSuchMethodException e) {
- return null;
- } catch (InvocationTargetException e) {
- return null;
- } catch (IllegalAccessException e) {
- return null;
- } catch (InstantiationException e) {
- return null;
- }
- if(item != null) {
- item.addItem(unknown);
- }
- return item;
-
- }
- */
-
/** Traverse the query tree and return total number of terms */
int getNumTerms(Item rootNode) {
int numTerms = 0;
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/MarkerWordItem.java b/container-search/src/main/java/com/yahoo/prelude/query/MarkerWordItem.java
index 0f22d99a744..75187f8b8e1 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/MarkerWordItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/MarkerWordItem.java
@@ -4,6 +4,8 @@ package com.yahoo.prelude.query;
import com.yahoo.net.UrlTokenizer;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
+import java.util.Objects;
+
/**
* Special words known by the index used for marking things.
@@ -35,21 +37,14 @@ public class MarkerWordItem extends WordItem {
@Override
public boolean equals(Object o) {
- if (!super.equals(o)) {
- return false;
- }
- if (!(o instanceof MarkerWordItem)) {
- return false;
- }
-
+ if (!super.equals(o)) return false;
MarkerWordItem other = (MarkerWordItem) o;
-
return markerWord.equals(other.markerWord);
}
@Override
public int hashCode() {
- return super.hashCode() + 499 * markerWord.hashCode();
+ return Objects.hash(super.hashCode(), markerWord);
}
@Override
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NearItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NearItem.java
index ffc16bfa298..3a2b6c974bf 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NearItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NearItem.java
@@ -5,6 +5,7 @@ import com.yahoo.compress.IntegerCompressor;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
@@ -77,15 +78,6 @@ public class NearItem extends CompositeItem {
}
@Override
- public int hashCode() {
- return super.hashCode() + 23* distance;
- }
-
- /**
- * Returns whether this item is of the same class and
- * contains the same state as the given item
- */
- @Override
public boolean equals(Object object) {
if (!super.equals(object)) return false;
NearItem other = (NearItem) object; // Ensured by superclass
@@ -93,4 +85,9 @@ public class NearItem extends CompositeItem {
return true;
}
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), distance);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java
index 5b7eb1a5053..4e848173f77 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NearestNeighborItem.java
@@ -6,6 +6,7 @@ import com.yahoo.compress.IntegerCompressor;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
* Represent a query item matching the K nearest neighbors in a multi-dimensional vector space.
@@ -33,7 +34,7 @@ public class NearestNeighborItem extends SimpleTaggableItem {
/** Returns the K number of hits to produce */
public int getTargetNumHits() { return targetNumHits; }
- /** Returns the field name */
+ /** Returns the name of the index (field) to be searched */
public String getIndexName() { return field; }
/** Returns the distance threshold for nearest-neighbor hits */
@@ -106,4 +107,23 @@ public class NearestNeighborItem extends SimpleTaggableItem {
discloser.addProperty("targetHits", targetNumHits);
}
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ NearestNeighborItem other = (NearestNeighborItem)o;
+ if (this.targetNumHits != other.targetNumHits) return false;
+ if (this.hnswExploreAdditionalHits != other.hnswExploreAdditionalHits) return false;
+ if (this.distanceThreshold != other.distanceThreshold) return false;
+ if (this.approximate != other.approximate) return false;
+ if ( ! this.field.equals(other.field)) return false;
+ if ( ! this.queryTensorName.equals(other.queryTensorName)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), targetNumHits, hnswExploreAdditionalHits,
+ distanceThreshold, approximate, field, queryTensorName);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java
index 7483863e459..d9c903de374 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NonReducibleCompositeItem.java
@@ -6,9 +6,7 @@ import java.util.Optional;
/**
* A composite item which specifies semantics which are not maintained
* if an instance with a single child is replaced by the single child.
- * <p>
* Most composites, like AND and OR, are reducible as e.g (AND a) is semantically equal to (a).
- * <p>
* This type functions as a marker type for query rewriters.
*
* @author bratseth
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java
index 22079cf0666..833b8635f61 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NotItem.java
@@ -1,11 +1,9 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-import com.yahoo.protect.Validator;
-
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
/**
* A composite item where the first item is positive and the following
@@ -16,18 +14,17 @@ import java.util.List;
// TODO: Handle nulls by creating nullItem or checking in encode/toString
public class NotItem extends CompositeItem {
+ @Override
public ItemType getItemType() {
return ItemType.NOT;
}
+ @Override
public String getName() {
return "NOT";
}
- /**
- * Adds an item. The first item is the positive
- * the rest is negative
- */
+ /** Adds an item. The first item is the positive, the rest are negative */
public void addItem(Item item) {
super.addItem(item);
}
@@ -46,10 +43,7 @@ public class NotItem extends CompositeItem {
/** Returns the negative items of this: All child items except the first */
public List<Item> negativeItems() { return items().subList(1, getItemCount()); }
- /**
- * Returns the positive item (the first subitem),
- * or null if no positive items has been added
- */
+ /** Returns the positive item (the first subitem), or null if no positive items has been added. */
public Item getPositiveItem() {
if (getItemCount() == 0) {
return null;
@@ -60,10 +54,10 @@ public class NotItem extends CompositeItem {
/**
* Sets the positive item (the first item)
*
- * @return the old positive item, or null if there was no items
+ * @return the old positive item, or null if there was none
*/
public Item setPositiveItem(Item item) {
- Validator.ensureNotNull("Positive item of " + this, item);
+ Objects.requireNonNull(item, () -> "Positive item of " + this);
if (getItemCount() == 0) {
addItem(item);
return null;
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/NullItem.java b/container-search/src/main/java/com/yahoo/prelude/query/NullItem.java
index 98a9e242778..1c7716be295 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/NullItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/NullItem.java
@@ -15,30 +15,28 @@ public class NullItem extends Item {
public NullItem() {}
/** Does nothing */
+ @Override
public void setIndexName(String index) {}
+ @Override
public int encode(ByteBuffer buffer) {
- throw new RuntimeException(
- "A NullItem was attempted encoded. "
- + "This is probably a misbehaving " + "searcher.");
+ throw new IllegalStateException("A NullItem was attempted encoded. This is probably a misbehaving searcher");
}
+ @Override
public ItemType getItemType() {
- throw new RuntimeException(
- "Packet code access attempted. "
- + "A NullItem has no packet code. "
- + "This is probably a misbehaving " + "searcher.");
+ throw new IllegalStateException("Packet code access attempted. A NullItem has no packet code. " +
+ "This is probably a misbehaving searcher.");
}
- public void appendBodyString(StringBuilder buffer) {
- // No body for this Item
- return;
- }
+ @Override
+ public void appendBodyString(StringBuilder buffer) {}
public void appendHeadingString(StringBuilder buffer) {
buffer.append(getName());
}
+ @Override
public String getName() {
return "NULL";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/ONearItem.java b/container-search/src/main/java/com/yahoo/prelude/query/ONearItem.java
index 5f3796e2564..f0f5989d20d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/ONearItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/ONearItem.java
@@ -4,7 +4,6 @@ package com.yahoo.prelude.query;
/**
* Ordered NearItem.
- * <p>
* Matches as a near operator, but also demands that the operands have the
* same order in the document as in the query.
*
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/OrItem.java b/container-search/src/main/java/com/yahoo/prelude/query/OrItem.java
index 380993ec7c9..fdc4aabbcd5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/OrItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/OrItem.java
@@ -9,10 +9,12 @@ package com.yahoo.prelude.query;
*/
public class OrItem extends CompositeItem {
+ @Override
public ItemType getItemType() {
return ItemType.OR;
}
+ @Override
public String getName() {
return "OR";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java
index 00d25c94d67..fae282868f8 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PhraseItem.java
@@ -5,6 +5,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.Objects;
import java.util.Optional;
/**
@@ -43,6 +44,7 @@ public class PhraseItem extends CompositeIndexedItem {
return "PHRASE";
}
+ @Override
public void setIndexName(String index) {
super.setIndexName(index);
for (Iterator<Item> i = getItemIterator(); i.hasNext();) {
@@ -73,6 +75,7 @@ public class PhraseItem extends CompositeIndexedItem {
*
* @throws IllegalArgumentException if the given item is not a WordItem or PhraseItem
*/
+ @Override
public void addItem(Item item) {
if (item instanceof WordItem || item instanceof PhraseSegmentItem || item instanceof WordAlternativesItem) {
addIndexedItem((IndexedItem) item);
@@ -233,6 +236,7 @@ public class PhraseItem extends CompositeIndexedItem {
buffer.append("\"");
}
+ @Override
public String getIndexedString() {
StringBuilder buf = new StringBuilder();
@@ -251,6 +255,7 @@ public class PhraseItem extends CompositeIndexedItem {
return getNumWords();
}
+ @Override
public int getNumWords() {
int numWords = 0;
for (Iterator<Item> j = getItemIterator(); j.hasNext();) {
@@ -265,4 +270,15 @@ public class PhraseItem extends CompositeIndexedItem {
discloser.addProperty("explicit", explicit);
}
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ return this.explicit == ((PhraseItem)other).explicit;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), explicit);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java
index 9534a5751fd..16e22f6d482 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PhraseSegmentItem.java
@@ -5,6 +5,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.Objects;
import java.util.Optional;
@@ -63,6 +64,7 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
return "SPHRASE";
}
+ @Override
public void setIndexName(String index) {
super.setIndexName(index);
for (Iterator<Item> i = getItemIterator(); i.hasNext();) {
@@ -120,6 +122,7 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
return (WordItem) getItem(index);
}
+ @Override
protected void encodeThis(ByteBuffer buffer) {
super.encodeThis(buffer); // takes care of index bytes
}
@@ -144,6 +147,7 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
/** Returns false, no parenthezes for phrases */
+ @Override
protected boolean shouldParenthize() {
return false;
}
@@ -171,13 +175,6 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
buffer.append("'");
}
- // TODO: Must check all pertinent items
- @Override
- public boolean equals(Object object) {
- if ( ! super.equals(object)) return false;
- return true;
- }
-
@Override
public String getIndexedString() {
StringBuilder buf = new StringBuilder();
@@ -207,4 +204,15 @@ public class PhraseSegmentItem extends IndexedSegmentItem {
discloser.addProperty("explicit", explicit);
}
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ return this.explicit == ((PhraseSegmentItem)other).explicit;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), explicit);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PredicateQueryItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PredicateQueryItem.java
index da94070c94f..91a0ea4eb51 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PredicateQueryItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PredicateQueryItem.java
@@ -6,6 +6,8 @@ import com.yahoo.compress.IntegerCompressor;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
/**
* A PredicateQueryItem is a collection of feature/value-pairs
@@ -18,30 +20,26 @@ import java.util.Collection;
public class PredicateQueryItem extends SimpleTaggableItem {
private String fieldName = "predicate";
- private ArrayList<Entry> features = new ArrayList<>();
- private ArrayList<RangeEntry> rangeFeatures = new ArrayList<>();
+ private List<Entry> features = new ArrayList<>();
+ private List<RangeEntry> rangeFeatures = new ArrayList<>();
public static final long ALL_SUB_QUERIES = 0xffffffffffffffffL;
- /**
- * Sets the field name to be used for the predicates.
- * @param index name of the field.
- */
+ /** Sets the name of the index (field) to be used for the predicates. */
@Override
public void setIndexName(String index) {
this.fieldName = index;
}
- /**
- * @return the field name used for the predicates.
- */
+ /** Returns the name of the index (field) used for the predicates. */
public String getIndexName() {
return fieldName;
}
/**
* Adds a feature/value-pair to the predicate query. This feature is applied to all sub queries.
- * @param key name of the feature to be set in this query.
- * @param value value of the feature.
+ *
+ * @param key name of the feature to be set in this query
+ * @param value value of the feature
*/
public void addFeature(String key, String value) {
addFeature(key, value, ALL_SUB_QUERIES);
@@ -49,9 +47,10 @@ public class PredicateQueryItem extends SimpleTaggableItem {
/**
* Adds a feature/value-pair to the predicate query.
- * @param key name of the feature to be set in this query.
- * @param value value of the feature.
- * @param subQueryBitmap bitmap specifying which sub queries this feature applies to.
+ *
+ * @param key name of the feature to be set in this query
+ * @param value value of the feature
+ * @param subQueryBitmap bitmap specifying which sub queries this feature applies to
*/
public void addFeature(String key, String value, long subQueryBitmap) {
addFeature(new Entry(key, value, subQueryBitmap));
@@ -59,7 +58,8 @@ public class PredicateQueryItem extends SimpleTaggableItem {
/**
* Adds a feature/value-pair to the predicate query.
- * @param entry the feature to add.
+ *
+ * @param entry the feature to add
*/
public void addFeature(Entry entry) {
features.add(entry);
@@ -68,8 +68,9 @@ public class PredicateQueryItem extends SimpleTaggableItem {
/**
* Adds a range feature with a given value to the predicate query.
* This feature is applied to all sub queries.
- * @param key name of the feature to be set in this query.
- * @param value value of the feature.
+ *
+ * @param key name of the feature to be set in this query
+ * @param value value of the feature
*/
public void addRangeFeature(String key, long value) {
addRangeFeature(key, value, ALL_SUB_QUERIES);
@@ -77,9 +78,10 @@ public class PredicateQueryItem extends SimpleTaggableItem {
/**
* Adds a range feature with a given value to the predicate query.
- * @param key name of the feature to be set in this query.
- * @param value value of the feature.
- * @param subQueryBitmap bitmap specifying which sub queries this feature applies to.
+ *
+ * @param key name of the feature to be set in this query
+ * @param value value of the feature
+ * @param subQueryBitmap bitmap specifying which sub queries this feature applies to
*/
public void addRangeFeature(String key, long value, long subQueryBitmap) {
addRangeFeature(new RangeEntry(key, value, subQueryBitmap));
@@ -87,22 +89,19 @@ public class PredicateQueryItem extends SimpleTaggableItem {
/**
* Adds a range feature with a given value to the predicate query.
- * @param entry the feature to add.
+ *
+ * @param entry the feature to add
*/
public void addRangeFeature(RangeEntry entry) {
rangeFeatures.add(entry);
}
- /**
- * @return a mutable collection of feature entries.
- */
+ /** Returns a mutable collection of feature entries. */
public Collection<Entry> getFeatures() {
return features;
}
- /**
- * @return a mutable collection of range feature entries.
- */
+ /** Returns a mutable collection of range feature entries. */
public Collection<RangeEntry> getRangeFeatures() {
return rangeFeatures;
}
@@ -126,7 +125,7 @@ public class PredicateQueryItem extends SimpleTaggableItem {
return 1; // number of encoded stack dump items
}
- private void encodeFeatures(ArrayList<? extends EntryBase> features, ByteBuffer buffer) {
+ private void encodeFeatures(List<? extends EntryBase> features, ByteBuffer buffer) {
IntegerCompressor.putCompressedPositiveNumber(features.size(), buffer);
for (EntryBase e : features) {
e.encode(buffer);
@@ -173,9 +172,26 @@ public class PredicateQueryItem extends SimpleTaggableItem {
return clone;
}
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (PredicateQueryItem)o;
+ if ( ! this.fieldName.equals(other.fieldName)) return false;
+ if ( ! this.features.equals(other.features)) return false;
+ if ( ! this.rangeFeatures.equals(other.rangeFeatures)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), fieldName, features, rangeFeatures);
+ }
+
+ /** An entry in a predicate item. This is immutable. */
public abstract static class EntryBase {
- private String key;
- private long subQueryBitmap;
+
+ private final String key;
+ private final long subQueryBitmap;
public EntryBase(String key, long subQueryBitmap) {
this.key = key;
@@ -190,15 +206,29 @@ public class PredicateQueryItem extends SimpleTaggableItem {
return subQueryBitmap;
}
- public void setSubQueryBitmap(long subQueryBitmap) {
- this.subQueryBitmap = subQueryBitmap;
+ public abstract void encode(ByteBuffer buffer);
+
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+
+ var other = (EntryBase)o;
+ if ( ! Objects.equals(this.key, other.key)) return false;
+ if ( this.subQueryBitmap != other.subQueryBitmap) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), key, subQueryBitmap);
}
- public abstract void encode(ByteBuffer buffer);
}
+ /** A unique entry in a predicate item. This is immutable. */
public static class Entry extends EntryBase {
- private String value;
+
+ private final String value;
public Entry(String key, String value) {
this(key, value, ALL_SUB_QUERIES);
@@ -218,10 +248,25 @@ public class PredicateQueryItem extends SimpleTaggableItem {
putString(getValue(), buffer);
buffer.putLong(getSubQueryBitmap());
}
+
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ if ( ! Objects.equals(this.value, ((Entry)other).value)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), value);
+ }
+
}
+ /** A range entry in a predicate item. This is immutable. */
public static class RangeEntry extends EntryBase {
- private long value;
+
+ private final long value;
public RangeEntry(String key, long value) {
this(key, value, ALL_SUB_QUERIES);
@@ -242,5 +287,19 @@ public class PredicateQueryItem extends SimpleTaggableItem {
buffer.putLong(getValue());
buffer.putLong(getSubQueryBitmap());
}
+
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ if ( this.value != ((RangeEntry)other).value) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), value);
+ }
+
}
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PrefixItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PrefixItem.java
index e48759323fb..fbe0f2d609c 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PrefixItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PrefixItem.java
@@ -19,14 +19,17 @@ public class PrefixItem extends WordItem {
public PrefixItem(String prefix, String indexName) { super(prefix, indexName); }
+ @Override
public ItemType getItemType() {
return ItemType.PREFIX;
}
+ @Override
public String getName() {
return "PREFIX";
}
+ @Override
public String stringValue() {
return getWord() + "*";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedInteger.java b/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedInteger.java
index 7b93cf30b42..bf8fb2c7d9e 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedInteger.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedInteger.java
@@ -2,11 +2,14 @@
package com.yahoo.prelude.query;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
+ * An int item which cannot provide its own index (field) name, but will always query the index
+ * specified by the parent item it is added to.
+ *
* @author baldersheim
*/
-// TODO: Fix javadoc
public class PureWeightedInteger extends PureWeightedItem {
private final long value;
@@ -40,7 +43,20 @@ public class PureWeightedInteger extends PureWeightedItem {
buffer.append(value);
super.appendBodyString(buffer);
}
+
public long getValue() {
return value;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ return value == ((PureWeightedInteger)other).value;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), value);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedItem.java b/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedItem.java
index f29f120f353..cf7cf87434c 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedItem.java
@@ -4,14 +4,21 @@ package com.yahoo.prelude.query;
import java.nio.ByteBuffer;
/**
+ * An item which cannot provide its own index (field) name, but will always query the index
+ * specified by the parent item it is added to.
+ * It's more efficient to use pure items where possible instead of
+ * {@link TermItem} children ({@link WordItem}, {@link IntItem})
+ * who each carry their own index name.
+ *
* @author baldersheim
*/
-// TODO: Fix javadoc
public abstract class PureWeightedItem extends Item {
public PureWeightedItem(int weight) {
setWeight(weight);
}
+
+ /** Ignored. */
@Override
public void setIndexName(String index) {
// No index
@@ -19,7 +26,7 @@ public abstract class PureWeightedItem extends Item {
@Override
public String getName() {
- return getItemType().name(); //To change body of implemented methods use File | Settings | File Templates.
+ return getItemType().name();
}
@Override
@@ -32,4 +39,5 @@ public abstract class PureWeightedItem extends Item {
protected void appendBodyString(StringBuilder buffer) {
buffer.append(':').append(getWeight());
}
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedString.java b/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedString.java
index 409915fbd1e..58171070678 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedString.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/PureWeightedString.java
@@ -2,11 +2,14 @@
package com.yahoo.prelude.query;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
+ * A word item which cannot provide its own index (field) name, but will always query the index
+ * specified by the parent item it is added to.
+ *
* @author baldersheim
*/
-// TODO: Fix javadoc
public class PureWeightedString extends PureWeightedItem {
private final String value;
@@ -14,6 +17,7 @@ public class PureWeightedString extends PureWeightedItem {
public PureWeightedString(String value) {
this(value, 100);
}
+
public PureWeightedString(String value, int weight) {
super(weight);
this.value = value;
@@ -44,4 +48,16 @@ public class PureWeightedString extends PureWeightedItem {
public String getString() {
return value;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ return Objects.equals(value, ((PureWeightedString)other).value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), value);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java
index 77814c01213..1f30833b3db 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/QueryCanonicalizer.java
@@ -30,7 +30,7 @@ public class QueryCanonicalizer {
}
/**
- * Canonicalize this query
+ * Canonicalizes this query
*
* @return null if the query is valid, an error message if it is invalid
*/
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/RangeItem.java b/container-search/src/main/java/com/yahoo/prelude/query/RangeItem.java
index 557c86ffaa1..afe660e58a5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/RangeItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/RangeItem.java
@@ -109,5 +109,4 @@ public class RangeItem extends IntItem {
return getToLimit().number();
}
-
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/RankItem.java b/container-search/src/main/java/com/yahoo/prelude/query/RankItem.java
index 094fa4bb748..d2ae41ff726 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/RankItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/RankItem.java
@@ -14,10 +14,12 @@ package com.yahoo.prelude.query;
*/
public class RankItem extends CompositeItem {
+ @Override
public ItemType getItemType() {
return ItemType.RANK;
}
+ @Override
public String getName() {
return "RANK";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java
index a02991db0ae..ba884d530c8 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/SameElementItem.java
@@ -5,6 +5,7 @@ import com.yahoo.protect.Validator;
import java.nio.ByteBuffer;
import java.util.Iterator;
+import java.util.Objects;
import java.util.Optional;
/**
@@ -75,5 +76,18 @@ public class SameElementItem extends NonReducibleCompositeItem {
public String getName() {
return getItemType().toString();
}
+
public String getFieldName() { return fieldName; }
+
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ return Objects.equals(this.fieldName, ((SameElementItem)other).fieldName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), fieldName);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SegmentItem.java
index e2f0ece5501..d02a98486a0 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/SegmentItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/SegmentItem.java
@@ -4,6 +4,8 @@ package com.yahoo.prelude.query;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
+import java.util.Objects;
+
/**
* An immutable and'ing of a collection of sub-expressions. It does not
@@ -15,13 +17,13 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
public abstract class SegmentItem extends CompositeItem implements BlockItem {
private boolean locked = false;
- private String rawWord;
- private String value;
- private boolean isFromQuery;
+ private final String rawWord;
+ private final String value;
+ private final boolean isFromQuery;
private boolean isFromUser;
- private boolean stemmed;
+ private final boolean stemmed;
private SegmentingRule segmentingRule = SegmentingRule.LANGUAGE_DEFAULT;
- private Substring origin;
+ private final Substring origin;
/**
* Creates a new segment item
@@ -42,7 +44,7 @@ public abstract class SegmentItem extends CompositeItem implements BlockItem {
* @param current the current transformed version of the raw form, or the raw form repeated if no normalized form is known
* @param isFromQuery whether this segment stems from the query received in the request
* @param stemmed whether this is stemmed
- * @param origin TODO
+ * @param origin the original text that led to this
*/
public SegmentItem(String rawWord, String current, boolean isFromQuery, boolean stemmed, Substring origin) {
this.rawWord = rawWord;
@@ -66,10 +68,12 @@ public abstract class SegmentItem extends CompositeItem implements BlockItem {
return value;
}
+ @Override
public boolean isFromQuery() {
return isFromQuery;
}
+ @Override
public boolean isStemmed() {
return stemmed;
}
@@ -87,40 +91,32 @@ public abstract class SegmentItem extends CompositeItem implements BlockItem {
return getItemCount();
}
+ @Override
public void addItem(Item item) {
- if (locked) {
- dontAdd();
- }
+ throwIfLocked();
super.addItem(item);
}
+ @Override
public void addItem(int index, Item item) {
- if (locked) {
- dontAdd();
- }
+ throwIfLocked();
super.addItem(index, item);
}
- private void dontAdd() {
- throw new IllegalArgumentException("Tried to add item to an immutable segment.");
- }
-
+ @Override
public Item removeItem(int index) {
- if (locked) {
- dontRemove();
- }
+ throwIfLocked();
return super.removeItem(index);
}
public boolean removeItem(Item item) {
- if (locked) {
- dontRemove();
- }
+ throwIfLocked();
return super.removeItem(item);
}
- private void dontRemove() {
- throw new IllegalArgumentException("Tried to remove an item from an immutable segment.");
+ private void throwIfLocked() {
+ if (locked)
+ throw new IllegalStateException("Cannot change change an immutable segment");
}
// TODO: Add a getItemIterator which is safe for immutability
@@ -140,6 +136,7 @@ public abstract class SegmentItem extends CompositeItem implements BlockItem {
return copy;
}
+ @Override
public boolean isWords() {
return true;
}
@@ -175,4 +172,24 @@ public abstract class SegmentItem extends CompositeItem implements BlockItem {
public void setSegmentingRule(SegmentingRule segmentingRule) {
this.segmentingRule = segmentingRule;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (SegmentItem)o;
+ if ( ! Objects.equals(this.rawWord, other.rawWord)) return false;
+ if ( ! Objects.equals(this.value, other.value)) return false;
+ if ( this.isFromQuery != other.isFromQuery) return false;
+ if ( this.isFromUser != other.isFromUser) return false;
+ if ( this.stemmed != other.stemmed) return false;
+ if ( this.segmentingRule != other.segmentingRule) return false;
+ if ( ! Objects.equals(this.origin, other.origin)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), rawWord, value, isFromQuery, isFromUser, stemmed, segmentingRule, origin);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SimpleIndexedItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SimpleIndexedItem.java
index 880add231ac..00a7c5cf9b7 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/SimpleIndexedItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/SimpleIndexedItem.java
@@ -4,6 +4,7 @@ package com.yahoo.prelude.query;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
* Common implementation for Item classes implementing the IndexedItem interface.
@@ -61,7 +62,7 @@ public abstract class SimpleIndexedItem extends SimpleTaggableItem implements In
@Override
public int hashCode() {
- return super.hashCode() + 113 * index.hashCode();
+ return Objects.hash(super.hashCode(), index);
}
public abstract String getIndexedString();
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/Substring.java b/container-search/src/main/java/com/yahoo/prelude/query/Substring.java
index fc77d8297d2..599805260fa 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/Substring.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/Substring.java
@@ -1,12 +1,13 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
+import java.util.Objects;
/**
* An substring which also provides access to the full (query) string it is a substring of.
- * This is immutable.
+ * This is a value object.
*
- * @author bratseth
+ * @author bratseth
*/
public class Substring {
@@ -66,4 +67,19 @@ public class Substring {
return "(" + start + ' ' + end + ')';
}
+ @Override
+ public boolean equals(Object o) {
+ if ( ! (o instanceof Substring)) return false;
+ var other = (Substring)o;
+ if (this.start != other.start) return false;
+ if (this.end != other.end) return false;
+ if (! Objects.equals(this.string, other.string)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(start, end, string);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SubstringItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SubstringItem.java
index 21dfe979ab9..cf3dfba207d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/SubstringItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/SubstringItem.java
@@ -1,7 +1,6 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-
/**
* A word that matches substrings of words
*
@@ -17,14 +16,17 @@ public class SubstringItem extends WordItem {
super(substring, isFromQuery);
}
+ @Override
public ItemType getItemType() {
return ItemType.SUBSTRING;
}
+ @Override
public String getName() {
return "SUBSTRING";
}
+ @Override
public String stringValue() {
return "*" + getWord() + "*";
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/SuffixItem.java b/container-search/src/main/java/com/yahoo/prelude/query/SuffixItem.java
index d1b0952da9c..5890a3d1000 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/SuffixItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/SuffixItem.java
@@ -1,7 +1,6 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-
/**
* A word that matches a suffix of words instead of a complete word.
*
@@ -17,14 +16,17 @@ public class SuffixItem extends WordItem {
super(suffix, isFromQuery);
}
+ @Override
public ItemType getItemType() {
return ItemType.SUFFIX;
}
+ @Override
public String getName() {
return "SUFFIX";
}
+ @Override
public String stringValue() {
return "*" + getWord();
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/TaggableItem.java b/container-search/src/main/java/com/yahoo/prelude/query/TaggableItem.java
index ac41544224b..cab1b810c0f 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/TaggableItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/TaggableItem.java
@@ -1,7 +1,6 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-
/**
* An interface used for anything which may be addressed using an external,
* unique ID in the query tree in the backend.
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/TaggableSegmentItem.java b/container-search/src/main/java/com/yahoo/prelude/query/TaggableSegmentItem.java
index ebd39e1f72c..91fb91a31b0 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/TaggableSegmentItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/TaggableSegmentItem.java
@@ -20,16 +20,19 @@ public abstract class TaggableSegmentItem extends SegmentItem implements Taggabl
super(rawWord, current, isFromQuery, stemmed, origin);
}
+ @Override
public int getUniqueID() {
return uniqueID;
}
+ @Override
public void setUniqueID(int id) {
setHasUniqueID(true);
uniqueID = id;
}
/** See {@link TaggableItem#setConnectivity} */
+ @Override
public void setConnectivity(Item item, double connectivity) {
if (!(item instanceof TaggableItem)) {
throw new IllegalArgumentException("setConnectivity item must be taggable, was: "
@@ -46,34 +49,42 @@ public abstract class TaggableSegmentItem extends SegmentItem implements Taggabl
connectedItem.connectedBacklink = this;
}
+ @Override
public Item getConnectedItem() {
return connectedItem;
}
+ @Override
public double getConnectivity() {
return connectivity;
}
+ @Override
public void setSignificance(double significance) {
setHasUniqueID(true);
setExplicitSignificance(true);
this.significance = significance;
}
+ @Override
public void setExplicitSignificance(boolean explicitSignificance) {
this.explicitSignificance = explicitSignificance;
}
+ @Override
public boolean hasExplicitSignificance() {
return explicitSignificance;
}
+ @Override
public double getSignificance() {
return significance;
}
//Change access privilege from protected to public.
+ @Override
public boolean hasUniqueID() {
return super.hasUniqueID();
}
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/TermItem.java b/container-search/src/main/java/com/yahoo/prelude/query/TermItem.java
index 2794c310010..9d74fdbefe5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/TermItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/TermItem.java
@@ -1,11 +1,10 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
-
+import java.util.Objects;
/**
* Superclass of "leaf" conditions containing a single entity which is either matched in a field or not.
@@ -16,7 +15,7 @@ import java.nio.ByteBuffer;
public abstract class TermItem extends SimpleIndexedItem implements BlockItem {
/** Whether the term is from the raw query or is synthetic. */
- private final boolean isFromQuery;
+ private boolean isFromQuery;
/** Whether accent dropping should be performed */
private boolean normalizable = true;
@@ -70,6 +69,7 @@ public abstract class TermItem extends SimpleIndexedItem implements BlockItem {
* the superstring this substring was a part of, e.g the whole query string.
* If this did not originate directly from a user string, this is null.
*/
+ @Override
public Substring getOrigin() { return origin; }
/**
@@ -77,8 +77,13 @@ public abstract class TermItem extends SimpleIndexedItem implements BlockItem {
* Only terms from the user should be modified by query rewriters which attempts to improve the
* precision or recall of the user's query.
*/
+ @Override
public boolean isFromQuery() { return isFromQuery; }
+ public void setFromQuery(boolean isFromQuery) {
+ this.isFromQuery = isFromQuery;
+ }
+
@Override
public abstract boolean isWords();
@@ -112,4 +117,19 @@ public abstract class TermItem extends SimpleIndexedItem implements BlockItem {
public void setSegmentingRule(SegmentingRule segmentingRule) { this.segmentingRule = segmentingRule; }
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (TermItem)o;
+ if ( this.isFromQuery != other.isFromQuery) return false;
+ if ( this.normalizable != other.normalizable) return false;
+ if ( this.segmentingRule != other.segmentingRule) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), isFromQuery, normalizable, segmentingRule);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/TermType.java b/container-search/src/main/java/com/yahoo/prelude/query/TermType.java
index c041472d5aa..309befd80f5 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/TermType.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/TermType.java
@@ -10,19 +10,19 @@ package com.yahoo.prelude.query;
*/
public class TermType {
- public static TermType RANK = new TermType("rank", RankItem.class, null, "$");
+ public static final TermType RANK = new TermType("rank", RankItem.class, null, "$");
- public static TermType AND = new TermType("and", AndItem.class, null, "+");
+ public static final TermType AND = new TermType("and", AndItem.class, null, "+");
- public static TermType OR = new TermType("or", OrItem.class, null, "?");
+ public static final TermType OR = new TermType("or", OrItem.class, null, "?");
- public static TermType NOT = new TermType("not", NotItem.class, null, "-");
+ public static final TermType NOT = new TermType("not", NotItem.class, null, "-");
- public static TermType PHRASE = new TermType("phrase", PhraseItem.class, null, "\"");
+ public static final TermType PHRASE = new TermType("phrase", PhraseItem.class, null, "\"");
- public static TermType EQUIV = new TermType("equiv", EquivItem.class, null, "");
+ public static final TermType EQUIV = new TermType("equiv", EquivItem.class, null, "");
- public static TermType DEFAULT = new TermType("", CompositeItem.class, AndItem.class, "");
+ public static final TermType DEFAULT = new TermType("", CompositeItem.class, AndItem.class, "");
public final String name;
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/UriItem.java b/container-search/src/main/java/com/yahoo/prelude/query/UriItem.java
index 89a3281f1ca..d25d32614af 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/UriItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/UriItem.java
@@ -4,6 +4,7 @@ package com.yahoo.prelude.query;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
+import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -78,4 +79,19 @@ public class UriItem extends PhraseItem {
return items.stream().map(item -> ((WordItem)item).getWord()).collect(Collectors.joining(" "));
}
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (UriItem)o;
+ if ( this.startAnchorDefault != other.startAnchorDefault) return false;
+ if ( this.endAnchorDefault != other.endAnchorDefault) return false;
+ if ( ! Objects.equals(this.sourceString, other.sourceString)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), startAnchorDefault, endAnchorDefault, sourceString);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/WandItem.java b/container-search/src/main/java/com/yahoo/prelude/query/WandItem.java
index cb71e0b90bf..8aef14a11b8 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/WandItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/WandItem.java
@@ -6,6 +6,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
import java.util.Map;
+import java.util.Objects;
/**
* A weighted set query item to be evaluated as a Wand with dot product scoring.
@@ -113,4 +114,19 @@ public class WandItem extends WeightedSetItem {
discloser.addProperty("thresholdBoostFactor", thresholdBoostFactor);
}
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (WandItem)o;
+ if ( this.targetNumHits != other.targetNumHits) return false;
+ if ( this.scoreThreshold != other.scoreThreshold) return false;
+ if ( this.thresholdBoostFactor != other.thresholdBoostFactor) return false;
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), targetNumHits, scoreThreshold, thresholdBoostFactor);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java b/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java
index 393a498dd3e..5ffd4d1584d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/WeakAndItem.java
@@ -5,6 +5,7 @@ import com.yahoo.compress.IntegerCompressor;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
* Weak And of a collection of sub-expressions:
@@ -53,6 +54,10 @@ public final class WeakAndItem extends NonReducibleCompositeItem {
@Override
public String getName() { return "WEAKAND"; }
+ /**
+ * Sets the default index name to apply to all child items of this.
+ * This is useful in conjunction with using {@link PureWeightedItem}s as children.
+ */
@Override
public void setIndexName(String index) {
String toSet = (index == null) ? "" : index;
@@ -60,6 +65,7 @@ public final class WeakAndItem extends NonReducibleCompositeItem {
this.index = toSet;
}
+ /** Returns the index name set for this, or null if none. */
public String getIndexName() { return index; }
/** Appends the heading of this string - <code>[getName()]([limit]) </code> */
@@ -100,7 +106,7 @@ public final class WeakAndItem extends NonReducibleCompositeItem {
}
@Override
- public int hashCode() { return super.hashCode() + 31 * n; }
+ public int hashCode() { return Objects.hash(super.hashCode(), n, index); }
/** Returns whether this item is of the same class and contains the same state as the given item. */
@Override
@@ -108,6 +114,7 @@ public final class WeakAndItem extends NonReducibleCompositeItem {
if (!super.equals(object)) return false;
WeakAndItem other = (WeakAndItem) object; // Ensured by superclass
if (this.n != other.n) return false;
+ if ( ! Objects.equals(this.index, other.index)) return false;
return true;
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/WeightedSetItem.java b/container-search/src/main/java/com/yahoo/prelude/query/WeightedSetItem.java
index d7a07824251..84a176c2f7d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/WeightedSetItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/WeightedSetItem.java
@@ -8,6 +8,7 @@ import com.yahoo.prelude.query.textualrepresentation.Discloser;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.Map;
+import java.util.Objects;
/**
* A term which contains a weighted set.
@@ -26,7 +27,7 @@ import java.util.Map;
public class WeightedSetItem extends SimpleTaggableItem {
private String indexName;
- private CopyOnWriteHashMap<Object,Integer> set;
+ private CopyOnWriteHashMap<Object, Integer> set;
/** Creates an empty weighted set; note you must provide an index name up front */
public WeightedSetItem(String indexName) {
@@ -37,6 +38,7 @@ public class WeightedSetItem extends SimpleTaggableItem {
}
set = new CopyOnWriteHashMap<>(1000);
}
+
public WeightedSetItem(String indexName, Map<Object, Integer> map) {
if (indexName == null) {
this.indexName = "";
@@ -51,11 +53,11 @@ public class WeightedSetItem extends SimpleTaggableItem {
}
/**
- * Add weighted token.
- * If token is already in the set, the maximum weight is kept.
- * NOTE: The weight must be 1 or more; negative values (and zero) are not allowed.
+ * Adds a weighted token.
+ * If this token is already in the set, the maximum weight is kept.
+ * The weight must be 1 or more; negative values (and zero) are not allowed.
*
- * @return weight of added token (might be old value, if kept)
+ * @return the weight of the added token (might be the old value, if kept)
*/
public Integer addToken(String token, int weight) {
if (token == null) throw new IllegalArgumentException("token must be a string");
@@ -72,9 +74,7 @@ public class WeightedSetItem extends SimpleTaggableItem {
return newWeight;
}
- /**
- * Add token with weight 1.
- */
+ /** Adds a token with weight 1. */
public Integer addToken(String token) {
return addToken(token, 1);
}
@@ -180,4 +180,18 @@ public class WeightedSetItem extends SimpleTaggableItem {
return clone;
}
+ @Override
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (WeightedSetItem)o;
+ if ( ! Objects.equals(this.indexName, other.indexName)) return false;
+ if ( ! Objects.equals(this.set, other.set)) return false;
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), indexName, set);
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/WordAlternativesItem.java b/container-search/src/main/java/com/yahoo/prelude/query/WordAlternativesItem.java
index 3b22bdbb163..59dad29ab5c 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/WordAlternativesItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/WordAlternativesItem.java
@@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
@@ -20,26 +21,6 @@ public class WordAlternativesItem extends TermItem {
private List<Alternative> alternatives;
- public static final class Alternative {
-
- public final String word;
- public final double exactness;
-
- public Alternative(String word, double exactness) {
- super();
- this.word = word;
- this.exactness = exactness;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("Alternative [word=").append(word).append(", exactness=").append(exactness).append("]");
- return builder.toString();
- }
-
- }
-
public WordAlternativesItem(String indexName, boolean isFromQuery, Substring origin, Collection<Alternative> terms) {
super(indexName, isFromQuery, origin);
setAlternatives(terms);
@@ -159,4 +140,55 @@ public class WordAlternativesItem extends TermItem {
setAlternatives(newTerms);
}
+ @Override
+ public WordAlternativesItem clone() {
+ var clone = (WordAlternativesItem)super.clone();
+ clone.alternatives = new ArrayList(this.alternatives);
+ return clone;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if ( ! super.equals(other)) return false;
+ return this.alternatives.equals(((WordAlternativesItem)other).alternatives);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), alternatives);
+ }
+
+ /** A word alternative. This is a value object. */
+ public static final class Alternative {
+
+ public final String word;
+ public final double exactness;
+
+ public Alternative(String word, double exactness) {
+ super();
+ this.word = word;
+ this.exactness = exactness;
+ }
+
+ @Override
+ public String toString() {
+ return "Alternative [word=" + word + ", exactness=" + exactness + "]";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ( ! (o instanceof Alternative)) return false;
+ var other = (Alternative)o;
+ if ( ! Objects.equals(this.word, other.word)) return false;
+ if (this.exactness != other.exactness) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(word, exactness);
+ }
+
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/query/WordItem.java b/container-search/src/main/java/com/yahoo/prelude/query/WordItem.java
index aa6e9b75fcb..4a2fc69a912 100644
--- a/container-search/src/main/java/com/yahoo/prelude/query/WordItem.java
+++ b/container-search/src/main/java/com/yahoo/prelude/query/WordItem.java
@@ -1,12 +1,12 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.query;
-
import com.yahoo.prelude.query.parser.Token;
import com.yahoo.prelude.query.textualrepresentation.Discloser;
import com.yahoo.protect.Validator;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
* A simple word or token to match in some field.
@@ -147,16 +147,21 @@ public class WordItem extends TermItem {
protected void appendHeadingString(StringBuilder buffer) {}
@Override
- public int hashCode() {
- return word.hashCode() + 71 * super.hashCode();
+ public boolean equals(Object o) {
+ if ( ! super.equals(o)) return false;
+ var other = (WordItem)o;
+ if ( this.words != other.words) return false;
+ if ( this.stemmed != other.stemmed) return false;
+ if ( this.fromSegmented != other.fromSegmented) return false;
+ if ( this.segmentIndex != other.segmentIndex) return false;
+ if ( ! Objects.equals(this.word, other.word)) return false;
+ if ( this.lowercased != other.lowercased) return false;
+ return true;
}
@Override
- public boolean equals(Object object) {
- if (!super.equals(object)) return false;
-
- WordItem other = (WordItem) object; // Ensured by superclass
- return this.word.equals(other.word);
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), words, stemmed, fromSegmented, segmentIndex, word, lowercased);
}
@Override