From e44509f2dfc22f95f0a13372461d6db58b66611c Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Tue, 24 May 2016 10:33:15 +0200 Subject: [PATCH] LUCENE-7277: Make Query.hashCode and Query.equals abstract. --- lucene/CHANGES.txt | 3 + lucene/MIGRATE.txt | 5 + .../lucene/search/BlendedTermQuery.java | 21 ++-- .../apache/lucene/search/BooleanQuery.java | 19 +-- .../org/apache/lucene/search/BoostQuery.java | 17 +-- .../lucene/search/ConstantScoreQuery.java | 15 +-- .../lucene/search/DisjunctionMaxQuery.java | 18 +-- .../lucene/search/DocValuesRewriteMethod.java | 24 ++-- .../apache/lucene/search/FieldValueQuery.java | 11 +- .../lucene/search/MatchAllDocsQuery.java | 10 ++ .../lucene/search/MatchNoDocsQuery.java | 29 +++-- .../lucene/search/MultiPhraseQuery.java | 20 +-- .../apache/lucene/search/MultiTermQuery.java | 27 ++--- .../MultiTermQueryConstantScoreWrapper.java | 11 +- .../lucene/search/NGramPhraseQuery.java | 16 +-- .../org/apache/lucene/search/PhraseQuery.java | 19 +-- .../apache/lucene/search/PointInSetQuery.java | 22 ++-- .../apache/lucene/search/PointRangeQuery.java | 38 ++---- .../java/org/apache/lucene/search/Query.java | 49 ++++++-- .../apache/lucene/search/SynonymQuery.java | 15 +-- .../org/apache/lucene/search/TermQuery.java | 9 +- .../search/spans/FieldMaskingSpanQuery.java | 24 ++-- .../lucene/search/spans/SpanBoostQuery.java | 18 +-- .../lucene/search/spans/SpanContainQuery.java | 16 +-- .../spans/SpanMultiTermQueryWrapper.java | 14 +-- .../lucene/search/spans/SpanNearQuery.java | 40 ++++-- .../lucene/search/spans/SpanNotQuery.java | 19 +-- .../lucene/search/spans/SpanOrQuery.java | 13 +- .../search/spans/SpanPositionCheckQuery.java | 13 +- .../lucene/search/spans/SpanTermQuery.java | 14 +-- .../lucene/search/JustCompileSearch.java | 33 +++-- .../lucene/search/TestBooleanScorer.java | 12 +- .../lucene/search/TestConstantScoreQuery.java | 11 +- .../lucene/search/TestLRUQueryCache.java | 15 ++- .../apache/lucene/search/TestNeedsScores.java | 25 ++-- .../lucene/search/TestQueryRescorer.java | 35 +++--- .../apache/lucene/search/TestScorerPerf.java | 10 +- .../apache/lucene/search/TestSortRandom.java | 16 +-- .../search/spans/JustCompileSearchSpans.java | 14 ++- .../apache/lucene/facet/DrillDownQuery.java | 21 ++-- .../lucene/facet/DrillSidewaysQuery.java | 31 ++--- .../lucene/facet/range/DoubleRange.java | 19 +-- .../apache/lucene/facet/range/LongRange.java | 19 +-- .../lucene/facet/TestDrillSideways.java | 25 ++-- .../facet/range/TestRangeFacetCounts.java | 11 +- .../search/highlight/HighlighterTest.java | 8 +- .../custom/HighlightCustomQueryTest.java | 25 +--- .../vectorhighlight/FieldQueryTest.java | 102 ++++++++-------- .../search/join/GlobalOrdinalsQuery.java | 23 ++-- .../join/GlobalOrdinalsWithScoreQuery.java | 29 ++--- .../join/PointInSetIncludingScoreQuery.java | 23 ++-- .../search/join/TermsIncludingScoreQuery.java | 27 ++--- .../search/join/ToChildBlockJoinQuery.java | 19 ++- .../search/join/ToParentBlockJoinQuery.java | 21 ++-- .../lucene/search/join/TestBlockJoin.java | 114 ++++++++++-------- .../lucene/search/join/TestJoinUtil.java | 31 +++-- .../uninverting/TestFieldCacheSortRandom.java | 19 +-- .../apache/lucene/queries/BoostingQuery.java | 27 +++-- .../lucene/queries/CommonTermsQuery.java | 48 ++++---- .../lucene/queries/CustomScoreQuery.java | 28 ++--- .../org/apache/lucene/queries/TermsQuery.java | 20 ++- .../lucene/queries/function/BoostedQuery.java | 15 ++- .../queries/function/FunctionQuery.java | 10 +- .../queries/function/FunctionRangeQuery.java | 23 ++-- .../lucene/queries/mlt/MoreLikeThisQuery.java | 55 ++++----- .../queries/payloads/PayloadScoreQuery.java | 29 +++-- .../payloads/SpanPayloadCheckQuery.java | 13 +- .../ComplexPhraseQueryParser.java | 50 +++----- .../surround/query/RewriteQuery.java | 33 +++-- .../classic/TestMultiAnalyzer.java | 49 +++++--- .../lucene/document/LatLonPointBoxQuery.java | 36 ++---- .../document/LatLonPointDistanceQuery.java | 22 ++-- .../document/LatLonPointInPolygonQuery.java | 18 +-- .../sandbox/queries/FuzzyLikeThisQuery.java | 45 +++---- .../lucene/search/DocValuesNumbersQuery.java | 20 ++- .../lucene/search/DocValuesRangeQuery.java | 24 ++-- .../lucene/search/DocValuesTermsQuery.java | 19 ++- .../lucene/search/TermAutomatonQuery.java | 45 ++++--- .../lucene/search/TestTermAutomatonQuery.java | 18 +-- .../composite/CompositeVerifyQuery.java | 21 ++-- .../composite/IntersectsRPTVerifyQuery.java | 17 ++- .../prefix/AbstractPrefixTreeQuery.java | 18 ++- .../serialized/SerializedDVStrategy.java | 14 +-- .../geopoint/search/GeoPointInBBoxQuery.java | 25 ++-- ...GeoPointTermQueryConstantScoreWrapper.java | 11 +- .../spatial3d/PointInGeo3DShapeQuery.java | 26 ++-- .../search/suggest/document/ContextQuery.java | 13 +- .../document/PrefixCompletionQuery.java | 10 ++ .../document/RegexCompletionQuery.java | 9 ++ .../apache/lucene/search/AssertingQuery.java | 9 +- .../org/apache/lucene/search/QueryUtils.java | 53 ++++---- .../search/RandomApproximationQuery.java | 14 +-- .../search/spans/AssertingSpanQuery.java | 24 ++-- .../org/apache/solr/schema/LatLonType.java | 9 +- .../org/apache/solr/search/BitDocSet.java | 16 ++- .../solr/search/CollapsingQParserPlugin.java | 22 ++-- .../org/apache/solr/search/DocSetBase.java | 17 ++- .../solr/search/ExportQParserPlugin.java | 25 ++-- .../apache/solr/search/ExtendedQueryBase.java | 2 +- .../solr/search/GraphTermsQParserPlugin.java | 12 +- .../apache/solr/search/HashQParserPlugin.java | 37 ++++-- .../apache/solr/search/JoinQParserPlugin.java | 26 ++-- .../solr/search/QueryWrapperFilter.java | 12 +- .../solr/search/ReRankQParserPlugin.java | 13 +- .../solr/search/SolrConstantScoreQuery.java | 11 +- .../apache/solr/search/SolrIndexSearcher.java | 27 ++++- .../apache/solr/search/SortedIntDocSet.java | 12 ++ .../search/join/BlockJoinFacetFilter.java | 17 +++ .../search/join/BlockJoinParentQParser.java | 11 +- .../apache/solr/search/join/GraphQuery.java | 64 ++++------ .../search/join/ScoreJoinQParserPlugin.java | 40 +++--- .../solr/update/DeleteByQueryWrapper.java | 28 ++--- .../solr/search/TestFilteredDocIdSet.java | 21 ++++ .../solr/search/TestQueryWrapperFilter.java | 14 +-- .../test/org/apache/solr/search/TestSort.java | 10 ++ 115 files changed, 1370 insertions(+), 1294 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 04153326328..18b99c22dc0 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -136,6 +136,9 @@ Documentation Other +* LUCENE-7277: Make Query.hashCode and Query.equals abstract. (Paul Elschot, + Dawid Weiss) + * LUCENE-7174: Upgrade randomizedtesting to 2.3.4. (Uwe Schindler, Dawid Weiss) * LUCENE-7205: Remove repeated nl.getLength() calls in diff --git a/lucene/MIGRATE.txt b/lucene/MIGRATE.txt index f931aea612a..7de0f47d4de 100644 --- a/lucene/MIGRATE.txt +++ b/lucene/MIGRATE.txt @@ -1,5 +1,10 @@ # Apache Lucene Migration Guide +## Query.hashCode and Query.equals are now abstract methods (LUCENE-7277) +Any custom query subclasses should redeclare equivalence relationship according +to the subclass's details. See code patterns used in existing core Lucene query +classes for details. + ## The way how number of document calculated is changed (LUCENE-6711) The number of documents (numDocs) is used to calculate term specificity (idf) and average document length (avdl). Prior to LUCENE-6711, collectionStats.maxDoc() was used for the statistics. diff --git a/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java index c0ac6bbcab2..ca9459f339b 100644 --- a/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java @@ -224,20 +224,21 @@ public final class BlendedTermQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - BlendedTermQuery that = (BlendedTermQuery) obj; - return Arrays.equals(terms, that.terms) - && Arrays.equals(contexts, that.contexts) - && Arrays.equals(boosts, that.boosts) - && rewriteMethod.equals(that.rewriteMethod); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(BlendedTermQuery other) { + return Arrays.equals(terms, other.terms) && + Arrays.equals(contexts, other.contexts) && + Arrays.equals(boosts, other.boosts) && + rewriteMethod.equals(other.rewriteMethod); } @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + Arrays.hashCode(terms); h = 31 * h + Arrays.hashCode(contexts); h = 31 * h + Arrays.hashCode(boosts); diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java index 4699df4c3aa..3371b502314 100644 --- a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java @@ -421,17 +421,18 @@ public class BooleanQuery extends Query implements Iterable { */ @Override public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - BooleanQuery that = (BooleanQuery)o; - return this.getMinimumNumberShouldMatch() == that.getMinimumNumberShouldMatch() - && this.disableCoord == that.disableCoord - && clauseSets.equals(that.clauseSets); + return sameClassAs(o) && + equalsTo(getClass().cast(o)); + } + + private boolean equalsTo(BooleanQuery other) { + return getMinimumNumberShouldMatch() == other.getMinimumNumberShouldMatch() && + disableCoord == other.disableCoord && + clauseSets.equals(other.clauseSets); } private int computeHashCode() { - int hashCode = 31 * super.hashCode() + Objects.hash(disableCoord, minimumNumberShouldMatch, clauseSets); + int hashCode = Objects.hash(disableCoord, minimumNumberShouldMatch, clauseSets); if (hashCode == 0) { hashCode = 1; } @@ -443,8 +444,8 @@ public class BooleanQuery extends Query implements Iterable { @Override public int hashCode() { + // no need for synchronization, in the worst case we would just compute the hash several times. if (hashCode == 0) { - // no need for synchronization, in the worst case we would just compute the hash several times hashCode = computeHashCode(); assert hashCode != 0; } diff --git a/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java b/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java index c7d0aea4079..eb7f4b97ec9 100644 --- a/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java @@ -58,18 +58,19 @@ public final class BoostQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - BoostQuery that = (BoostQuery) obj; - return query.equals(that.query) - && Float.floatToIntBits(boost) == Float.floatToIntBits(that.boost); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(BoostQuery other) { + return query.equals(other.query) && + Float.floatToIntBits(boost) == Float.floatToIntBits(other.boost); } @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + query.hashCode(); h = 31 * h + Float.floatToIntBits(boost); return h; diff --git a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java index 4ca80e25947..eb5e2d34760 100644 --- a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -162,20 +162,13 @@ public final class ConstantScoreQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!super.equals(o)) - return false; - if (o instanceof ConstantScoreQuery) { - final ConstantScoreQuery other = (ConstantScoreQuery) o; - return this.query.equals(other.query); - } - return false; + public boolean equals(Object other) { + return sameClassAs(other) && + query.equals(((ConstantScoreQuery) other).query); } @Override public int hashCode() { - return 31 * super.hashCode() + query.hashCode(); + return 31 * classHash() + query.hashCode(); } - } diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java index 9bcd05fa736..8b1c45d1d85 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java @@ -241,16 +241,18 @@ public final class DisjunctionMaxQuery extends Query implements Iterable } /** Return true iff we represent the same query as o - * @param o another object + * @param other another object * @return true iff o is a DisjunctionMaxQuery with the same boost and the same subqueries, in the same order, as us */ @Override - public boolean equals(Object o) { - if (! (o instanceof DisjunctionMaxQuery) ) return false; - DisjunctionMaxQuery other = (DisjunctionMaxQuery)o; - return super.equals(o) - && this.tieBreakerMultiplier == other.tieBreakerMultiplier - && Arrays.equals(disjuncts, other.disjuncts); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(DisjunctionMaxQuery other) { + return tieBreakerMultiplier == other.tieBreakerMultiplier && + Arrays.equals(disjuncts, other.disjuncts); } /** Compute a hash code for hashing us @@ -258,7 +260,7 @@ public final class DisjunctionMaxQuery extends Query implements Iterable */ @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + Float.floatToIntBits(tieBreakerMultiplier); h = 31 * h + Arrays.hashCode(disjuncts); return h; diff --git a/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java b/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java index 0c544e3120d..261e8e5497d 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java +++ b/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java @@ -59,17 +59,14 @@ public final class DocValuesRewriteMethod extends MultiTermQuery.RewriteMethod { } @Override - public final boolean equals(final Object o) { - if (super.equals(o) == false) { - return false; - } - MultiTermQueryDocValuesWrapper that = (MultiTermQueryDocValuesWrapper) o; - return query.equals(that.query); + public final boolean equals(final Object other) { + return sameClassAs(other) && + query.equals(((MultiTermQueryDocValuesWrapper) other).query); } - + @Override public final int hashCode() { - return 31 * super.hashCode() + query.hashCode(); + return 31 * classHash() + query.hashCode(); } /** Returns the field name for this query */ @@ -169,14 +166,9 @@ public final class DocValuesRewriteMethod extends MultiTermQuery.RewriteMethod { } @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - return true; + public boolean equals(Object other) { + return other != null && + getClass() == other.getClass(); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java b/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java index 4bc081c460e..ed3c5e7f1ac 100644 --- a/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/FieldValueQuery.java @@ -43,17 +43,14 @@ public final class FieldValueQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - final FieldValueQuery that = (FieldValueQuery) obj; - return field.equals(that.field); + public boolean equals(Object other) { + return sameClassAs(other) && + field.equals(((FieldValueQuery) other).field); } @Override public int hashCode() { - return 31 * super.hashCode() + field.hashCode(); + return 31 * classHash() + field.hashCode(); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java b/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java index 4f62f74af20..2566cf0743c 100644 --- a/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java @@ -71,4 +71,14 @@ public final class MatchAllDocsQuery extends Query { public String toString(String field) { return "*:*"; } + + @Override + public boolean equals(Object o) { + return sameClassAs(o); + } + + @Override + public int hashCode() { + return classHash(); + } } diff --git a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java index d0bc18c2fbc..77b7952d05e 100644 --- a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java @@ -22,18 +22,27 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; /** - * A query that matches no documents. + * A query that matches no documents. */ public class MatchNoDocsQuery extends Query { + @Override + public Query rewrite(IndexReader reader) throws IOException { + // Rewrite to an empty BooleanQuery so no Scorer or Weight is required + return new BooleanQuery.Builder().build(); + } - @Override - public Query rewrite(IndexReader reader) throws IOException { - // Rewrite to an empty BooleanQuery so no Scorer or Weight is required - return new BooleanQuery.Builder().build(); - } + @Override + public String toString(String field) { + return ""; + } - @Override - public String toString(String field) { - return ""; - } + @Override + public boolean equals(Object o) { + return sameClassAs(o); + } + + @Override + public int hashCode() { + return classHash(); + } } diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java index d703ebdba52..cf4f39c03fc 100644 --- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java @@ -383,20 +383,22 @@ public class MultiPhraseQuery extends Query { /** Returns true if o is equal to this. */ @Override - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - MultiPhraseQuery other = (MultiPhraseQuery)o; - return this.slop == other.slop - && termArraysEquals(this.termArrays, other.termArrays) // terms equal implies field equal - && Arrays.equals(this.positions, other.positions); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(MultiPhraseQuery other) { + return this.slop == other.slop && + termArraysEquals(this.termArrays, other.termArrays) && /* terms equal implies field equal */ + Arrays.equals(this.positions, other.positions); + } /** Returns a hash code value for this object.*/ @Override public int hashCode() { - return super.hashCode() + return classHash() ^ slop ^ termArraysHashCode() // terms equal implies field equal ^ Arrays.hashCode(positions); diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java index 6b5c65f14f8..ef2b01433db 100644 --- a/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/MultiTermQuery.java @@ -332,27 +332,20 @@ public abstract class MultiTermQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = 1; + int result = classHash(); result = prime * result + rewriteMethod.hashCode(); - if (field != null) result = prime * result + field.hashCode(); + result = prime * result + field.hashCode(); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - MultiTermQuery other = (MultiTermQuery) obj; - if (!super.equals(obj)) - return false; - if (!rewriteMethod.equals(other.rewriteMethod)) { - return false; - } - return (other.field == null ? field == null : other.field.equals(field)); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(MultiTermQuery other) { + return rewriteMethod.equals(other.rewriteMethod) && + field.equals(other.field); } - } diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java b/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java index eb7436f1247..66577570143 100644 --- a/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java +++ b/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java @@ -91,17 +91,14 @@ final class MultiTermQueryConstantScoreWrapper extends } @Override - public final boolean equals(final Object o) { - if (super.equals(o) == false) { - return false; - } - final MultiTermQueryConstantScoreWrapper that = (MultiTermQueryConstantScoreWrapper) o; - return this.query.equals(that.query); + public final boolean equals(final Object other) { + return sameClassAs(other) && + query.equals(((MultiTermQueryConstantScoreWrapper) other).query); } @Override public final int hashCode() { - return 31 * super.hashCode() + query.hashCode(); + return 31 * classHash() + query.hashCode(); } /** Returns the encapsulated query */ diff --git a/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java index e6f085c326a..db997d37e75 100644 --- a/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java @@ -78,17 +78,19 @@ public class NGramPhraseQuery extends Query { } @Override - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - NGramPhraseQuery other = (NGramPhraseQuery) o; - return n == other.n && phraseQuery.equals(other.phraseQuery); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(NGramPhraseQuery other) { + return n == other.n && + phraseQuery.equals(other.phraseQuery); } @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + phraseQuery.hashCode(); h = 31 * h + n; return h; diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java index 143ed176e12..459d6648abf 100644 --- a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java @@ -561,20 +561,21 @@ public class PhraseQuery extends Query { /** Returns true iff o is equal to this. */ @Override - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - PhraseQuery that = (PhraseQuery) o; - return slop == that.slop - && Arrays.equals(terms, that.terms) - && Arrays.equals(positions, that.positions); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(PhraseQuery other) { + return slop == other.slop && + Arrays.equals(terms, other.terms) && + Arrays.equals(positions, other.positions); } /** Returns a hash code value for this object.*/ @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + slop; h = 31 * h + Arrays.hashCode(terms); h = 31 * h + Arrays.hashCode(positions); diff --git a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java index 05490778797..c19e457c13d 100644 --- a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java @@ -305,7 +305,7 @@ public abstract class PointInSetQuery extends Query { @Override public final int hashCode() { - int hash = super.hashCode(); + int hash = classHash(); hash = 31 * hash + field.hashCode(); hash = 31 * hash + sortedPackedPointsHashCode; hash = 31 * hash + numDims; @@ -315,16 +315,16 @@ public abstract class PointInSetQuery extends Query { @Override public final boolean equals(Object other) { - if (super.equals(other)) { - final PointInSetQuery q = (PointInSetQuery) other; - return q.field.equals(field) && - q.numDims == numDims && - q.bytesPerDim == bytesPerDim && - q.sortedPackedPointsHashCode == sortedPackedPointsHashCode && - q.sortedPackedPoints.equals(sortedPackedPoints); - } - - return false; + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(PointInSetQuery other) { + return other.field.equals(field) && + other.numDims == numDims && + other.bytesPerDim == bytesPerDim && + other.sortedPackedPointsHashCode == sortedPackedPointsHashCode && + other.sortedPackedPoints.equals(sortedPackedPoints); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java index abd4cbc20da..fb7051d2cab 100644 --- a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java @@ -220,7 +220,7 @@ public abstract class PointRangeQuery extends Query { @Override public final int hashCode() { - int hash = super.hashCode(); + int hash = classHash(); hash = 31 * hash + field.hashCode(); hash = 31 * hash + Arrays.hashCode(lowerPoint); hash = 31 * hash + Arrays.hashCode(upperPoint); @@ -230,33 +230,17 @@ public abstract class PointRangeQuery extends Query { } @Override - public final boolean equals(Object other) { - if (super.equals(other) == false) { - return false; - } + public final boolean equals(Object o) { + return sameClassAs(o) && + equalsTo(getClass().cast(o)); + } - final PointRangeQuery q = (PointRangeQuery) other; - if (field.equals(q.field) == false) { - return false; - } - - if (q.numDims != numDims) { - return false; - } - - if (q.bytesPerDim != bytesPerDim) { - return false; - } - - if (Arrays.equals(lowerPoint, q.lowerPoint) == false) { - return false; - } - - if (Arrays.equals(upperPoint, q.upperPoint) == false) { - return false; - } - - return true; + private boolean equalsTo(PointRangeQuery other) { + return Objects.equals(field, other.field) && + numDims == other.numDims && + bytesPerDim == other.bytesPerDim && + Arrays.equals(lowerPoint, other.lowerPoint) && + Arrays.equals(upperPoint, other.upperPoint); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/search/Query.java b/lucene/core/src/java/org/apache/lucene/search/Query.java index 49134ec38af..8cab2d173f9 100644 --- a/lucene/core/src/java/org/apache/lucene/search/Query.java +++ b/lucene/core/src/java/org/apache/lucene/search/Query.java @@ -74,15 +74,50 @@ public abstract class Query { return this; } + /** + * Override and implement query instance equivalence properly in a subclass. + * This is required so that {@link QueryCache} works properly. + * + * Typically a query will be equal to another only if it's an instance of + * the same class and its document-filtering properties are identical that other + * instance. Utility methods are provided for certain repetitive code. + * + * @see #sameClassAs(Object) + * @see #classHash() + */ @Override - public int hashCode() { - return getClass().hashCode(); + public abstract boolean equals(Object obj); + + /** + * Override and implement query hash code properly in a subclass. + * This is required so that {@link QueryCache} works properly. + * + * @see #equals(Object) + */ + @Override + public abstract int hashCode(); + + /** + * Utility method to check whether other is not null and is exactly + * of the same class as this object's class. + * + * When this method is used in an implementation of {@link #equals(Object)}, + * consider using {@link #classHash()} in the implementation + * of {@link #hashCode} to differentiate different class + */ + protected final boolean sameClassAs(Object other) { + return other != null && getClass() == other.getClass(); } - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - return getClass() == obj.getClass(); + private final int CLASS_NAME_HASH = getClass().getName().hashCode(); + + /** + * Provides a constant integer for a given class, derived from the name of the class. + * The rationale for not using just {@link Class#hashCode()} is that classes may be + * assigned different hash codes for each execution and we want hashes to be possibly + * consistent to facilitate debugging. + */ + protected final int classHash() { + return CLASS_NAME_HASH; } } diff --git a/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java b/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java index 4a0ca56b62b..4d49cd91346 100644 --- a/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java @@ -88,20 +88,13 @@ public final class SynonymQuery extends Query { @Override public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + Arrays.hashCode(terms); - return result; + return 31 * classHash() + Arrays.hashCode(terms); } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - SynonymQuery other = (SynonymQuery) obj; - if (!Arrays.equals(terms, other.terms)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + Arrays.equals(terms, ((SynonymQuery) other).terms); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java index b7b6d290722..e815ff61a8a 100644 --- a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java @@ -211,14 +211,13 @@ public class TermQuery extends Query { /** Returns true iff o is equal to this. */ @Override - public boolean equals(Object o) { - if (!(o instanceof TermQuery)) return false; - TermQuery other = (TermQuery) o; - return super.equals(o) && this.term.equals(other.term); + public boolean equals(Object other) { + return sameClassAs(other) && + term.equals(((TermQuery) other).term); } @Override public int hashCode() { - return super.hashCode() ^ term.hashCode(); + return classHash() ^ term.hashCode(); } } diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java index 8a2dae3afd1..5c5e4dca9db 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java @@ -95,8 +95,6 @@ public final class FieldMaskingSpanQuery extends SpanQuery { @Override public Query rewrite(IndexReader reader) throws IOException { - FieldMaskingSpanQuery clone = null; - SpanQuery rewritten = (SpanQuery) maskedQuery.rewrite(reader); if (rewritten != maskedQuery) { return new FieldMaskingSpanQuery(rewritten, field); @@ -117,20 +115,20 @@ public final class FieldMaskingSpanQuery extends SpanQuery { } @Override - public boolean equals(Object o) { - if (! super.equals(o)) { - return false; - } - FieldMaskingSpanQuery other = (FieldMaskingSpanQuery) o; - return (this.getField().equals(other.getField()) - && this.getMaskedQuery().equals(other.getMaskedQuery())); - + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); } + private boolean equalsTo(FieldMaskingSpanQuery other) { + return getField().equals(other.getField()) && + getMaskedQuery().equals(other.getMaskedQuery()); + } + @Override public int hashCode() { - return super.hashCode() - ^ getMaskedQuery().hashCode() - ^ getField().hashCode(); + return classHash() ^ + getMaskedQuery().hashCode() ^ + getField().hashCode(); } } diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java index 911fdc09642..9ecd743def1 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java @@ -31,7 +31,6 @@ import org.apache.lucene.search.BoostQuery; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; -import org.apache.lucene.search.Scorer; /** * Counterpart of {@link BoostQuery} for spans. @@ -63,18 +62,19 @@ public final class SpanBoostQuery extends SpanQuery { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - SpanBoostQuery that = (SpanBoostQuery) obj; - return query.equals(that.query) - && Float.floatToIntBits(boost) == Float.floatToIntBits(that.boost); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(SpanBoostQuery other) { + return query.equals(other.query) && + Float.floatToIntBits(boost) == Float.floatToIntBits(other.boost); } @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + query.hashCode(); h = 31 * h + Float.floatToIntBits(boost); return h; diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java index 551138d32c8..b122a09e64a 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java @@ -129,17 +129,19 @@ abstract class SpanContainQuery extends SpanQuery implements Cloneable { } @Override - public boolean equals(Object o) { - if (! super.equals(o)) { - return false; - } - SpanContainQuery other = (SpanContainQuery)o; - return big.equals(other.big) && little.equals(other.little); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(SpanContainQuery other) { + return big.equals(other.big) && + little.equals(other.little); } @Override public int hashCode() { - int h = Integer.rotateLeft(super.hashCode(), 1); + int h = Integer.rotateLeft(classHash(), 1); h ^= big.hashCode(); h = Integer.rotateLeft(h, 1); h ^= little.hashCode(); diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java index 95b7e93fca2..f4c6f24f9df 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java @@ -123,19 +123,13 @@ public class SpanMultiTermQueryWrapper extends SpanQue @Override public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + query.hashCode(); - return result; + return classHash() * 31 + query.hashCode(); } @Override - public boolean equals(Object obj) { - if (! super.equals(obj)) { - return false; - } - SpanMultiTermQueryWrapper other = (SpanMultiTermQueryWrapper) obj; - return query.equals(other.query); + public boolean equals(Object other) { + return sameClassAs(other) && + query.equals(((SpanMultiTermQueryWrapper) other).query); } /** Abstract class that defines how the query is rewritten. */ diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java index d542227b37f..217d75f163f 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java @@ -253,22 +253,21 @@ public class SpanNearQuery extends SpanQuery implements Cloneable { return super.rewrite(reader); } - /** Returns true iff o is equal to this. */ @Override - public boolean equals(Object o) { - if (! super.equals(o)) { - return false; - } - final SpanNearQuery spanNearQuery = (SpanNearQuery) o; - - return (inOrder == spanNearQuery.inOrder) - && (slop == spanNearQuery.slop) - && clauses.equals(spanNearQuery.clauses); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(SpanNearQuery other) { + return inOrder == other.inOrder && + slop == other.slop && + clauses.equals(other.clauses); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result ^= clauses.hashCode(); result += slop; int fac = 1 + (inOrder ? 8 : 4); @@ -321,6 +320,25 @@ public class SpanNearQuery extends SpanQuery implements Cloneable { } } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(SpanGapQuery other) { + return width == other.width && + field.equals(other.field); + } + + @Override + public int hashCode() { + int result = classHash(); + result -= 7 * width; + return result * 15 - field.hashCode(); + } + } static class GapSpans extends Spans { diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java index 5b2aeaca5de..9b07abf9258 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java @@ -200,20 +200,21 @@ public final class SpanNotQuery extends SpanQuery { } /** Returns true iff o is equal to this. */ @Override - public boolean equals(Object o) { - if (!super.equals(o)) - return false; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } - SpanNotQuery other = (SpanNotQuery)o; - return this.include.equals(other.include) - && this.exclude.equals(other.exclude) - && this.pre == other.pre - && this.post == other.post; + private boolean equalsTo(SpanNotQuery other) { + return include.equals(other.include) && + exclude.equals(other.exclude) && + pre == other.pre && + post == other.post; } @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = Integer.rotateLeft(h, 1); h ^= include.hashCode(); h = Integer.rotateLeft(h, 1); diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java index c07ec38e7a4..37e58631613 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java @@ -103,19 +103,14 @@ public final class SpanOrQuery extends SpanQuery { } @Override - public boolean equals(Object o) { - if (! super.equals(o)) { - return false; - } - final SpanOrQuery that = (SpanOrQuery) o; - return clauses.equals(that.clauses); + public boolean equals(Object other) { + return sameClassAs(other) && + clauses.equals(((SpanOrQuery) other).clauses); } @Override public int hashCode() { - int h = super.hashCode(); - h = (h * 7) ^ clauses.hashCode(); - return h; + return classHash() ^ clauses.hashCode(); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java index b2166e4176e..21c3a0334f3 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java @@ -120,18 +120,15 @@ public abstract class SpanPositionCheckQuery extends SpanQuery implements Clonea return super.rewrite(reader); } - /** Returns true iff o is equal to this. */ + /** Returns true iff other is equal to this. */ @Override - public boolean equals(Object o) { - if (! super.equals(o)) { - return false; - } - SpanPositionCheckQuery spcq = (SpanPositionCheckQuery) o; - return match.equals(spcq.match); + public boolean equals(Object other) { + return sameClassAs(other) && + match.equals(((SpanPositionCheckQuery) other).match); } @Override public int hashCode() { - return match.hashCode() ^ super.hashCode(); + return classHash() ^ match.hashCode(); } } diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java index bf6c6d0ec5a..43e0dccd4de 100644 --- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java +++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java @@ -163,19 +163,13 @@ public class SpanTermQuery extends SpanQuery { @Override public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + term.hashCode(); - return result; + return classHash() ^ term.hashCode(); } @Override - public boolean equals(Object obj) { - if (! super.equals(obj)) { - return false; - } - SpanTermQuery other = (SpanTermQuery) obj; - return term.equals(other.term); + public boolean equals(Object other) { + return sameClassAs(other) && + term.equals(((SpanTermQuery) other).term); } } diff --git a/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java index ca586cfe49e..b46a46e4e52 100644 --- a/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -28,7 +28,7 @@ import org.apache.lucene.util.PriorityQueue; /** * Holds all implementations of classes in the o.a.l.search package as a - * back-compatibility test. It does not run any tests per-se, however if + * back-compatibility test. It does not run any tests per-se, however if * someone adds a method to an interface or abstract method to an abstract * class, one of the implementations here will fail to compile and so we know * back-compat policy was violated. @@ -59,7 +59,7 @@ final class JustCompileSearch { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } } - + static final class JustCompileDocIdSet extends DocIdSet { @Override @@ -84,18 +84,18 @@ final class JustCompileSearch { public int nextDoc() { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + @Override public int advance(int target) { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + @Override public long cost() { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } } - + static final class JustCompileFieldComparator extends FieldComparator { @Override @@ -126,7 +126,7 @@ final class JustCompileSearch { int sortPos, boolean reversed) { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + } static final class JustCompileFilteredDocIdSetIterator extends FilteredDocIdSetIterator { @@ -139,7 +139,7 @@ final class JustCompileSearch { protected boolean match(int doc) { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + @Override public long cost() { throw new UnsupportedOperationException(UNSUPPORTED_MSG); @@ -152,9 +152,18 @@ final class JustCompileSearch { public String toString(String field) { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + + @Override + public boolean equals(Object obj) { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } } - + static final class JustCompileScorer extends Scorer { protected JustCompileScorer(Weight weight) { @@ -165,7 +174,7 @@ final class JustCompileSearch { public float score() { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + @Override public int freq() { throw new UnsupportedOperationException(UNSUPPORTED_MSG); @@ -181,7 +190,7 @@ final class JustCompileSearch { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } } - + static final class JustCompileSimilarity extends Similarity { @Override @@ -264,5 +273,5 @@ final class JustCompileSearch { } } - + } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java index df1be3e7cf8..90c86c82525 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java @@ -39,7 +39,7 @@ import org.apache.lucene.util.TestUtil; public class TestBooleanScorer extends LuceneTestCase { private static final String FIELD = "category"; - + public void testMethod() throws Exception { Directory directory = newDirectory(); @@ -122,6 +122,16 @@ public class TestBooleanScorer extends LuceneTestCase { } }; } + + @Override + public boolean equals(Object obj) { + return this == obj; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } } /** Make sure BooleanScorer can embed another diff --git a/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java index 22532947898..0a49259019c 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java @@ -148,17 +148,14 @@ public class TestConstantScoreQuery extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - QueryWrapper that = (QueryWrapper) obj; - return in.equals(that.in); + public boolean equals(Object other) { + return sameClassAs(other) && + in.equals(((QueryWrapper) other).in); } @Override public int hashCode() { - return 31 * super.hashCode() + in.hashCode(); + return 31 * classHash() + in.hashCode(); } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java b/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java index 63ccdd879a3..48dcdf0e1b8 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java @@ -357,11 +357,9 @@ public class TestLRUQueryCache extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (obj instanceof DummyQuery == false) { - return false; - } - return id == ((DummyQuery) obj).id; + public boolean equals(Object other) { + return sameClassAs(other) && + id == ((DummyQuery) other).id; } @Override @@ -950,9 +948,14 @@ public class TestLRUQueryCache extends LuceneTestCase { @Override public int hashCode() { - return super.hashCode() ^ i[0]; + return classHash() ^ i[0]; } + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + i[0] == ((BadQuery) other).i[0]; + } } public void testDetectMutatedQueries() throws IOException { diff --git a/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java b/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java index fa637593369..2723ce8f4e8 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java @@ -19,6 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; import java.util.Set; +import java.util.Objects; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; @@ -95,7 +96,7 @@ public class TestNeedsScores extends LuceneTestCase { final boolean value; AssertNeedsScores(Query in, boolean value) { - this.in = in; + this.in = Objects.requireNonNull(in); this.value = value; } @@ -144,23 +145,21 @@ public class TestNeedsScores extends LuceneTestCase { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((in == null) ? 0 : in.hashCode()); + int result = classHash(); + result = prime * result + in.hashCode(); result = prime * result + (value ? 1231 : 1237); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - AssertNeedsScores other = (AssertNeedsScores) obj; - if (in == null) { - if (other.in != null) return false; - } else if (!in.equals(other.in)) return false; - if (value != other.value) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(AssertNeedsScores other) { + return in.equals(other.in) && + value == other.value; } @Override diff --git a/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java b/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java index d029e017f6e..c0428f4bd57 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java @@ -503,30 +503,27 @@ public class TestQueryRescorer extends LuceneTestCase { } @Override - public boolean equals(Object o) { - if ((o instanceof FixedScoreQuery) == false) { - return false; - } - FixedScoreQuery other = (FixedScoreQuery) o; - return super.equals(o) && - reverse == other.reverse && - Arrays.equals(idToNum, other.idToNum); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(FixedScoreQuery other) { + return reverse == other.reverse && + Arrays.equals(idToNum, other.idToNum); + } + + @Override + public int hashCode() { + int hash = classHash(); + hash = 31 * hash + (reverse ? 0 : 1); + hash = 31 * hash + Arrays.hashCode(idToNum); + return hash; } @Override public Query clone() { return new FixedScoreQuery(idToNum, reverse); } - - @Override - public int hashCode() { - int PRIME = 31; - int hash = super.hashCode(); - if (reverse) { - hash = PRIME * hash + 3623; - } - hash = PRIME * hash + Arrays.hashCode(idToNum); - return hash; - } } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java b/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java index 82d5e1850b7..4b1a4d2bf42 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java @@ -165,16 +165,14 @@ public class TestScorerPerf extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - return docs == ((BitSetQuery) obj).docs; + public boolean equals(Object other) { + return sameClassAs(other) && + docs.equals(((BitSetQuery) other).docs); } @Override public int hashCode() { - return 31 * super.hashCode() + System.identityHashCode(docs); + return 31 * classHash() + docs.hashCode(); } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java b/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java index c362fd6e1c4..32bce9e6751 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java @@ -257,19 +257,21 @@ public class TestSortRandom extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - RandomQuery other = (RandomQuery) obj; - return seed == other.seed && docValues == other.docValues; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(RandomQuery other) { + return seed == other.seed && + docValues == other.docValues; } @Override public int hashCode() { int h = Objects.hash(seed, density); h = 31 * h + System.identityHashCode(docValues); - h = 31 * h + super.hashCode(); + h = 31 * h + classHash(); return h; } } diff --git a/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java b/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java index f844795d983..6e6102f8561 100644 --- a/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java +++ b/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java @@ -48,7 +48,7 @@ final class JustCompileSearchSpans { public int advance(int target) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + @Override public int startPosition() { throw new UnsupportedOperationException(UNSUPPORTED_MSG); @@ -101,7 +101,17 @@ final class JustCompileSearchSpans { public String toString(String field) { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } - + + @Override + public boolean equals(Object o) { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } + } } diff --git a/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java b/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java index 91d5b0f80ff..bb52ede43f0 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java @@ -122,19 +122,20 @@ public final class DrillDownQuery extends Query { @Override public int hashCode() { - return 31 * super.hashCode() + Objects.hash(baseQuery, dimQueries); + return classHash() + Objects.hash(baseQuery, dimQueries); } - + @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - DrillDownQuery other = (DrillDownQuery) obj; - return Objects.equals(baseQuery, other.baseQuery) - && dimQueries.equals(other.dimQueries); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); } - + + private boolean equalsTo(DrillDownQuery other) { + return Objects.equals(baseQuery, other.baseQuery) && + dimQueries.equals(other.dimQueries); + } + @Override public Query rewrite(IndexReader r) throws IOException { BooleanQuery rewritten = getBooleanQuery(); diff --git a/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java b/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java index b3ffb0d39a5..48883eaa4e5 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java @@ -161,29 +161,24 @@ class DrillSidewaysQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((baseQuery == null) ? 0 : baseQuery.hashCode()); - result = prime * result - + ((drillDownCollector == null) ? 0 : drillDownCollector.hashCode()); + int result = classHash(); + result = prime * result + Objects.hashCode(baseQuery); + result = prime * result + Objects.hashCode(drillDownCollector); result = prime * result + Arrays.hashCode(drillDownQueries); result = prime * result + Arrays.hashCode(drillSidewaysCollectors); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - DrillSidewaysQuery other = (DrillSidewaysQuery) obj; - if (baseQuery == null) { - if (other.baseQuery != null) return false; - } else if (!baseQuery.equals(other.baseQuery)) return false; - if (drillDownCollector == null) { - if (other.drillDownCollector != null) return false; - } else if (!drillDownCollector.equals(other.drillDownCollector)) return false; - if (!Arrays.equals(drillDownQueries, other.drillDownQueries)) return false; - if (!Arrays.equals(drillSidewaysCollectors, other.drillSidewaysCollectors)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(DrillSidewaysQuery other) { + return Objects.equals(baseQuery, other.baseQuery) && + Objects.equals(drillDownCollector, other.drillDownCollector) && + Arrays.equals(drillDownQueries, other.drillDownQueries) && + Arrays.equals(drillSidewaysCollectors, other.drillSidewaysCollectors); } } diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java b/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java index 6f005ed4a1a..8893c659ebf 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java @@ -104,19 +104,20 @@ public final class DoubleRange extends Range { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - ValueSourceQuery other = (ValueSourceQuery) obj; - return range.equals(other.range) - && Objects.equals(fastMatchQuery, other.fastMatchQuery) - && valueSource.equals(other.valueSource); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(ValueSourceQuery other) { + return range.equals(other.range) && + Objects.equals(fastMatchQuery, other.fastMatchQuery) && + valueSource.equals(other.valueSource); } @Override public int hashCode() { - return 31 * Objects.hash(range, fastMatchQuery, valueSource) + super.hashCode(); + return classHash() + 31 * Objects.hash(range, fastMatchQuery, valueSource); } @Override diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java b/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java index ef789c58cb4..46ee00b3448 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java @@ -96,19 +96,20 @@ public final class LongRange extends Range { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - ValueSourceQuery other = (ValueSourceQuery) obj; - return range.equals(other.range) - && Objects.equals(fastMatchQuery, other.fastMatchQuery) - && valueSource.equals(other.valueSource); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(ValueSourceQuery other) { + return range.equals(other.range) && + Objects.equals(fastMatchQuery, other.fastMatchQuery) && + valueSource.equals(other.valueSource); } @Override public int hashCode() { - return 31 * Objects.hash(range, fastMatchQuery, valueSource) + super.hashCode(); + return classHash() + 31 * Objects.hash(range, fastMatchQuery, valueSource); } @Override diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java index e37215ec3d3..97247e09c3e 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java @@ -117,7 +117,7 @@ public class TestDrillSideways extends FacetTestCase { // case: drill-down on a single field; in this // case the drill-sideways + drill-down counts == - // drill-down of just the query: + // drill-down of just the query: DrillDownQuery ddq = new DrillDownQuery(config); ddq.add("Author", "Lisa"); DrillSidewaysResult r = ds.search(null, ddq, 10); @@ -361,7 +361,7 @@ public class TestDrillSideways extends FacetTestCase { String contentToken; public Doc() {} - + // -1 if the doc is missing this dim, else the index // -into the values for this dim: int[] dims; @@ -437,7 +437,7 @@ public class TestDrillSideways extends FacetTestCase { if (s.length() > 0) { values.add(s); } - } + } dimValues[dim] = values.toArray(new String[values.size()]); valueCount *= 2; } @@ -560,7 +560,7 @@ public class TestDrillSideways extends FacetTestCase { final SortedSetDocValuesReaderState sortedSetDVState; IndexSearcher s = newSearcher(r); - + if (doUseDV) { sortedSetDVState = new DefaultSortedSetDocValuesReaderState(s.getIndexReader()); } else { @@ -669,7 +669,7 @@ public class TestDrillSideways extends FacetTestCase { public int length() { return context.reader().maxDoc(); } - + }; } }; @@ -680,6 +680,15 @@ public class TestDrillSideways extends FacetTestCase { return "drillSidewaysTestFilter"; } + @Override + public boolean equals(Object o) { + return o == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } }; } else { filter = null; @@ -823,7 +832,7 @@ public class TestDrillSideways extends FacetTestCase { int[] uniqueCounts; public TestFacetResult() {} } - + private int[] getTopNOrds(final int[] counts, final String[] values, int topN) { final int[] ids = new int[counts.length]; for(int i=0;ivery", fragment); } - - public void testHighlightUnknowQueryAfterRewrite() throws IOException, InvalidTokenOffsetsException { + + public void testHighlightUnknownQueryAfterRewrite() throws IOException, InvalidTokenOffsetsException { Query query = new Query() { @Override @@ -242,12 +242,12 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte @Override public int hashCode() { - return 31 * super.hashCode(); + return System.identityHashCode(this); } @Override public boolean equals(Object obj) { - return super.equals(obj); + return obj == this; } }; diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java index bbb3bb9aa3d..a54687dbfbb 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java @@ -38,6 +38,7 @@ import org.apache.lucene.util.LuceneTestCase; import java.io.IOException; import java.util.Collections; import java.util.Map; +import java.util.Objects; /** * Tests the extensibility of {@link WeightedSpanTermExtractor} and @@ -161,7 +162,6 @@ public class HighlightCustomQueryTest extends LuceneTestCase { private final Term term; public CustomQuery(Term term) { - super(); this.term = term; } @@ -177,28 +177,13 @@ public class HighlightCustomQueryTest extends LuceneTestCase { @Override public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((term == null) ? 0 : term.hashCode()); - return result; + return classHash() + Objects.hashCode(term); } @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - CustomQuery other = (CustomQuery) obj; - if (term == null) { - if (other.term != null) - return false; - } else if (!term.equals(other.term)) - return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(term, ((CustomQuery) other).term); } - } } diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java index 70ed833491b..ce8254658f5 100644 --- a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java +++ b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java @@ -61,7 +61,7 @@ public class FieldQueryTest extends AbstractTestCase { Query booleanQuery = booleanQueryB.build(); booleanQuery = new BoostQuery(booleanQuery, boost); - + FieldQuery fq = new FieldQuery(booleanQuery, true, true ); Set flatQueries = new HashSet<>(); fq.flatten(booleanQuery, reader, flatQueries, 1f); @@ -235,14 +235,14 @@ public class FieldQueryTest extends AbstractTestCase { public void testGetFieldTermMap() throws Exception { Query query = tq( "a" ); FieldQuery fq = new FieldQuery( query, true, true ); - + QueryPhraseMap pqm = fq.getFieldTermMap( F, "a" ); assertNotNull( pqm ); assertTrue( pqm.isTerminal() ); - + pqm = fq.getFieldTermMap( F, "b" ); assertNull( pqm ); - + pqm = fq.getFieldTermMap( F1, "a" ); assertNull( pqm ); } @@ -296,10 +296,10 @@ public class FieldQueryTest extends AbstractTestCase { termSet = fq.getTermSet( "y" ); assertNull( termSet ); } - + public void testQueryPhraseMap1Term() throws Exception { Query query = tq( "a" ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query, true, true ); Map map = fq.rootMaps; @@ -311,7 +311,7 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm.subMap.get( "a" ) != null ); assertTrue( qpm.subMap.get( "a" ).terminal ); assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); - + // phraseHighlight = true, fieldMatch = false fq = new FieldQuery( query, true, false ); map = fq.rootMaps; @@ -323,7 +323,7 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm.subMap.get( "a" ) != null ); assertTrue( qpm.subMap.get( "a" ).terminal ); assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); - + // phraseHighlight = false, fieldMatch = true fq = new FieldQuery( query, false, true ); map = fq.rootMaps; @@ -335,7 +335,7 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm.subMap.get( "a" ) != null ); assertTrue( qpm.subMap.get( "a" ).terminal ); assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); - + // phraseHighlight = false, fieldMatch = false fq = new FieldQuery( query, false, false ); map = fq.rootMaps; @@ -347,7 +347,7 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm.subMap.get( "a" ) != null ); assertTrue( qpm.subMap.get( "a" ).terminal ); assertEquals( 1F, qpm.subMap.get( "a" ).boost, 0); - + // boost != 1 query = tq( 2, "a" ); fq = new FieldQuery( query, true, true ); @@ -355,10 +355,10 @@ public class FieldQueryTest extends AbstractTestCase { qpm = map.get( F ); assertEquals( 2F, qpm.subMap.get( "a" ).boost, 0); } - + public void testQueryPhraseMap1Phrase() throws Exception { Query query = pqF( "a", "b" ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query, true, true ); Map map = fq.rootMaps; @@ -375,7 +375,7 @@ public class FieldQueryTest extends AbstractTestCase { QueryPhraseMap qpm3 = qpm2.subMap.get( "b" ); assertTrue( qpm3.terminal ); assertEquals( 1F, qpm3.boost, 0); - + // phraseHighlight = true, fieldMatch = false fq = new FieldQuery( query, true, false ); map = fq.rootMaps; @@ -392,7 +392,7 @@ public class FieldQueryTest extends AbstractTestCase { qpm3 = qpm2.subMap.get( "b" ); assertTrue( qpm3.terminal ); assertEquals( 1F, qpm3.boost, 0); - + // phraseHighlight = false, fieldMatch = true fq = new FieldQuery( query, false, true ); map = fq.rootMaps; @@ -415,7 +415,7 @@ public class FieldQueryTest extends AbstractTestCase { qpm2 = qpm.subMap.get( "b" ); assertTrue( qpm2.terminal ); assertEquals( 1F, qpm2.boost, 0); - + // phraseHighlight = false, fieldMatch = false fq = new FieldQuery( query, false, false ); map = fq.rootMaps; @@ -452,10 +452,10 @@ public class FieldQueryTest extends AbstractTestCase { qpm2 = qpm.subMap.get( "b" ); assertEquals( 2F, qpm2.boost, 0); } - + public void testQueryPhraseMap1PhraseAnother() throws Exception { Query query = pqF( "search", "engines" ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query, true, true ); Map map = fq.rootMaps; @@ -473,12 +473,12 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm3.terminal ); assertEquals( 1F, qpm3.boost, 0); } - + public void testQueryPhraseMap2Phrases() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add( pqF( "a", "b" ), Occur.SHOULD ); query.add( pqF( 2, "c", "d" ), Occur.SHOULD ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query.build(), true, true ); Map map = fq.rootMaps; @@ -508,12 +508,12 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm3.terminal ); assertEquals( 2F, qpm3.boost, 0); } - + public void testQueryPhraseMap2PhrasesFields() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add( pq( F1, "a", "b" ), Occur.SHOULD ); query.add( pq( 2F, F2, "c", "d" ), Occur.SHOULD ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query.build(), true, true ); Map map = fq.rootMaps; @@ -545,7 +545,7 @@ public class FieldQueryTest extends AbstractTestCase { qpm3 = qpm2.subMap.get( "d" ); assertTrue( qpm3.terminal ); assertEquals( 2F, qpm3.boost, 0); - + // phraseHighlight = true, fieldMatch = false fq = new FieldQuery( query.build(), true, false ); map = fq.rootMaps; @@ -576,10 +576,10 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm3.terminal ); assertEquals( 2F, qpm3.boost, 0); } - + /* * ...terminal - * + * * a-b-c- * +-d- * b-c-d- @@ -590,7 +590,7 @@ public class FieldQueryTest extends AbstractTestCase { query.add( pqF( "a", "b", "c" ), Occur.SHOULD ); query.add( pqF( 2, "b", "c", "d" ), Occur.SHOULD ); query.add( pqF( 3, "b", "d" ), Occur.SHOULD ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query.build(), true, true ); Map map = fq.rootMaps; @@ -636,10 +636,10 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm3.terminal ); assertEquals( 3F, qpm3.boost, 0); } - + /* * ...terminal - * + * * a-b- * +-c- */ @@ -647,7 +647,7 @@ public class FieldQueryTest extends AbstractTestCase { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add( pqF( "a", "b" ), Occur.SHOULD ); query.add( pqF( 2, "a", "b", "c" ), Occur.SHOULD ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query.build(), true, true ); Map map = fq.rootMaps; @@ -674,10 +674,10 @@ public class FieldQueryTest extends AbstractTestCase { assertTrue( qpm4.terminal ); assertEquals( 2F, qpm4.boost, 0); } - + /* * ...terminal - * + * * a-a-a- * +-a- * +-a- @@ -687,7 +687,7 @@ public class FieldQueryTest extends AbstractTestCase { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add( pqF( "a", "a", "a", "a" ), Occur.SHOULD ); query.add( pqF( 2, "a", "a", "a" ), Occur.SHOULD ); - + // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query.build(), true, true ); Map map = fq.rootMaps; @@ -728,7 +728,7 @@ public class FieldQueryTest extends AbstractTestCase { QueryPhraseMap qpm7 = qpm6.subMap.get( "a" ); assertTrue( qpm7.terminal ); } - + public void testQueryPhraseMapOverlap2gram() throws Exception { BooleanQuery.Builder query = new BooleanQuery.Builder(); query.add(toPhraseQuery(analyze("abc", F, analyzerB), F), Occur.MUST); @@ -769,7 +769,7 @@ public class FieldQueryTest extends AbstractTestCase { qpm3 = qpm2.subMap.get( "cd" ); assertTrue( qpm3.terminal ); assertEquals( 1F, qpm3.boost, 0); - + // phraseHighlight = false, fieldMatch = true fq = new FieldQuery( query.build(), false, true ); map = fq.rootMaps; @@ -815,13 +815,13 @@ public class FieldQueryTest extends AbstractTestCase { assertEquals( 1F, qpm2.boost, 0); assertEquals( 0, qpm2.subMap.size() ); } - + public void testSearchPhrase() throws Exception { Query query = pqF( "a", "b", "c" ); // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query, true, true ); - + // "a" List phraseCandidate = new ArrayList<>(); phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); @@ -836,14 +836,14 @@ public class FieldQueryTest extends AbstractTestCase { // phraseHighlight = true, fieldMatch = false fq = new FieldQuery( query, true, false ); - + // "a b c" assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); assertNotNull( fq.searchPhrase( "x", phraseCandidate ) ); // phraseHighlight = false, fieldMatch = true fq = new FieldQuery( query, false, true ); - + // "a" phraseCandidate.clear(); phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); @@ -856,14 +856,14 @@ public class FieldQueryTest extends AbstractTestCase { assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); assertNull( fq.searchPhrase( "x", phraseCandidate ) ); } - + public void testSearchPhraseSlop() throws Exception { // "a b c"~0 Query query = pqF( "a", "b", "c" ); // phraseHighlight = true, fieldMatch = true FieldQuery fq = new FieldQuery( query, true, true ); - + // "a b c" w/ position-gap = 2 List phraseCandidate = new ArrayList<>(); phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); @@ -876,10 +876,10 @@ public class FieldQueryTest extends AbstractTestCase { // phraseHighlight = true, fieldMatch = true fq = new FieldQuery( query, true, true ); - + // "a b c" w/ position-gap = 2 assertNotNull( fq.searchPhrase( F, phraseCandidate ) ); - + // "a b c" w/ position-gap = 3 phraseCandidate.clear(); phraseCandidate.add( new TermInfo( "a", 0, 1, 0, 1 ) ); @@ -887,7 +887,7 @@ public class FieldQueryTest extends AbstractTestCase { phraseCandidate.add( new TermInfo( "c", 4, 5, 6, 1 ) ); assertNull( fq.searchPhrase( F, phraseCandidate ) ); } - + public void testHighlightQuery() throws Exception { makeIndexStrMV(); defgMultiTermQueryTest(new WildcardQuery(new Term(F, "d*g"))); @@ -897,7 +897,7 @@ public class FieldQueryTest extends AbstractTestCase { makeIndexStrMV(); defgMultiTermQueryTest(new PrefixQuery(new Term(F, "de"))); } - + public void testRegexpQuery() throws Exception { makeIndexStrMV(); Term term = new Term(F, "d[a-z].g"); @@ -918,7 +918,7 @@ public class FieldQueryTest extends AbstractTestCase { phraseCandidate.add( new TermInfo( "defg", 0, 12, 0, 1 ) ); assertNotNull (fq.searchPhrase(F, phraseCandidate)); } - + public void testStopRewrite() throws Exception { Query q = new Query() { @@ -926,13 +926,21 @@ public class FieldQueryTest extends AbstractTestCase { public String toString(String field) { return "DummyQuery"; } - + @Override + public boolean equals(Object o) { + throw new AssertionError(); + } + + @Override + public int hashCode() { + throw new AssertionError(); + } }; make1d1fIndex( "a" ); assertNotNull(reader); new FieldQuery(q, reader, true, true ); } - + public void testFlattenConstantScoreQuery() throws Exception { initBoost(); Query query = new ConstantScoreQuery(pqF( "A" )); @@ -942,5 +950,5 @@ public class FieldQueryTest extends AbstractTestCase { fq.flatten( query, reader, flatQueries, 1f ); assertCollectionQueries( flatQueries, tq( boost, "A" ) ); } - + } diff --git a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java index f9b74d46932..6c380b4cfde 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java @@ -65,24 +65,21 @@ final class GlobalOrdinalsQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } - GlobalOrdinalsQuery that = (GlobalOrdinalsQuery) o; - - if (!fromQuery.equals(that.fromQuery)) return false; - if (!joinField.equals(that.joinField)) return false; - if (!toQuery.equals(that.toQuery)) return false; - if (!indexReader.equals(that.indexReader)) return false; - - return true; + private boolean equalsTo(GlobalOrdinalsQuery other) { + return fromQuery.equals(other.fromQuery) && + joinField.equals(other.joinField) && + toQuery.equals(other.toQuery) && + indexReader.equals(other.indexReader); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result = 31 * result + joinField.hashCode(); result = 31 * result + toQuery.hashCode(); result = 31 * result + fromQuery.hashCode(); diff --git a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java index f9b2064c65f..289f8335e5f 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java @@ -66,26 +66,23 @@ final class GlobalOrdinalsWithScoreQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - GlobalOrdinalsWithScoreQuery that = (GlobalOrdinalsWithScoreQuery) o; - - if (min != that.min) return false; - if (max != that.max) return false; - if (!joinField.equals(that.joinField)) return false; - if (!fromQuery.equals(that.fromQuery)) return false; - if (!toQuery.equals(that.toQuery)) return false; - if (!indexReader.equals(that.indexReader)) return false; - - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(GlobalOrdinalsWithScoreQuery other) { + return min == other.min && + max == other.max && + joinField.equals(other.joinField) && + fromQuery.equals(other.fromQuery) && + toQuery.equals(other.toQuery) && + indexReader.equals(other.indexReader); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result = 31 * result + joinField.hashCode(); result = 31 * result + toQuery.hashCode(); result = 31 * result + fromQuery.hashCode(); diff --git a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java index df6aa98b63e..d83bc8f5862 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java @@ -6,7 +6,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.function.BiFunction; -import java.util.function.Function; import org.apache.lucene.document.DoublePoint; import org.apache.lucene.document.FloatPoint; @@ -21,7 +20,6 @@ import org.apache.lucene.index.PointValues.Relation; import org.apache.lucene.index.PrefixCodedTerms; import org.apache.lucene.index.PrefixCodedTerms.TermIterator; import org.apache.lucene.index.Term; -import org.apache.lucene.search.ConstantScoreScorer; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.IndexSearcher; @@ -32,7 +30,6 @@ import org.apache.lucene.search.Weight; import org.apache.lucene.util.BitSetIterator; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; -import org.apache.lucene.util.DocIdSetBuilder; import org.apache.lucene.util.FixedBitSet; /* @@ -289,7 +286,7 @@ abstract class PointInSetIncludingScoreQuery extends Query { @Override public final int hashCode() { - int hash = super.hashCode(); + int hash = classHash(); hash = 31 * hash + field.hashCode(); hash = 31 * hash + originalQuery.hashCode(); hash = 31 * hash + sortedPackedPointsHashCode; @@ -299,16 +296,16 @@ abstract class PointInSetIncludingScoreQuery extends Query { @Override public final boolean equals(Object other) { - if (super.equals(other)) { - final PointInSetIncludingScoreQuery q = (PointInSetIncludingScoreQuery) other; - return q.field.equals(field) && - q.originalQuery.equals(originalQuery) && - q.bytesPerDim == bytesPerDim && - q.sortedPackedPointsHashCode == sortedPackedPointsHashCode && - q.sortedPackedPoints.equals(sortedPackedPoints); - } + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } - return false; + private boolean equalsTo(PointInSetIncludingScoreQuery other) { + return other.field.equals(field) && + other.originalQuery.equals(originalQuery) && + other.bytesPerDim == bytesPerDim && + other.sortedPackedPointsHashCode == sortedPackedPointsHashCode && + other.sortedPackedPoints.equals(sortedPackedPoints); } @Override diff --git a/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java index 65ab1f02775..94df35b1bad 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java @@ -86,29 +86,20 @@ class TermsIncludingScoreQuery extends Query { } @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } if (!super.equals(obj)) { - return false; - } if (getClass() != obj.getClass()) { - return false; - } - - TermsIncludingScoreQuery other = (TermsIncludingScoreQuery) obj; - if (!field.equals(other.field)) { - return false; - } - if (!unwrittenOriginalQuery.equals(other.unwrittenOriginalQuery)) { - return false; - } - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(TermsIncludingScoreQuery other) { + return field.equals(other.field) && + unwrittenOriginalQuery.equals(other.unwrittenOriginalQuery); } @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); + int result = classHash(); result += prime * field.hashCode(); result += prime * unwrittenOriginalQuery.hashCode(); return result; diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java index 237b78696d2..f3d487f7922 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java @@ -344,21 +344,20 @@ public class ToChildBlockJoinQuery extends Query { } @Override - public boolean equals(Object _other) { - if (_other instanceof ToChildBlockJoinQuery) { - final ToChildBlockJoinQuery other = (ToChildBlockJoinQuery) _other; - return origParentQuery.equals(other.origParentQuery) && - parentsFilter.equals(other.parentsFilter) && - super.equals(other); - } else { - return false; - } + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(ToChildBlockJoinQuery other) { + return origParentQuery.equals(other.origParentQuery) && + parentsFilter.equals(other.parentsFilter); } @Override public int hashCode() { final int prime = 31; - int hash = super.hashCode(); + int hash = classHash(); hash = prime * hash + origParentQuery.hashCode(); hash = prime * hash + parentsFilter.hashCode(); return hash; diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java index 2a0ebaf2ba7..c7bc72ff526 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java @@ -474,22 +474,21 @@ public class ToParentBlockJoinQuery extends Query { } @Override - public boolean equals(Object _other) { - if (_other instanceof ToParentBlockJoinQuery) { - final ToParentBlockJoinQuery other = (ToParentBlockJoinQuery) _other; - return origChildQuery.equals(other.origChildQuery) && - parentsFilter.equals(other.parentsFilter) && - scoreMode == other.scoreMode && - super.equals(other); - } else { - return false; - } + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(ToParentBlockJoinQuery other) { + return origChildQuery.equals(other.origChildQuery) && + parentsFilter.equals(other.parentsFilter) && + scoreMode == other.scoreMode; } @Override public int hashCode() { final int prime = 31; - int hash = super.hashCode(); + int hash = classHash(); hash = prime * hash + origChildQuery.hashCode(); hash = prime * hash + scoreMode.hashCode(); hash = prime * hash + parentsFilter.hashCode(); diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java index a67b0ec28bd..e11d207c44b 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java @@ -152,7 +152,7 @@ public class TestBlockJoin extends LuceneTestCase { docs.add(makeResume("Frank", "United States")); w.addDocuments(docs); w.commit(); - + IndexReader r = DirectoryReader.open(w); w.close(); IndexSearcher s = new IndexSearcher(r); @@ -184,7 +184,7 @@ public class TestBlockJoin extends LuceneTestCase { r.close(); dir.close(); } - + public void testSimple() throws Exception { @@ -203,7 +203,7 @@ public class TestBlockJoin extends LuceneTestCase { docs.add(makeJob("java", 2006)); docs.add(makeResume("Frank", "United States")); w.addDocuments(docs); - + IndexReader r = w.getReader(); w.close(); IndexSearcher s = newSearcher(r, false); @@ -232,7 +232,7 @@ public class TestBlockJoin extends LuceneTestCase { ToParentBlockJoinCollector c = new ToParentBlockJoinCollector(Sort.RELEVANCE, 1, true, true); s.search(fullQuery.build(), c); - + TopGroups results = c.getTopGroups(childJoinQuery, null, 0, 10, 0, true); assertFalse(Float.isNaN(results.maxScore)); @@ -259,7 +259,7 @@ public class TestBlockJoin extends LuceneTestCase { BooleanQuery.Builder fullChildQuery = new BooleanQuery.Builder(); fullChildQuery.add(new BooleanClause(parentJoinQuery, Occur.MUST)); fullChildQuery.add(new BooleanClause(childQuery.build(), Occur.MUST)); - + //System.out.println("FULL: " + fullChildQuery); TopDocs hits = s.search(fullChildQuery.build(), 10); assertEquals(1, hits.totalHits); @@ -272,7 +272,7 @@ public class TestBlockJoin extends LuceneTestCase { // Test with filter on child docs: fullChildQuery.add(new TermQuery(new Term("skill", "foosball")), Occur.FILTER); assertEquals(0, s.search(fullChildQuery.build(), 1).totalHits); - + r.close(); dir.close(); } @@ -296,7 +296,7 @@ public class TestBlockJoin extends LuceneTestCase { IndexSearcher s = newSearcher(r, false); // Hacky: this causes the query to need 2 rewrite - // iterations: + // iterations: BooleanQuery.Builder builder = new BooleanQuery.Builder(); builder.add(IntPoint.newExactQuery("year", 2007), BooleanClause.Occur.MUST); Query qc = new Query() { @@ -309,6 +309,16 @@ public class TestBlockJoin extends LuceneTestCase { public String toString(String field) { return "hack!"; } + + @Override + public boolean equals(Object o) { + return o == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } }; BitSetProducer parentsFilter = new QueryBitSetProducer(new TermQuery(new Term("docType", "resume"))); @@ -353,15 +363,15 @@ public class TestBlockJoin extends LuceneTestCase { docs2.add(makeJob("java", 2006)); Collections.shuffle(docs2, random()); docs2.add(makeResume("Frank", "United States")); - + addSkillless(w); boolean turn = random().nextBoolean(); w.addDocuments(turn ? docs:docs2); addSkillless(w); - + w.addDocuments(!turn ? docs:docs2); - + addSkillless(w); IndexReader r = w.getReader(); @@ -379,11 +389,11 @@ public class TestBlockJoin extends LuceneTestCase { // Define parent document criteria (find a resident in the UK) Query parentQuery = new TermQuery(new Term("country", "United Kingdom")); - + // Wrap the child document query to 'join' any matches // up to corresponding parent: ToParentBlockJoinQuery childJoinQuery = new ToParentBlockJoinQuery(childQuery.build(), parentsFilter, ScoreMode.Avg); - + assertEquals("no filter - both passed", 2, s.search(childJoinQuery, 10).totalHits); Query query = new BooleanQuery.Builder() @@ -396,14 +406,14 @@ public class TestBlockJoin extends LuceneTestCase { .add(new TermQuery(new Term("docType", "resume")), Occur.FILTER) .build(); assertEquals("dummy filter passes everyone ", 2, s.search(query, 10).totalHits); - + // not found test query = new BooleanQuery.Builder() .add(childJoinQuery, Occur.MUST) .add(new TermQuery(new Term("country", "Oz")), Occur.FILTER) .build(); assertEquals("noone live there", 0, s.search(query, 1).totalHits); - + // apply the UK filter by the searcher query = new BooleanQuery.Builder() .add(childJoinQuery, Occur.MUST) @@ -421,11 +431,11 @@ public class TestBlockJoin extends LuceneTestCase { TopDocs usThen = s.search(query, 1); assertEquals("has filter - single passed", 1, usThen.totalHits); assertEquals("Frank", r.document(usThen.scoreDocs[0].doc).get("name")); - - + + TermQuery us = new TermQuery(new Term("country", "United States")); - assertEquals("@ US we have java and ruby", 2, - s.search(new ToChildBlockJoinQuery(us, + assertEquals("@ US we have java and ruby", 2, + s.search(new ToChildBlockJoinQuery(us, parentsFilter), 10).totalHits ); query = new BooleanQuery.Builder() @@ -452,7 +462,7 @@ public class TestBlockJoin extends LuceneTestCase { w.addDocument(makeResume("Skillless", random().nextBoolean() ? "United Kingdom":"United States")); } } - + private Document getParentDoc(IndexReader reader, BitSetProducer parents, int childDocID) throws IOException { final List leaves = reader.leaves(); final int subIndex = ReaderUtil.subIndex(childDocID, leaves); @@ -460,14 +470,14 @@ public class TestBlockJoin extends LuceneTestCase { final BitSet bits = parents.getBitSet(leaf); return leaf.reader().document(bits.nextSetBit(childDocID - leaf.docBase)); } - + public void testBoostBug() throws Exception { final Directory dir = newDirectory(); final RandomIndexWriter w = new RandomIndexWriter(random(), dir); IndexReader r = w.getReader(); w.close(); IndexSearcher s = newSearcher(r); - + ToParentBlockJoinQuery q = new ToParentBlockJoinQuery(new MatchNoDocsQuery(), new QueryBitSetProducer(new MatchAllDocsQuery()), ScoreMode.Avg); QueryUtils.check(random(), q, s); s.search(q, 10); @@ -489,7 +499,7 @@ public class TestBlockJoin extends LuceneTestCase { } else { valueCount = TestUtil.nextInt(random(), 1, maxUniqueValues); } - + final String[] values = fields[fieldID] = new String[valueCount]; for(int i=0;i docs = new ArrayList<>(); - + final int rv = TestUtil.nextInt(random(), 1, 10); final int numJobs = atLeast(10); for (int j = 0; j < numJobs; j++) { @@ -1732,19 +1742,19 @@ public class TestBlockJoin extends LuceneTestCase { for (int i = 0; i < numQueryIters; i++) { final int qjv = TestUtil.nextInt(random(), -10, -1); final int qrv = TestUtil.nextInt(random(), 1, 10); - + Query resumeQuery = new ToChildBlockJoinQuery(new TermQuery(new Term("country","rv" + qrv)), resumeFilter); - + Query jobQuery = new ToChildBlockJoinQuery(IntPoint.newRangeQuery("year", qjv, qjv), jobFilter); - + BooleanQuery.Builder fullQuery = new BooleanQuery.Builder(); fullQuery.add(new BooleanClause(jobQuery, Occur.MUST)); fullQuery.add(new BooleanClause(resumeQuery, Occur.MUST)); - + TopDocs hits = s.search(fullQuery.build(), 100); // NOTE: totally possible that we'll get no matches - + for (ScoreDoc sd : hits.scoreDocs) { // since we're looking for children of jobs, all results must be qualifications String q = r.document(sd.doc).get("qualification"); @@ -1753,10 +1763,10 @@ public class TestBlockJoin extends LuceneTestCase { assertTrue(q + " MUST contain rv" + qrv, q.contains("rv"+qrv)); } } - + r.close(); dir.close(); } - + } diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java index c67811fd589..5591d5d0a56 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java @@ -507,6 +507,17 @@ public class TestJoinUtil extends LuceneTestCase { public String toString(String field) { return fieldQuery.toString(field); } + + @Override + public boolean equals(Object o) { + return o == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + }; Directory dir = newDirectory(); @@ -964,10 +975,10 @@ public class TestJoinUtil extends LuceneTestCase { final Query joinQuery; { - // single val can be handled by multiple-vals + // single val can be handled by multiple-vals final boolean muliValsQuery = multipleValuesPerDocument || random().nextBoolean(); - final String fromField = from ? "from":"to"; - final String toField = from ? "to":"from"; + final String fromField = from ? "from":"to"; + final String toField = from ? "to":"from"; int surpriseMe = random().nextInt(3); switch (surpriseMe) { @@ -1079,22 +1090,22 @@ public class TestJoinUtil extends LuceneTestCase { for (int i = 0; i < numRandomValues; i++) { String uniqueRandomValue; do { - // the trick is to generate values which will be ordered similarly for string, ints&longs, positive nums makes it easier + // the trick is to generate values which will be ordered similarly for string, ints&longs, positive nums makes it easier final int nextInt = random.nextInt(Integer.MAX_VALUE); uniqueRandomValue = String.format(Locale.ROOT, "%08x", nextInt); assert nextInt == Integer.parseUnsignedInt(uniqueRandomValue,16); } while ("".equals(uniqueRandomValue) || trackSet.contains(uniqueRandomValue)); - + // Generate unique values and empty strings aren't allowed. trackSet.add(uniqueRandomValue); - + context.randomFrom[i] = random.nextBoolean(); context.randomUniqueValues[i] = uniqueRandomValue; - + } List randomUniqueValuesReplica = new ArrayList<>(Arrays.asList(context.randomUniqueValues)); - + RandomDoc[] docs = new RandomDoc[nDocs]; for (int i = 0; i < nDocs; i++) { String id = Integer.toString(i); @@ -1117,7 +1128,7 @@ public class TestJoinUtil extends LuceneTestCase { Collections.shuffle(subValues, random); } for (String linkValue : subValues) { - + assert !docs[i].linkValues.contains(linkValue); docs[i].linkValues.add(linkValue); if (from) { @@ -1131,7 +1142,7 @@ public class TestJoinUtil extends LuceneTestCase { context.fromDocuments.get(linkValue).add(docs[i]); context.randomValueFromDocs.get(value).add(docs[i]); addLinkFields(random, document, "from", linkValue, multipleValuesPerDocument, globalOrdinalJoin); - + } else { if (!context.toDocuments.containsKey(linkValue)) { context.toDocuments.put(linkValue, new ArrayList<>()); diff --git a/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java b/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java index f3bd455e691..6a810444b6c 100644 --- a/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java +++ b/lucene/misc/src/test/org/apache/lucene/uninverting/TestFieldCacheSortRandom.java @@ -296,19 +296,22 @@ public class TestFieldCacheSortRandom extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - RandomQuery other = (RandomQuery) obj; - return seed == other.seed && docValues == other.docValues; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(RandomQuery other) { + return seed == other.seed && + docValues == other.docValues && + density == other.density; } @Override public int hashCode() { - int h = Objects.hash(seed, density); + int h = classHash(); + h = 31 * h + Objects.hash(seed, density); h = 31 * h + System.identityHashCode(docValues); - h = 31 * h + super.hashCode(); return h; } } diff --git a/lucene/queries/src/java/org/apache/lucene/queries/BoostingQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/BoostingQuery.java index 0d4ff2cbf30..713014c1f10 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/BoostingQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/BoostingQuery.java @@ -134,11 +134,6 @@ public class BoostingQuery extends Query { }; } - @Override - public int hashCode() { - return 31 * super.hashCode() + Objects.hash(match, context, boost); - } - public Query getMatch() { return match; } @@ -152,14 +147,20 @@ public class BoostingQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - BoostingQuery that = (BoostingQuery) obj; - return match.equals(that.match) - && context.equals(that.context) - && Float.floatToIntBits(boost) == Float.floatToIntBits(that.boost); + public int hashCode() { + return 31 * classHash() + Objects.hash(match, context, boost); + } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(BoostingQuery other) { + return match.equals(other.match) + && context.equals(other.context) + && Float.floatToIntBits(boost) == Float.floatToIntBits(other.boost); } @Override diff --git a/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java index c7b7e2f3fdc..7ebc01a0ff6 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexReader; @@ -411,42 +412,35 @@ public class CommonTermsQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); + int result = classHash(); result = prime * result + (disableCoord ? 1231 : 1237); result = prime * result + Float.floatToIntBits(highFreqBoost); - result = prime * result - + ((highFreqOccur == null) ? 0 : highFreqOccur.hashCode()); + result = prime * result + Objects.hashCode(highFreqOccur); + result = prime * result + Objects.hashCode(lowFreqOccur); result = prime * result + Float.floatToIntBits(lowFreqBoost); - result = prime * result - + ((lowFreqOccur == null) ? 0 : lowFreqOccur.hashCode()); result = prime * result + Float.floatToIntBits(maxTermFrequency); result = prime * result + Float.floatToIntBits(lowFreqMinNrShouldMatch); result = prime * result + Float.floatToIntBits(highFreqMinNrShouldMatch); - result = prime * result + ((terms == null) ? 0 : terms.hashCode()); + result = prime * result + Objects.hashCode(terms); return result; } - + @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - CommonTermsQuery other = (CommonTermsQuery) obj; - if (disableCoord != other.disableCoord) return false; - if (Float.floatToIntBits(highFreqBoost) != Float - .floatToIntBits(other.highFreqBoost)) return false; - if (highFreqOccur != other.highFreqOccur) return false; - if (Float.floatToIntBits(lowFreqBoost) != Float - .floatToIntBits(other.lowFreqBoost)) return false; - if (lowFreqOccur != other.lowFreqOccur) return false; - if (Float.floatToIntBits(maxTermFrequency) != Float - .floatToIntBits(other.maxTermFrequency)) return false; - if (lowFreqMinNrShouldMatch != other.lowFreqMinNrShouldMatch) return false; - if (highFreqMinNrShouldMatch != other.highFreqMinNrShouldMatch) return false; - if (terms == null) { - if (other.terms != null) return false; - } else if (!terms.equals(other.terms)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(CommonTermsQuery other) { + return disableCoord == other.disableCoord && + Float.floatToIntBits(highFreqBoost) == Float.floatToIntBits(other.highFreqBoost) && + highFreqOccur == other.highFreqOccur && + lowFreqOccur == other.lowFreqOccur && + Float.floatToIntBits(lowFreqBoost) == Float.floatToIntBits(other.lowFreqBoost) && + Float.floatToIntBits(maxTermFrequency) == Float.floatToIntBits(other.maxTermFrequency) && + lowFreqMinNrShouldMatch == other.lowFreqMinNrShouldMatch && + highFreqMinNrShouldMatch == other.highFreqMinNrShouldMatch && + terms.equals(other.terms); } /** diff --git a/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java index ed78a03a779..ab44fedc579 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/CustomScoreQuery.java @@ -137,25 +137,25 @@ public class CustomScoreQuery extends Query implements Cloneable { /** Returns true if o is equal to this. */ @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!super.equals(o)) - return false; - CustomScoreQuery other = (CustomScoreQuery)o; - if (!this.subQuery.equals(other.subQuery) || - this.strict != other.strict || - this.scoringQueries.length != other.scoringQueries.length) { - return false; - } - return Arrays.equals(scoringQueries, other.scoringQueries); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(CustomScoreQuery other) { + return subQuery.equals(other.subQuery) && + strict == other.strict && + scoringQueries.length == other.scoringQueries.length && + Arrays.equals(scoringQueries, other.scoringQueries); } /** Returns a hash code value for this object. */ @Override public int hashCode() { - return (getClass().hashCode() + subQuery.hashCode() + Arrays.hashCode(scoringQueries)) - ^ (strict ? 1234 : 4321); + // Didn't change this hashcode, but it looks suspicious. + return (classHash() + + subQuery.hashCode() + + Arrays.hashCode(scoringQueries)) ^ (strict ? 1234 : 4321); } /** diff --git a/lucene/queries/src/java/org/apache/lucene/queries/TermsQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/TermsQuery.java index c29500bb695..5c03b2ddcdd 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/TermsQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/TermsQuery.java @@ -173,22 +173,20 @@ public class TermsQuery extends Query implements Accountable { } @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - TermsQuery that = (TermsQuery) obj; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(TermsQuery other) { // termData might be heavy to compare so check the hash code first - return termDataHashCode == that.termDataHashCode - && termData.equals(that.termData); + return termDataHashCode == other.termDataHashCode && + termData.equals(other.termData); } @Override public int hashCode() { - return 31 * super.hashCode() + termDataHashCode; + return 31 * classHash() + termDataHashCode; } /** Returns the terms wrapped in a PrefixCodedTerms. */ diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/BoostedQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/BoostedQuery.java index e42fe644c9e..cafa819102d 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/function/BoostedQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/BoostedQuery.java @@ -160,16 +160,19 @@ public final class BoostedQuery extends Query { } @Override - public boolean equals(Object o) { - if (!super.equals(o)) return false; - BoostedQuery other = (BoostedQuery)o; - return this.q.equals(other.q) - && this.boostVal.equals(other.boostVal); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(BoostedQuery other) { + return q.equals(other.q) && + boostVal.equals(other.boostVal); } @Override public int hashCode() { - int h = super.hashCode(); + int h = classHash(); h = 31 * h + q.hashCode(); h = 31 * h + boostVal.hashCode(); return h; diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java index 85eac268dfd..e6152e88d27 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java @@ -163,15 +163,13 @@ public class FunctionQuery extends Query { /** Returns true if o is equal to this. */ @Override - public boolean equals(Object o) { - if (!FunctionQuery.class.isInstance(o)) return false; - FunctionQuery other = (FunctionQuery)o; - return super.equals(o) - && this.func.equals(other.func); + public boolean equals(Object other) { + return sameClassAs(other) && + func.equals(((FunctionQuery) other).func); } @Override public int hashCode() { - return super.hashCode() ^ func.hashCode(); + return classHash() ^ func.hashCode(); } } diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java index 65215a3dda4..60cfca3d157 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java @@ -95,21 +95,22 @@ public class FunctionRangeQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof FunctionRangeQuery)) return false; - if (!super.equals(o)) return false; - FunctionRangeQuery that = (FunctionRangeQuery) o; - return Objects.equals(includeLower, that.includeLower) && - Objects.equals(includeUpper, that.includeUpper) && - Objects.equals(valueSource, that.valueSource) && - Objects.equals(lowerVal, that.lowerVal) && - Objects.equals(upperVal, that.upperVal); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(FunctionRangeQuery other) { + return Objects.equals(includeLower, other.includeLower) && + Objects.equals(includeUpper, other.includeUpper) && + Objects.equals(valueSource, other.valueSource) && + Objects.equals(lowerVal, other.lowerVal) && + Objects.equals(upperVal, other.upperVal); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), valueSource, lowerVal, upperVal, includeLower, includeUpper); + return classHash() ^ Objects.hash(valueSource, lowerVal, upperVal, includeLower, includeUpper); } @Override diff --git a/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java index ecd3e60118e..4f44919191b 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import java.util.Set; +import java.util.Objects; /** * A simple wrapper for MoreLikeThis for use in scenarios where a Query object is required eg @@ -48,10 +49,10 @@ public class MoreLikeThisQuery extends Query { * @param moreLikeFields fields used for similarity measure */ public MoreLikeThisQuery(String likeText, String[] moreLikeFields, Analyzer analyzer, String fieldName) { - this.likeText = likeText; - this.moreLikeFields = moreLikeFields; - this.analyzer = analyzer; - this.fieldName = fieldName; + this.likeText = Objects.requireNonNull(likeText); + this.moreLikeFields = Objects.requireNonNull(moreLikeFields); + this.analyzer = Objects.requireNonNull(analyzer); + this.fieldName = Objects.requireNonNull(fieldName); } @Override @@ -152,43 +153,31 @@ public class MoreLikeThisQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((analyzer == null) ? 0 : analyzer.hashCode()); - result = prime * result + ((fieldName == null) ? 0 : fieldName.hashCode()); - result = prime * result + ((likeText == null) ? 0 : likeText.hashCode()); + int result = classHash(); + result = prime * result + Objects.hash(analyzer, fieldName, likeText, stopWords); result = prime * result + maxQueryTerms; result = prime * result + minDocFreq; result = prime * result + minTermFrequency; result = prime * result + Arrays.hashCode(moreLikeFields); result = prime * result + Float.floatToIntBits(percentTermsToMatch); - result = prime * result + ((stopWords == null) ? 0 : stopWords.hashCode()); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - MoreLikeThisQuery other = (MoreLikeThisQuery) obj; - if (analyzer == null) { - if (other.analyzer != null) return false; - } else if (!analyzer.equals(other.analyzer)) return false; - if (fieldName == null) { - if (other.fieldName != null) return false; - } else if (!fieldName.equals(other.fieldName)) return false; - if (likeText == null) { - if (other.likeText != null) return false; - } else if (!likeText.equals(other.likeText)) return false; - if (maxQueryTerms != other.maxQueryTerms) return false; - if (minDocFreq != other.minDocFreq) return false; - if (minTermFrequency != other.minTermFrequency) return false; - if (!Arrays.equals(moreLikeFields, other.moreLikeFields)) return false; - if (Float.floatToIntBits(percentTermsToMatch) != Float - .floatToIntBits(other.percentTermsToMatch)) return false; - if (stopWords == null) { - if (other.stopWords != null) return false; - } else if (!stopWords.equals(other.stopWords)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(MoreLikeThisQuery other) { + return maxQueryTerms == other.maxQueryTerms && + minDocFreq == other.minDocFreq && + minTermFrequency == other.minTermFrequency && + Float.floatToIntBits(percentTermsToMatch) == Float.floatToIntBits(other.percentTermsToMatch) && + analyzer.equals(other.analyzer) && + fieldName.equals(other.fieldName) && + likeText.equals(other.likeText) && + Arrays.equals(moreLikeFields, other.moreLikeFields) && + Objects.equals(stopWords, other.stopWords); } } diff --git a/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java index d35eb35a025..2d483ba7940 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java @@ -19,6 +19,7 @@ package org.apache.lucene.queries.payloads; import java.io.IOException; import java.util.Map; import java.util.Set; +import java.util.Objects; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.PostingsEnum; @@ -60,8 +61,8 @@ public class PayloadScoreQuery extends SpanQuery { * @param includeSpanScore include both span score and payload score in the scoring algorithm */ public PayloadScoreQuery(SpanQuery wrappedQuery, PayloadFunction function, boolean includeSpanScore) { - this.wrappedQuery = wrappedQuery; - this.function = function; + this.wrappedQuery = Objects.requireNonNull(wrappedQuery); + this.function = Objects.requireNonNull(function); this.includeSpanScore = includeSpanScore; } @@ -93,23 +94,21 @@ public class PayloadScoreQuery extends SpanQuery { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof PayloadScoreQuery)) return false; - if (!super.equals(o)) return false; - - PayloadScoreQuery that = (PayloadScoreQuery) o; - - if (wrappedQuery != null ? !wrappedQuery.equals(that.wrappedQuery) : that.wrappedQuery != null) return false; - return !(function != null ? !function.equals(that.function) : that.function != null); - + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(PayloadScoreQuery other) { + return wrappedQuery.equals(other.wrappedQuery) && + function.equals(other.function); } @Override public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (wrappedQuery != null ? wrappedQuery.hashCode() : 0); - result = 31 * result + (function != null ? function.hashCode() : 0); + int result = classHash(); + result = 31 * result + Objects.hashCode(wrappedQuery); + result = 31 * result + Objects.hashCode(function); return result; } diff --git a/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java index 62704b42ba8..419a82a36ed 100644 --- a/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java +++ b/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java @@ -173,18 +173,13 @@ public class SpanPayloadCheckQuery extends SpanQuery { } @Override - public boolean equals(Object o) { - if (! super.equals(o)) { - return false; - } - SpanPayloadCheckQuery other = (SpanPayloadCheckQuery)o; - return this.payloadToMatch.equals(other.payloadToMatch); + public boolean equals(Object other) { + return sameClassAs(other) && + payloadToMatch.equals(((SpanPayloadCheckQuery) other).payloadToMatch); } @Override public int hashCode() { - int h = super.hashCode(); - h = (h * 63) ^ payloadToMatch.hashCode(); - return h; + return classHash() ^ payloadToMatch.hashCode(); } } \ No newline at end of file diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java index 1faea18c1a7..2a7f8a8a5ec 100644 --- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java +++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Objects; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.IndexReader; @@ -221,9 +222,8 @@ public class ComplexPhraseQueryParser extends QueryParser { public ComplexPhraseQuery(String field, String phrasedQueryStringContents, int slopFactor, boolean inOrder) { - super(); - this.field = field; - this.phrasedQueryStringContents = phrasedQueryStringContents; + this.field = Objects.requireNonNull(field); + this.phrasedQueryStringContents = Objects.requireNonNull(phrasedQueryStringContents); this.slopFactor = slopFactor; this.inOrder = inOrder; } @@ -407,43 +407,25 @@ public class ComplexPhraseQueryParser extends QueryParser { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((field == null) ? 0 : field.hashCode()); - result = prime - * result - + ((phrasedQueryStringContents == null) ? 0 - : phrasedQueryStringContents.hashCode()); + int result = classHash(); + result = prime * result + field.hashCode(); + result = prime * result + phrasedQueryStringContents.hashCode(); result = prime * result + slopFactor; result = prime * result + (inOrder ? 1 : 0); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - if (!super.equals(obj)) { - return false; - } - ComplexPhraseQuery other = (ComplexPhraseQuery) obj; - if (field == null) { - if (other.field != null) - return false; - } else if (!field.equals(other.field)) - return false; - if (phrasedQueryStringContents == null) { - if (other.phrasedQueryStringContents != null) - return false; - } else if (!phrasedQueryStringContents - .equals(other.phrasedQueryStringContents)) - return false; - if (slopFactor != other.slopFactor) - return false; - return inOrder == other.inOrder; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(ComplexPhraseQuery other) { + return field.equals(other.field) && + phrasedQueryStringContents.equals(other.phrasedQueryStringContents) && + slopFactor == other.slopFactor && + inOrder == other.inOrder; } } } diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/RewriteQuery.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/RewriteQuery.java index 90684236c1f..438535ff5fe 100644 --- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/RewriteQuery.java +++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/RewriteQuery.java @@ -16,6 +16,7 @@ */ package org.apache.lucene.queryparser.surround.query; import java.io.IOException; +import java.util.Objects; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.Query; @@ -29,9 +30,9 @@ abstract class RewriteQuery extends Query { SQ srndQuery, String fieldName, BasicQueryFactory qf) { - this.srndQuery = srndQuery; - this.fieldName = fieldName; - this.qf = qf; + this.srndQuery = Objects.requireNonNull(srndQuery); + this.fieldName = Objects.requireNonNull(fieldName); + this.qf = Objects.requireNonNull(qf); } @Override @@ -49,24 +50,22 @@ abstract class RewriteQuery extends Query { @Override public int hashCode() { - return super.hashCode() - ^ fieldName.hashCode() - ^ qf.hashCode() - ^ srndQuery.hashCode(); + return classHash() + ^ fieldName.hashCode() + ^ qf.hashCode() + ^ srndQuery.hashCode(); } @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (! getClass().equals(obj.getClass())) - return false; - @SuppressWarnings("unchecked") RewriteQuery other = (RewriteQuery)obj; - return super.equals(obj) - && fieldName.equals(other.fieldName) - && qf.equals(other.qf) - && srndQuery.equals(other.srndQuery); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); } + private boolean equalsTo(RewriteQuery other) { + return fieldName.equals(other.fieldName) && + qf.equals(other.qf) && + srndQuery.equals(other.srndQuery); + } } diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java index 9fe2367c2e5..41772a0e702 100644 --- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java +++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java @@ -18,6 +18,7 @@ package org.apache.lucene.queryparser.classic; import java.io.IOException; import java.io.Reader; +import java.util.Objects; import org.apache.lucene.analysis.*; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; @@ -38,7 +39,7 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { private static int multiToken = 0; public void testMultiAnalyzer() throws ParseException { - + QueryParser qp = new QueryParser("", new MultiAnalyzer()); // trivial, no multiple tokens: @@ -91,7 +92,7 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { assertEquals("+Synonym(multi multi2) +foo", qp.parse("multi foo").toString()); } - + public void testMultiAnalyzerWithSubclassOfQueryParser() throws ParseException { DumbQueryParser qp = new DumbQueryParser("", new MultiAnalyzer()); @@ -104,22 +105,22 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { assertEquals("\"(multi multi2) bar\"~99", qp.getSuperFieldQuery("","multi bar", true).toString()); - + // ask sublcass to parse phrase with modified default slop assertEquals("\"(multi multi2) foo\"~99 bar", qp.parse("\"multi foo\" bar").toString()); - + } - + public void testPosIncrementAnalyzer() throws ParseException { QueryParser qp = new QueryParser("", new PosIncrementAnalyzer()); assertEquals("quick brown", qp.parse("the quick brown").toString()); assertEquals("quick brown fox", qp.parse("the quick brown fox").toString()); } - + /** * Expands "multi" to "multi" and "multi2", both at the same position, - * and expands "triplemulti" to "triplemulti", "multi3", and "multi2". + * and expands "triplemulti" to "triplemulti", "multi3", and "multi2". */ private class MultiAnalyzer extends Analyzer { @@ -131,16 +132,16 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { } private final class TestFilter extends TokenFilter { - + private String prevType; private int prevStartOffset; private int prevEndOffset; - + private final CharTermAttribute termAtt; private final PositionIncrementAttribute posIncrAtt; private final OffsetAttribute offsetAtt; private final TypeAttribute typeAtt; - + public TestFilter(TokenStream in) { super(in); termAtt = addAttribute(CharTermAttribute.class); @@ -202,10 +203,10 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { } private final class TestPosIncrementFilter extends TokenFilter { - + CharTermAttribute termAtt; PositionIncrementAttribute posIncrAtt; - + public TestPosIncrementFilter(TokenStream in) { super(in); termAtt = addAttribute(CharTermAttribute.class); @@ -231,13 +232,13 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { /** a very simple subclass of QueryParser */ private final static class DumbQueryParser extends QueryParser { - + public DumbQueryParser(String f, Analyzer a) { super(f, a); } /** expose super's version */ - public Query getSuperFieldQuery(String f, String t, boolean quoted) + public Query getSuperFieldQuery(String f, String t, boolean quoted) throws ParseException { return super.getFieldQuery(f,t,quoted); } @@ -248,22 +249,32 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase { return new DumbQueryWrapper(getSuperFieldQuery(f,t,quoted)); } } - + /** * A very simple wrapper to prevent instanceof checks but uses * the toString of the query it wraps. */ private final static class DumbQueryWrapper extends Query { - private Query q; + public DumbQueryWrapper(Query q) { - super(); - this.q = q; + this.q = Objects.requireNonNull(q); } @Override public String toString(String f) { return q.toString(f); } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(q, ((DumbQueryWrapper) other).q); + } + + @Override + public int hashCode() { + return classHash() & q.hashCode(); + } } - + } diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointBoxQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointBoxQuery.java index 8d369461799..014e2a526d0 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointBoxQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointBoxQuery.java @@ -215,7 +215,7 @@ abstract class LatLonPointBoxQuery extends Query { @Override public final int hashCode() { - int hash = super.hashCode(); + int hash = classHash(); hash = 31 * hash + field.hashCode(); hash = 31 * hash + Arrays.hashCode(lowerPoint); hash = 31 * hash + Arrays.hashCode(upperPoint); @@ -226,32 +226,16 @@ abstract class LatLonPointBoxQuery extends Query { @Override public final boolean equals(Object other) { - if (super.equals(other) == false) { - return false; - } + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } - final LatLonPointBoxQuery q = (LatLonPointBoxQuery) other; - if (field.equals(q.field) == false) { - return false; - } - - if (q.numDims != numDims) { - return false; - } - - if (q.bytesPerDim != bytesPerDim) { - return false; - } - - if (Arrays.equals(lowerPoint, q.lowerPoint) == false) { - return false; - } - - if (Arrays.equals(upperPoint, q.upperPoint) == false) { - return false; - } - - return true; + private boolean equalsTo(LatLonPointBoxQuery other) { + return field.equals(other.field) && + numDims == other.numDims && + bytesPerDim == other.bytesPerDim && + Arrays.equals(lowerPoint, other.lowerPoint) && + Arrays.equals(upperPoint, other.upperPoint); } @Override diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java index f746deeda13..e3fd1125ccf 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java @@ -263,7 +263,7 @@ final class LatLonPointDistanceQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); + int result = classHash(); result = prime * result + field.hashCode(); long temp; temp = Double.doubleToLongBits(latitude); @@ -276,16 +276,16 @@ final class LatLonPointDistanceQuery extends Query { } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - LatLonPointDistanceQuery other = (LatLonPointDistanceQuery) obj; - if (field.equals(other.field) == false) return false; - if (Double.doubleToLongBits(latitude) != Double.doubleToLongBits(other.latitude)) return false; - if (Double.doubleToLongBits(longitude) != Double.doubleToLongBits(other.longitude)) return false; - if (Double.doubleToLongBits(radiusMeters) != Double.doubleToLongBits(other.radiusMeters)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(LatLonPointDistanceQuery other) { + return field.equals(other.field) && + Double.doubleToLongBits(latitude) == Double.doubleToLongBits(other.latitude) && + Double.doubleToLongBits(longitude) == Double.doubleToLongBits(other.longitude) && + Double.doubleToLongBits(radiusMeters) == Double.doubleToLongBits(other.radiusMeters); } @Override diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java index 9c0ac772a84..e90053755d0 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java @@ -169,21 +169,21 @@ final class LatLonPointInPolygonQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); + int result = classHash(); result = prime * result + field.hashCode(); result = prime * result + Arrays.hashCode(polygons); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - LatLonPointInPolygonQuery other = (LatLonPointInPolygonQuery) obj; - if (!field.equals(other.field)) return false; - if (!Arrays.equals(polygons, other.polygons)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(LatLonPointInPolygonQuery other) { + return field.equals(other.field) && + Arrays.equals(polygons, other.polygons); } @Override diff --git a/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java b/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java index adfa9d3131b..4aa0513804c 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Objects; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; @@ -77,45 +78,27 @@ public class FuzzyLikeThisQuery extends Query @Override public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((analyzer == null) ? 0 : analyzer.hashCode()); - result = prime * result - + ((fieldVals == null) ? 0 : fieldVals.hashCode()); + int prime = 31; + int result = classHash(); + result = prime * result + Objects.hashCode(analyzer); + result = prime * result + Objects.hashCode(fieldVals); result = prime * result + (ignoreTF ? 1231 : 1237); result = prime * result + maxNumTerms; return result; } @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - if (!super.equals(obj)) { - return false; - } - FuzzyLikeThisQuery other = (FuzzyLikeThisQuery) obj; - if (analyzer == null) { - if (other.analyzer != null) - return false; - } else if (!analyzer.equals(other.analyzer)) - return false; - if (fieldVals == null) { - if (other.fieldVals != null) - return false; - } else if (!fieldVals.equals(other.fieldVals)) - return false; - if (ignoreTF != other.ignoreTF) - return false; - if (maxNumTerms != other.maxNumTerms) - return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); } + private boolean equalsTo(FuzzyLikeThisQuery other) { + return Objects.equals(analyzer, other.analyzer) && + Objects.equals(fieldVals, other.fieldVals) && + ignoreTF == other.ignoreTF && + maxNumTerms == other.maxNumTerms; + } /** * diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java index a2ebca109fa..a588e88249f 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java @@ -58,21 +58,19 @@ public class DocValuesNumbersQuery extends Query { } @Override - public boolean equals(Object obj) { - if (!super.equals(obj)) { - return false; - } - // super.equals ensures we are the same class: - DocValuesNumbersQuery that = (DocValuesNumbersQuery) obj; - if (!field.equals(that.field)) { - return false; - } - return numbers.equals(that.numbers); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(DocValuesNumbersQuery other) { + return field.equals(other.field) && + numbers.equals(other.numbers); } @Override public int hashCode() { - return 31 * super.hashCode() + Objects.hash(field, numbers); + return 31 * classHash() + Objects.hash(field, numbers); } public String getField() { diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java index 97b199a96fd..d6030400d5d 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesRangeQuery.java @@ -78,22 +78,22 @@ public final class DocValuesRangeQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - final DocValuesRangeQuery that = (DocValuesRangeQuery) obj; - return field.equals(that.field) - && Objects.equals(lowerVal, that.lowerVal) - && Objects.equals(upperVal, that.upperVal) - && includeLower == that.includeLower - && includeUpper == that.includeUpper - && super.equals(obj); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(DocValuesRangeQuery other) { + return field.equals(other.field) && + Objects.equals(lowerVal, other.lowerVal) && + Objects.equals(upperVal, other.upperVal) && + includeLower == other.includeLower && + includeUpper == other.includeUpper; } @Override public int hashCode() { - return 31 * super.hashCode() + Objects.hash(field, lowerVal, upperVal, includeLower, includeUpper); + return 31 * classHash() + Objects.hash(field, lowerVal, upperVal, includeLower, includeUpper); } public String getField() { diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java index 4dd13cb9c90..7cb2ce12a37 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java @@ -119,20 +119,19 @@ public class DocValuesTermsQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - DocValuesTermsQuery that = (DocValuesTermsQuery) obj; - if (!field.equals(that.field)) { - return false; - } - return Arrays.equals(terms, that.terms); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(DocValuesTermsQuery other) { + return field.equals(other.field) && + Arrays.equals(terms, other.terms); } @Override public int hashCode() { - return 31 * super.hashCode() + Objects.hash(field, Arrays.asList(terms)); + return 31 * classHash() + Objects.hash(field, Arrays.asList(terms)); } @Override diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java index e9321df68f3..d0298c403bc 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java @@ -232,33 +232,32 @@ public class TermAutomatonQuery extends Query { /** Returns true iff o is equal to this. */ @Override - public boolean equals(Object o) { - if (!(o instanceof TermAutomatonQuery)) { - return false; - } - TermAutomatonQuery other = (TermAutomatonQuery) o; - - if (det == null) { - throw new IllegalStateException("please call finish first"); - } - if (other.det == null) { - throw new IllegalStateException("please call other.finish first"); - } - - // NOTE: not quite correct, because if terms were added in different - // order in each query but the language is the same, we return false: - return super.equals(o) - && this.termToID.equals(other.termToID) && - Operations.sameLanguage(det, other.det); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private static boolean checkFinished(TermAutomatonQuery q) { + if (q.det == null) { + throw new IllegalStateException("Call finish first on: " + q); + } + return true; + } + + private boolean equalsTo(TermAutomatonQuery other) { + // NOTE: not quite correct, because if terms were added in different + // order in each query but the language is the same, we return false: + return checkFinished(this) && + checkFinished(other) && + termToID.equals(other.termToID) && + Operations.sameLanguage(det, other.det); } - /** Returns a hash code value for this object. This is very costly! */ @Override public int hashCode() { - if (det == null) { - throw new IllegalStateException("please call finish first"); - } - return super.hashCode() ^ termToID.hashCode() + det.toDot().hashCode(); + checkFinished(this); + // TODO: LUCENE-7295: Automaton.toDot() is very costly! + return classHash() ^ termToID.hashCode() + det.toDot().hashCode(); } /** Returns the dot (graphviz) representation of this automaton. diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java index 8016b6168ed..1cc86bad7fe 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java +++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java @@ -45,9 +45,7 @@ import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.store.Directory; -import org.apache.lucene.util.BitDocIdSet; import org.apache.lucene.util.BitSetIterator; -import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.IOUtils; @@ -659,17 +657,19 @@ public class TestTermAutomatonQuery extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - RandomQuery other = (RandomQuery) obj; - return seed == other.seed && density == other.density; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(RandomQuery other) { + return seed == other.seed && + density == other.density; } @Override public int hashCode() { - return Objects.hash(super.hashCode(), seed, density); + return classHash() ^ Objects.hash(seed, density); } } diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java index 0e6ea2cb945..823b9c22ced 100644 --- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java +++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java @@ -57,22 +57,19 @@ public class CompositeVerifyQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - CompositeVerifyQuery that = (CompositeVerifyQuery) o; - - if (!indexQuery.equals(that.indexQuery)) return false; - if (!predicateValueSource.equals(that.predicateValueSource)) return false; - - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(CompositeVerifyQuery other) { + return indexQuery.equals(other.indexQuery) && + predicateValueSource.equals(other.predicateValueSource); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result = 31 * result + indexQuery.hashCode(); result = 31 * result + predicateValueSource.hashCode(); return result; diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java index ebb3ada20f8..ad9151410d2 100644 --- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java +++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java @@ -63,20 +63,19 @@ public class IntersectsRPTVerifyQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!super.equals(o)) return false; - - IntersectsRPTVerifyQuery that = (IntersectsRPTVerifyQuery) o; - - if (!intersectsDiffQuery.equals(that.intersectsDiffQuery)) return false; - return predicateValueSource.equals(that.predicateValueSource); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + private boolean equalsTo(IntersectsRPTVerifyQuery other) { + return intersectsDiffQuery.equals(other.intersectsDiffQuery) && + predicateValueSource.equals(other.predicateValueSource); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result = 31 * result + intersectsDiffQuery.hashCode(); result = 31 * result + predicateValueSource.hashCode(); return result; diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java index e599e79ab0e..a3f2f14d71a 100644 --- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java +++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java @@ -56,21 +56,19 @@ public abstract class AbstractPrefixTreeQuery extends Query { @Override public boolean equals(Object o) { - if (this == o) return true; - if (super.equals(o) == false) return false; + return sameClassAs(o) && + equalsTo(getClass().cast(o)); + } - AbstractPrefixTreeQuery that = (AbstractPrefixTreeQuery) o; - - if (detailLevel != that.detailLevel) return false; - if (!fieldName.equals(that.fieldName)) return false; - if (!queryShape.equals(that.queryShape)) return false; - - return true; + private boolean equalsTo(AbstractPrefixTreeQuery other) { + return detailLevel == other.detailLevel && + fieldName.equals(other.fieldName) && + queryShape.equals(other.queryShape); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result = 31 * result + queryShape.hashCode(); result = 31 * result + fieldName.hashCode(); result = 31 * result + detailLevel; diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java index cf2c329205e..7e37aace2e4 100644 --- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java +++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java @@ -156,20 +156,14 @@ public class SerializedDVStrategy extends SpatialStrategy { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (super.equals(o) == false) return false; - - PredicateValueSourceQuery that = (PredicateValueSourceQuery) o; - - if (!predicateValueSource.equals(that.predicateValueSource)) return false; - - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + predicateValueSource.equals(((PredicateValueSourceQuery) other).predicateValueSource); } @Override public int hashCode() { - return super.hashCode() + 31 * predicateValueSource.hashCode(); + return classHash() + 31 * predicateValueSource.hashCode(); } @Override diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java index 1634d45d39b..8d66e952d2b 100644 --- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java +++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointInBBoxQuery.java @@ -132,25 +132,22 @@ public class GeoPointInBBoxQuery extends Query { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof GeoPointInBBoxQuery)) return false; - if (!super.equals(o)) return false; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } - GeoPointInBBoxQuery that = (GeoPointInBBoxQuery) o; - - if (Double.compare(that.minLat, minLat) != 0) return false; - if (Double.compare(that.maxLat, maxLat) != 0) return false; - if (Double.compare(that.minLon, minLon) != 0) return false; - if (Double.compare(that.maxLon, maxLon) != 0) return false; - if (!field.equals(that.field)) return false; - - return true; + private boolean equalsTo(GeoPointInBBoxQuery other) { + return Double.compare(other.minLat, minLat) == 0 && + Double.compare(other.maxLat, maxLat) == 0 && + Double.compare(other.minLon, minLon) == 0 && + Double.compare(other.maxLon, maxLon) == 0 && + field.equals(other.field); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); long temp; result = 31 * result + field.hashCode(); temp = Double.doubleToLongBits(minLat); diff --git a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointTermQueryConstantScoreWrapper.java b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointTermQueryConstantScoreWrapper.java index 13ded15a9fd..739dec6862d 100644 --- a/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointTermQueryConstantScoreWrapper.java +++ b/lucene/spatial/src/java/org/apache/lucene/spatial/geopoint/search/GeoPointTermQueryConstantScoreWrapper.java @@ -64,17 +64,14 @@ final class GeoPointTermQueryConstantScoreWrapper that = (GeoPointTermQueryConstantScoreWrapper) o; - return this.query.equals(that.query); + public final boolean equals(final Object other) { + return sameClassAs(other) && + query.equals(((GeoPointTermQueryConstantScoreWrapper) other).query); } @Override public final int hashCode() { - return 31 * super.hashCode() + query.hashCode(); + return 31 * classHash() + query.hashCode(); } @Override diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java index d5d98d128b1..34e4de9839f 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java @@ -43,14 +43,14 @@ final class PointInGeo3DShapeQuery extends Query { final String field; final GeoShape shape; final XYZBounds shapeBounds; - + /** The lats/lons must be clockwise or counter-clockwise. */ public PointInGeo3DShapeQuery(String field, GeoShape shape) { this.field = field; this.shape = shape; this.shapeBounds = new XYZBounds(); shape.getBounds(shapeBounds); - + if (shape instanceof BasePlanetObject) { BasePlanetObject planetObject = (BasePlanetObject) shape; if (planetObject.getPlanetModel().equals(PlanetModel.WGS84) == false) { @@ -115,23 +115,19 @@ final class PointInGeo3DShapeQuery extends Query { } @Override - @SuppressWarnings({"unchecked","rawtypes"}) - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - PointInGeo3DShapeQuery that = (PointInGeo3DShapeQuery) o; - if (field.equals(that.field) == false) { - return false; - } - - return shape.equals(that.shape); + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(PointInGeo3DShapeQuery other) { + return field.equals(other.field) && + shape.equals(other.shape); } @Override public int hashCode() { - int result = super.hashCode(); + int result = classHash(); result = 31 * result + field.hashCode(); result = 31 * result + shape.hashCode(); return result; diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java index d004cdb109e..be9f208307b 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java @@ -34,7 +34,7 @@ import org.apache.lucene.util.automaton.Operations; import org.apache.lucene.util.fst.Util; /** - * A {@link CompletionQuery} that match documents specified by + * A {@link CompletionQuery} that matches documents specified by * a wrapped {@link CompletionQuery} supporting boosting and/or filtering * by specified contexts. *

@@ -315,4 +315,15 @@ public class ContextQuery extends CompletionQuery { return currentBoost + innerWeight.boost(); } } + + @Override + public boolean equals(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } + } diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java index 29d8c2ba895..91d494b3e9d 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java @@ -77,4 +77,14 @@ public class PrefixCompletionQuery extends CompletionQuery { public Analyzer getAnalyzer() { return analyzer; } + + @Override + public boolean equals(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } } diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java index 72bc495d3a6..5e0c489eb12 100644 --- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java +++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java @@ -106,4 +106,13 @@ public class RegexCompletionQuery extends CompletionQuery { return maxDeterminizedStates; } + @Override + public boolean equals(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public int hashCode() { + throw new UnsupportedOperationException(); + } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java index a6766028546..9110f5c1126 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java +++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java @@ -49,12 +49,9 @@ public final class AssertingQuery extends Query { } @Override - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof AssertingQuery)) { - return false; - } - final AssertingQuery that = (AssertingQuery) obj; - return this.in.equals(that.in); + public boolean equals(Object other) { + return sameClassAs(other) && + in.equals(((AssertingQuery) other).in); } @Override diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java b/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java index 74a46d4f5e7..ea70c988d5b 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java +++ b/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java @@ -67,9 +67,20 @@ public class QueryUtils { public String toString(String field) { return "My Whacky Query"; } + + @Override + public boolean equals(Object o) { + return o == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } + }; checkUnequal(q, whacky); - + // null test assertFalse(q.equals(null)); } @@ -87,13 +98,13 @@ public class QueryUtils { // happens, please change test to use a different example. assertTrue(q1.hashCode() != q2.hashCode()); } - + /** deep check that explanations of a query 'score' correctly */ public static void checkExplanations (final Query q, final IndexSearcher s) throws IOException { CheckHits.checkExplanations(q, null, s, true); } - - /** + + /** * Various query sanity checks on a searcher, some checks are only done for * instanceof IndexSearcher. * @@ -124,22 +135,22 @@ public class QueryUtils { throw new RuntimeException(e); } } - + /** This is a MultiReader that can be used for randomly wrapping other readers * without creating FieldCache insanity. * The trick is to use an opaque/fake cache key. */ public static class FCInvisibleMultiReader extends MultiReader { private final Object cacheKey = new Object(); - + public FCInvisibleMultiReader(IndexReader... readers) throws IOException { super(readers); } - + @Override public Object getCoreCacheKey() { return cacheKey; } - + @Override public Object getCombinedCoreAndDeletesKey() { return cacheKey; @@ -147,15 +158,15 @@ public class QueryUtils { } /** - * Given an IndexSearcher, returns a new IndexSearcher whose IndexReader - * is a MultiReader containing the Reader of the original IndexSearcher, - * as well as several "empty" IndexReaders -- some of which will have - * deleted documents in them. This new IndexSearcher should + * Given an IndexSearcher, returns a new IndexSearcher whose IndexReader + * is a MultiReader containing the Reader of the original IndexSearcher, + * as well as several "empty" IndexReaders -- some of which will have + * deleted documents in them. This new IndexSearcher should * behave exactly the same as the original IndexSearcher. * @param s the searcher to wrap * @param edge if negative, s will be the first sub; if 0, s will be in the middle, if positive s will be the last sub */ - public static IndexSearcher wrapUnderlyingReader(Random random, final IndexSearcher s, final int edge) + public static IndexSearcher wrapUnderlyingReader(Random random, final IndexSearcher s, final int edge) throws IOException { IndexReader r = s.getIndexReader(); @@ -179,7 +190,7 @@ public class QueryUtils { out.setSimilarity(s.getSimilarity(true)); return out; } - + private static IndexReader emptyReader(final int maxDoc) { return new LeafReader() { @@ -248,7 +259,7 @@ public class QueryUtils { public FieldInfos getFieldInfos() { return new FieldInfos(new FieldInfo[0]); } - + final Bits liveDocs = new Bits.MatchNoBits(maxDoc); @Override public Bits getLiveDocs() { @@ -345,7 +356,7 @@ public class QueryUtils { scorer = w.scorer(context); iterator = scorer.iterator(); } - + int op = order[(opidx[0]++) % order.length]; // System.out.println(op==skip_op ? // "skip("+(sdoc[0]+1)+")":"next()"); @@ -453,7 +464,7 @@ public class QueryUtils { } } } - + /** check that first skip on just created scorers always goes to the right doc */ public static void checkFirstSkipTo(final Query q, final IndexSearcher s) throws IOException { //System.out.println("checkFirstSkipTo: "+q); @@ -479,9 +490,9 @@ public class QueryUtils { Assert.assertTrue("query collected "+doc+" but advance("+i+") says no more docs!",scorer.iterator().advance(i) != DocIdSetIterator.NO_MORE_DOCS); Assert.assertEquals("query collected "+doc+" but advance("+i+") got to "+scorer.docID(),doc,scorer.docID()); float advanceScore = scorer.score(); - Assert.assertEquals("unstable advance("+i+") score!",advanceScore,scorer.score(),maxDiff); + Assert.assertEquals("unstable advance("+i+") score!",advanceScore,scorer.score(),maxDiff); Assert.assertEquals("query assigned doc "+doc+" a score of <"+score+"> but advance("+i+") has <"+advanceScore+">!",score,advanceScore,maxDiff); - + // Hurry things along if they are going slow (eg // if you got SimpleText codec this will kick in): if (i < doc && System.currentTimeMillis() - startMS > 5) { @@ -493,7 +504,7 @@ public class QueryUtils { throw new RuntimeException(e); } } - + @Override public boolean needsScores() { return true; @@ -596,7 +607,7 @@ public class QueryUtils { bulkScorer.score(new LeafCollector() { @Override public void setScorer(Scorer scorer) throws IOException {} - + @Override public void collect(int doc) throws IOException { // no more matches diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java index f628147fecb..7e822f137ca 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java +++ b/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java @@ -49,20 +49,14 @@ public class RandomApproximationQuery extends Query { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - final RandomApproximationQuery that = (RandomApproximationQuery) obj; - if (this.query.equals(that.query) == false) { - return false; - } - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + query.equals(((RandomApproximationQuery) other).query); } @Override public int hashCode() { - return 31 * super.hashCode() + query.hashCode(); + return 31 * classHash() + query.hashCode(); } @Override diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java index bf98ba1a4c6..544a53cf945 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java +++ b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java @@ -21,6 +21,7 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import java.io.IOException; +import java.util.Objects; /** Wraps a span query with asserts */ public class AssertingSpanQuery extends SpanQuery { @@ -64,22 +65,17 @@ public class AssertingSpanQuery extends SpanQuery { } @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((in == null) ? 0 : in.hashCode()); - return result; + public boolean equals(Object o) { + return sameClassAs(o) && + equalsTo(getClass().cast(o)); + } + + private boolean equalsTo(AssertingSpanQuery other) { + return Objects.equals(in, other.in); } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - AssertingSpanQuery other = (AssertingSpanQuery) obj; - if (in == null) { - if (other.in != null) return false; - } else if (!in.equals(other.in)) return false; - return true; + public int hashCode() { + return (in == null) ? 0 : in.hashCode(); } } diff --git a/solr/core/src/java/org/apache/solr/schema/LatLonType.java b/solr/core/src/java/org/apache/solr/schema/LatLonType.java index c30729adb48..2ff11942ea0 100644 --- a/solr/core/src/java/org/apache/solr/schema/LatLonType.java +++ b/solr/core/src/java/org/apache/solr/schema/LatLonType.java @@ -554,7 +554,7 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter { /** Returns true if o is equal to this. */ @Override public boolean equals(Object o) { - if (!super.equals(o)) return false; + if (!sameClassAs(o)) return false; SpatialDistanceQuery other = (SpatialDistanceQuery)o; return this.latCenter == other.latCenter && this.lonCenter == other.lonCenter @@ -576,12 +576,11 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter { @Override public int hashCode() { // don't bother making the hash expensive - the center latitude + min longitude will be very unique - long hash = Double.doubleToLongBits(latCenter); + long hash = classHash(); + hash = hash * 31 + Double.doubleToLongBits(latCenter); hash = hash * 31 + Double.doubleToLongBits(lonMin); - hash = hash * 31 + (long)super.hashCode(); - return (int)(hash >> 32 + hash); + return (int) (hash >> 32 + hash); } - } diff --git a/solr/core/src/java/org/apache/solr/search/BitDocSet.java b/solr/core/src/java/org/apache/solr/search/BitDocSet.java index 56c19bbf086..317e976fb9a 100644 --- a/solr/core/src/java/org/apache/solr/search/BitDocSet.java +++ b/solr/core/src/java/org/apache/solr/search/BitDocSet.java @@ -18,6 +18,7 @@ package org.apache.solr.search; import java.util.Collection; import java.util.Collections; +import java.util.Objects; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.LeafReaderContext; @@ -266,11 +267,12 @@ public class BitDocSet extends DocSetBase { @Override public Filter getTopFilter() { - final FixedBitSet bs = bits; // TODO: if cardinality isn't cached, do a quick measure of sparseness // and return null from bits() if too sparse. return new Filter() { + final FixedBitSet bs = bits; + @Override public DocIdSet getDocIdSet(final LeafReaderContext context, final Bits acceptDocs) { LeafReader reader = context.reader(); @@ -355,10 +357,22 @@ public class BitDocSet extends DocSetBase { }, acceptDocs2); } + @Override public String toString(String field) { return "BitSetDocTopFilter"; } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(bs, getClass().cast(other).bs); + } + + @Override + public int hashCode() { + return classHash() * 31 + bs.hashCode(); + } }; } diff --git a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java index 9a22221d638..5686fe1143a 100644 --- a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java @@ -239,25 +239,25 @@ public class CollapsingQParserPlugin extends QParserPlugin { return false; } + // Only a subset of fields in hashCode/equals? + public int hashCode() { - int hashCode = super.hashCode(); + int hashCode = classHash(); hashCode = 31 * hashCode + collapseField.hashCode(); hashCode = 31 * hashCode + groupHeadSelector.hashCode(); hashCode = 31 * hashCode + nullPolicy; return hashCode; } - public boolean equals(Object o) { + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } - if(o instanceof CollapsingPostFilter) { - CollapsingPostFilter c = (CollapsingPostFilter)o; - if(this.collapseField.equals(c.collapseField) && - this.groupHeadSelector.equals(c.groupHeadSelector) && - this.nullPolicy == c.nullPolicy) { - return true; - } - } - return false; + private boolean equalsTo(CollapsingPostFilter other) { + return collapseField.equals(other.collapseField) && + groupHeadSelector.equals(other.groupHeadSelector) && + nullPolicy == other.nullPolicy; } public int getCost() { diff --git a/solr/core/src/java/org/apache/solr/search/DocSetBase.java b/solr/core/src/java/org/apache/solr/search/DocSetBase.java index fa83981aba7..a35c19f8448 100644 --- a/solr/core/src/java/org/apache/solr/search/DocSetBase.java +++ b/solr/core/src/java/org/apache/solr/search/DocSetBase.java @@ -17,6 +17,7 @@ package org.apache.solr.search; import java.io.IOException; +import java.util.Objects; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.LeafReaderContext; @@ -161,9 +162,9 @@ abstract class DocSetBase implements DocSet { @Override public Filter getTopFilter() { - final FixedBitSet bs = getBits(); - return new Filter() { + final FixedBitSet bs = getBits(); + @Override public DocIdSet getDocIdSet(final LeafReaderContext context, Bits acceptDocs) { LeafReader reader = context.reader(); @@ -223,10 +224,22 @@ abstract class DocSetBase implements DocSet { }, acceptDocs2); } + @Override public String toString(String field) { return "DocSetTopFilter"; } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(bs, getClass().cast(other).bs); + } + + @Override + public int hashCode() { + return classHash() ^ bs.hashCode(); + } }; } diff --git a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java index aee667468d3..8156f245bdb 100644 --- a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java @@ -19,15 +19,15 @@ package org.apache.solr.search; import org.apache.lucene.util.FixedBitSet; import org.apache.solr.handler.component.MergeStrategy; import org.apache.solr.request.SolrRequestInfo; + import org.apache.lucene.search.*; import org.apache.lucene.index.*; -import org.apache.solr.common.util.NamedList; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.common.params.SolrParams; import java.io.IOException; import java.util.Map; -import java.util.Set; +import java.util.Objects; public class ExportQParserPlugin extends QParserPlugin { @@ -53,7 +53,6 @@ public class ExportQParserPlugin extends QParserPlugin { } public class ExportQuery extends RankQuery { - private Query mainQuery; private Object id; @@ -94,17 +93,21 @@ public class ExportQParserPlugin extends QParserPlugin { } public int hashCode() { - return 31 * super.hashCode() + id.hashCode(); + return classHash() + + 31 * id.hashCode() + + 31 * Objects.hash(mainQuery); + } + + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); } - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - ExportQuery q = (ExportQuery)o; - return id == q.id; + private boolean equalsTo(ExportQuery other) { + return Objects.equals(id, other.id) && + Objects.equals(mainQuery, other.mainQuery); } - + public String toString(String s) { return s; } diff --git a/solr/core/src/java/org/apache/solr/search/ExtendedQueryBase.java b/solr/core/src/java/org/apache/solr/search/ExtendedQueryBase.java index 91192e1f6d6..06d2401324d 100644 --- a/solr/core/src/java/org/apache/solr/search/ExtendedQueryBase.java +++ b/solr/core/src/java/org/apache/solr/search/ExtendedQueryBase.java @@ -18,7 +18,7 @@ package org.apache.solr.search; import org.apache.lucene.search.Query; -public class ExtendedQueryBase extends Query implements ExtendedQuery { +public abstract class ExtendedQueryBase extends Query implements ExtendedQuery { private int cost; private boolean cache = true; private boolean cacheSep; diff --git a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java index 3a66193f149..664fa07d6e9 100644 --- a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java @@ -149,16 +149,12 @@ public class GraphTermsQParserPlugin extends QParserPlugin { } public int hashCode() { - return 31 * super.hashCode() + id.hashCode(); + return 31 * classHash() + id.hashCode(); } - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - - GraphTermsQuery q = (GraphTermsQuery)o; - return id == q.id; + public boolean equals(Object other) { + return sameClassAs(other) && + id == ((GraphTermsQuery) other).id; } public GraphTermsQuery clone() { diff --git a/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java index a95f41ed863..2112c714446 100644 --- a/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java @@ -17,6 +17,7 @@ package org.apache.solr.search; import java.io.IOException; +import java.util.Arrays; import java.util.List; import org.apache.lucene.index.IndexReaderContext; @@ -38,7 +39,6 @@ import org.apache.lucene.util.CharsRef; import org.apache.lucene.util.CharsRefBuilder; import org.apache.lucene.util.FixedBitSet; import org.apache.solr.common.params.SolrParams; -import org.apache.solr.common.util.NamedList; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; @@ -89,15 +89,21 @@ public class HashQParserPlugin extends QParserPlugin { } public int hashCode() { - return 31 * super.hashCode() + keysParam.hashCode()+workers+worker; + return classHash() + + 31 * keysParam.hashCode() + + 31 * workers + + 31 * worker; } - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - HashQuery h = (HashQuery)o; - return keysParam.equals(h.keysParam) && workers == h.workers && worker == h.worker; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(HashQuery other) { + return keysParam.equals(other.keysParam) && + workers == other.workers && + worker == other.worker; } public HashQuery(String keysParam, int workers, int worker) { @@ -142,6 +148,21 @@ public class HashQParserPlugin extends QParserPlugin { public DocIdSet getDocIdSet(LeafReaderContext context, Bits bits) { return BitsFilteredDocIdSet.wrap(new BitDocIdSet(bitSets[context.ord]), bits); } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(BitsFilter other) { + return Arrays.equals(bitSets, other.bitSets); + } + + @Override + public int hashCode() { + return classHash() + Arrays.asList(bitSets).hashCode(); + } } diff --git a/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java index af333305e5d..15716526f78 100644 --- a/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexReader; @@ -505,24 +506,27 @@ class JoinQuery extends Query { } @Override - public boolean equals(Object o) { - if (!super.equals(o)) return false; - JoinQuery other = (JoinQuery)o; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(JoinQuery other) { return this.fromField.equals(other.fromField) - && this.toField.equals(other.toField) - && this.q.equals(other.q) - && (this.fromIndex == other.fromIndex || this.fromIndex != null && this.fromIndex.equals(other.fromIndex)) - && this.fromCoreOpenTime == other.fromCoreOpenTime - ; + && this.toField.equals(other.toField) + && this.q.equals(other.q) + && Objects.equals(fromIndex, other.fromIndex) + && this.fromCoreOpenTime == other.fromCoreOpenTime; } @Override public int hashCode() { - int h = super.hashCode(); - h = h * 31 + q.hashCode(); - h = h * 31 + (int)fromCoreOpenTime; + int h = classHash(); h = h * 31 + fromField.hashCode(); h = h * 31 + toField.hashCode(); + h = h * 31 + q.hashCode(); + h = h * 31 + Objects.hashCode(fromIndex); + h = h * 31 + (int) fromCoreOpenTime; return h; } diff --git a/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java b/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java index 264378b234a..6bba1de2c64 100644 --- a/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java +++ b/solr/core/src/java/org/apache/solr/search/QueryWrapperFilter.java @@ -89,14 +89,16 @@ public class QueryWrapperFilter extends Filter { @Override public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - return this.query.equals(((QueryWrapperFilter)o).query); + return sameClassAs(o) && + equalsTo(getClass().cast(o)); + } + + private boolean equalsTo(QueryWrapperFilter other) { + return query.equals(other.query); } @Override public int hashCode() { - return 31 * super.hashCode() + query.hashCode(); + return query.hashCode(); } } diff --git a/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java index 552acad040e..f80cf341c61 100644 --- a/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java @@ -110,14 +110,15 @@ public class ReRankQParserPlugin extends QParserPlugin { private Map boostedPriority; public int hashCode() { - return 31 * super.hashCode() + mainQuery.hashCode()+reRankQuery.hashCode()+(int)reRankWeight+reRankDocs; + return 31 * classHash() + mainQuery.hashCode()+reRankQuery.hashCode()+(int)reRankWeight+reRankDocs; } - public boolean equals(Object o) { - if (super.equals(o) == false) { - return false; - } - ReRankQuery rrq = (ReRankQuery)o; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(ReRankQuery rrq) { return mainQuery.equals(rrq.mainQuery) && reRankQuery.equals(rrq.reRankQuery) && reRankWeight == rrq.reRankWeight && diff --git a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java index c255dee8eda..6e55ad913dd 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java +++ b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java @@ -18,6 +18,7 @@ package org.apache.solr.search; import java.io.IOException; import java.util.Map; +import java.util.Objects; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.queries.function.ValueSource; @@ -118,17 +119,15 @@ public class SolrConstantScoreQuery extends Query implements ExtendedQuery { /** Returns true if o is equal to this. */ @Override - public boolean equals(Object o) { - if (this == o) return true; - if (super.equals(o) == false) return false; - SolrConstantScoreQuery other = (SolrConstantScoreQuery)o; - return filter.equals(other.filter); + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(filter, ((SolrConstantScoreQuery) other).filter); } /** Returns a hash code value for this object. */ @Override public int hashCode() { - return 31 * super.hashCode() + filter.hashCode(); + return 31 * classHash() + filter.hashCode(); } } diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java index 23ff63be34b..113fd90dac8 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -56,14 +56,14 @@ import org.apache.lucene.index.PostingsEnum; import org.apache.lucene.index.SlowCompositeReaderWrapper; import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.SortedSetDocValues; -import org.apache.lucene.index.StoredFieldVisitor.Status; import org.apache.lucene.index.StoredFieldVisitor; +import org.apache.lucene.index.StoredFieldVisitor.Status; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; -import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.CollectionStatistics; import org.apache.lucene.search.Collector; @@ -98,15 +98,14 @@ import org.apache.lucene.uninverting.UninvertingReader; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.FixedBitSet; -import org.apache.lucene.util.NumericUtils; import org.apache.solr.common.SolrDocumentBase; -import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.SolrException; +import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.SimpleOrderedMap; -import org.apache.solr.core.DirectoryFactory.DirContext; import org.apache.solr.core.DirectoryFactory; +import org.apache.solr.core.DirectoryFactory.DirContext; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrInfoMBean; @@ -129,6 +128,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.collect.Iterables; /** @@ -2621,6 +2621,23 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI } + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(FilterImpl other) { + return Objects.equal(this.topFilter, other.topFilter) && + Objects.equal(this.weights, other.weights); + } + + @Override + public int hashCode() { + return classHash() + + 31 * Objects.hashCode(topFilter) + + 31 * Objects.hashCode(weights); + } } } diff --git a/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java b/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java index 0cb5d08f1da..ba60707c6f4 100644 --- a/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java +++ b/solr/core/src/java/org/apache/solr/search/SortedIntDocSet.java @@ -775,6 +775,18 @@ public class SortedIntDocSet extends DocSetBase { public String toString(String field) { return "SortedIntDocSetTopFilter"; } + + // Equivalence should/could be based on docs here? How did it work previously? + + @Override + public boolean equals(Object other) { + return other == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } }; } diff --git a/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java index 1976431d364..83e9a8fac88 100644 --- a/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java +++ b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java @@ -16,6 +16,8 @@ */ package org.apache.solr.search.join; +import java.util.Objects; + import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.solr.search.DelegatingCollector; @@ -70,4 +72,19 @@ class BlockJoinFacetFilter extends Query implements PostFilter { public void setCacheSep(boolean cacheSep) { } + + @Override + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(BlockJoinFacetFilter other) { + return Objects.equals(blockJoinFacetCollector, other.blockJoinFacetCollector); + } + + @Override + public int hashCode() { + return classHash() * 31 + blockJoinFacetCollector.hashCode(); + } } diff --git a/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java b/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java index 2203220a201..8f36dd2e0bb 100644 --- a/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java +++ b/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java @@ -17,6 +17,7 @@ package org.apache.solr.search.join; import java.io.IOException; +import java.util.Objects; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.DocIdSet; @@ -134,16 +135,14 @@ public class BlockJoinParentQParser extends QParser { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - return filter.equals(((BitDocIdSetFilterWrapper) obj).filter); + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(filter, getClass().cast(other).filter); } @Override public int hashCode() { - return 31 * super.hashCode() + filter.hashCode(); + return classHash() + filter.hashCode(); } } diff --git a/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java index 188971762c6..9bac616c69a 100644 --- a/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java +++ b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java @@ -19,6 +19,7 @@ package org.apache.solr.search.join; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; @@ -450,56 +451,33 @@ public class GraphQuery extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((fromField == null) ? 0 : fromField.hashCode()); + int result = classHash(); + result = prime * result + Objects.hashCode(fromField); result = prime * result + maxDepth; result = prime * result + (onlyLeafNodes ? 1231 : 1237); - result = prime * result + ((q == null) ? 0 : q.hashCode()); + result = prime * result + Objects.hashCode(q); result = prime * result + (returnRoot ? 1231 : 1237); - result = prime * result + ((toField == null) ? 0 : toField.hashCode()); - result = prime * result + ((traversalFilter == null) ? 0 : traversalFilter.hashCode()); + result = prime * result + Objects.hashCode(toField); + result = prime * result + Objects.hashCode(traversalFilter); result = prime * result + (useAutn ? 1231 : 1237); return result; } - + @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - GraphQuery other = (GraphQuery) obj; - if (fromField == null) { - if (other.fromField != null) - return false; - } else if (!fromField.equals(other.fromField)) - return false; - if (maxDepth != other.maxDepth) - return false; - if (onlyLeafNodes != other.onlyLeafNodes) - return false; - if (q == null) { - if (other.q != null) - return false; - } else if (!q.equals(other.q)) - return false; - if (returnRoot != other.returnRoot) - return false; - if (toField == null) { - if (other.toField != null) - return false; - } else if (!toField.equals(other.toField)) - return false; - if (traversalFilter == null) { - if (other.traversalFilter != null) - return false; - } else if (!traversalFilter.equals(other.traversalFilter)) - return false; - if (useAutn != other.useAutn) - return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(GraphQuery other) { + return Objects.equals(fromField, other.fromField) && + maxDepth == other.maxDepth && + onlyLeafNodes == other.onlyLeafNodes && + returnRoot == other.returnRoot && + useAutn == other.useAutn && + Objects.equals(q, other.q) && + Objects.equals(toField, other.toField) && + Objects.equals(traversalFilter, other.traversalFilter); } } diff --git a/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java index be128c6aca0..93a4b20d295 100644 --- a/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java @@ -18,6 +18,7 @@ package org.apache.solr.search.join; import java.io.IOException; import java.util.Map; +import java.util.Objects; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.IndexReader; @@ -174,34 +175,25 @@ public class ScoreJoinQParserPlugin extends QParserPlugin { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result - + ((fromField == null) ? 0 : fromField.hashCode()); - result = prime * result - + ((fromQuery == null) ? 0 : fromQuery.hashCode()); - result = prime * result - + ((scoreMode == null) ? 0 : scoreMode.hashCode()); - result = prime * result + ((toField == null) ? 0 : toField.hashCode()); + int result = classHash(); + result = prime * result + Objects.hashCode(fromField); + result = prime * result + Objects.hashCode(fromQuery); + result = prime * result + Objects.hashCode(scoreMode); + result = prime * result + Objects.hashCode(toField); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - SameCoreJoinQuery other = (SameCoreJoinQuery) obj; - if (fromField == null) { - if (other.fromField != null) return false; - } else if (!fromField.equals(other.fromField)) return false; - if (fromQuery == null) { - if (other.fromQuery != null) return false; - } else if (!fromQuery.equals(other.fromQuery)) return false; - if (scoreMode != other.scoreMode) return false; - if (toField == null) { - if (other.toField != null) return false; - } else if (!toField.equals(other.toField)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(SameCoreJoinQuery other) { + return Objects.equals(fromField, other.fromField) && + Objects.equals(fromQuery, other.fromQuery) && + Objects.equals(scoreMode, other.scoreMode) && + Objects.equals(toField, other.toField); } } diff --git a/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java b/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java index c0367296817..3d871616484 100644 --- a/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java +++ b/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java @@ -17,6 +17,7 @@ package org.apache.solr.update; import java.io.IOException; +import java.util.Objects; import java.util.Set; import org.apache.lucene.index.IndexReader; @@ -29,7 +30,6 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Weight; import org.apache.lucene.uninverting.UninvertingReader; -import org.apache.lucene.util.Bits; import org.apache.solr.schema.IndexSchema; /** @@ -99,24 +99,20 @@ final class DeleteByQueryWrapper extends Query { @Override public int hashCode() { final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((in == null) ? 0 : in.hashCode()); - result = prime * result + ((schema == null) ? 0 : schema.hashCode()); + int result = classHash(); + result = prime * result + Objects.hashCode(in); + result = prime * result + Objects.hashCode(schema); return result; } @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - if (getClass() != obj.getClass()) return false; - DeleteByQueryWrapper other = (DeleteByQueryWrapper) obj; - if (in == null) { - if (other.in != null) return false; - } else if (!in.equals(other.in)) return false; - if (schema == null) { - if (other.schema != null) return false; - } else if (!schema.equals(other.schema)) return false; - return true; + public boolean equals(Object other) { + return sameClassAs(other) && + equalsTo(getClass().cast(other)); + } + + private boolean equalsTo(DeleteByQueryWrapper other) { + return Objects.equals(in, other.in) && + Objects.equals(schema, other.schema); } } diff --git a/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java b/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java index ec1ec78b6e7..044723b82c9 100644 --- a/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java +++ b/solr/core/src/test/org/apache/solr/search/TestFilteredDocIdSet.java @@ -137,6 +137,16 @@ public class TestFilteredDocIdSet extends LuceneTestCase { public String toString(String field) { return "nullDocIdSetFilter"; } + + @Override + public boolean equals(Object other) { + return other == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } }; Query filtered = new BooleanQuery.Builder() @@ -183,10 +193,21 @@ public class TestFilteredDocIdSet extends LuceneTestCase { } }; } + @Override public String toString(String field) { return "nullDocIdSetFilter"; } + + @Override + public boolean equals(Object other) { + return other == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } }; Query filtered = new BooleanQuery.Builder() diff --git a/solr/core/src/test/org/apache/solr/search/TestQueryWrapperFilter.java b/solr/core/src/test/org/apache/solr/search/TestQueryWrapperFilter.java index eb911c41d36..233e1a18188 100644 --- a/solr/core/src/test/org/apache/solr/search/TestQueryWrapperFilter.java +++ b/solr/core/src/test/org/apache/solr/search/TestQueryWrapperFilter.java @@ -18,6 +18,7 @@ package org.apache.solr.search; import java.io.IOException; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import org.apache.lucene.document.Document; @@ -49,8 +50,7 @@ public class TestQueryWrapperFilter extends LuceneTestCase { // a filter for which other queries don't have special rewrite rules private static class FilterWrapper extends Filter { - - private final Filter in; + final Filter in; FilterWrapper(Filter in) { this.in = in; @@ -67,16 +67,14 @@ public class TestQueryWrapperFilter extends LuceneTestCase { } @Override - public boolean equals(Object obj) { - if (super.equals(obj) == false) { - return false; - } - return in.equals(((FilterWrapper) obj).in); + public boolean equals(Object other) { + return sameClassAs(other) && + Objects.equals(in, getClass().cast(other).in); } @Override public int hashCode() { - return 31 * super.hashCode() + in.hashCode(); + return 31 * classHash() + in.hashCode(); } } diff --git a/solr/core/src/test/org/apache/solr/search/TestSort.java b/solr/core/src/test/org/apache/solr/search/TestSort.java index d6c2435fa44..e874c373e2d 100644 --- a/solr/core/src/test/org/apache/solr/search/TestSort.java +++ b/solr/core/src/test/org/apache/solr/search/TestSort.java @@ -245,6 +245,16 @@ public class TestSort extends SolrTestCaseJ4 { public String toString(String field) { return "TestSortFilter"; } + + @Override + public boolean equals(Object other) { + return other == this; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } }; int top = r.nextInt((ndocs>>3)+1)+1;