diff --git a/lucene/core/src/java/org/apache/lucene/search/TotalHits.java b/lucene/core/src/java/org/apache/lucene/search/TotalHits.java index 1b852a9c99d..7a0412f743b 100644 --- a/lucene/core/src/java/org/apache/lucene/search/TotalHits.java +++ b/lucene/core/src/java/org/apache/lucene/search/TotalHits.java @@ -63,6 +63,23 @@ public final class TotalHits { this.relation = Objects.requireNonNull(relation); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TotalHits totalHits = (TotalHits) o; + return value == totalHits.value && relation == totalHits.relation; + } + + @Override + public int hashCode() { + return Objects.hash(value, relation); + } + @Override public String toString() { return value + (relation == Relation.EQUAL_TO ? "" : "+") + " hits"; diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java index 1768254f68a..f8b8c0af25f 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java @@ -92,8 +92,7 @@ public class TestSynonymQuery extends LuceneTestCase { searcher.search(query, collector); TopDocs topDocs = collector.topDocs(); if (topDocs.totalHits.value < totalHitsThreshold) { - assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); - assertEquals(11, topDocs.totalHits.value); + assertEquals(new TotalHits(11, TotalHits.Relation.EQUAL_TO), topDocs.totalHits); } else { assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java index 809d83580dc..0d469f7397e 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java @@ -315,7 +315,7 @@ public class TestTopDocsCollector extends LuceneTestCase { TopDocs topDocs = collector.topDocs(); assertEquals(4, topDocs.totalHits.value); assertEquals(totalHitsThreshold < 4, scorer.minCompetitiveScore != null); - assertEquals(totalHitsThreshold < 4 ? TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO : TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); + assertEquals(new TotalHits(4, totalHitsThreshold < 4 ? TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO : TotalHits.Relation.EQUAL_TO), topDocs.totalHits); } reader.close(); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java index 43db2f23d70..db8b10503cb 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java @@ -385,20 +385,16 @@ public class TestTopDocsMerge extends LuceneTestCase { TopDocs topDocs4 = new TopDocs(new TotalHits(3, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), new ScoreDoc[] { new ScoreDoc(42, 2f) }); TopDocs merged1 = TopDocs.merge(1, new TopDocs[] {topDocs1, topDocs2}); - assertEquals(3, merged1.totalHits.value); - assertEquals(TotalHits.Relation.EQUAL_TO, merged1.totalHits.relation); + assertEquals(new TotalHits(3, TotalHits.Relation.EQUAL_TO), merged1.totalHits); TopDocs merged2 = TopDocs.merge(1, new TopDocs[] {topDocs1, topDocs3}); - assertEquals(3, merged2.totalHits.value); - assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, merged2.totalHits.relation); + assertEquals(new TotalHits(3, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), merged2.totalHits); TopDocs merged3 = TopDocs.merge(1, new TopDocs[] {topDocs3, topDocs4}); - assertEquals(4, merged3.totalHits.value); - assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, merged3.totalHits.relation); + assertEquals(new TotalHits(4, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), merged3.totalHits); TopDocs merged4 = TopDocs.merge(1, new TopDocs[] {topDocs4, topDocs2}); - assertEquals(4, merged4.totalHits.value); - assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, merged4.totalHits.relation); + assertEquals(new TotalHits(4, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), merged4.totalHits); } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java index 046990bc8a1..5ae0c1cfe2a 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java @@ -172,8 +172,7 @@ public class TestTopFieldCollector extends LuceneTestCase { if (totalHitsThreshold < 3) { expectThrows(CollectionTerminatedException.class, () -> leafCollector2.collect(1)); TopDocs topDocs = collector.topDocs(); - assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); - assertEquals(3, topDocs.totalHits.value); + assertEquals(new TotalHits(3, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), topDocs.totalHits); continue; } else { leafCollector2.collect(1); @@ -184,16 +183,14 @@ public class TestTopFieldCollector extends LuceneTestCase { if (totalHitsThreshold == 3) { expectThrows(CollectionTerminatedException.class, () -> leafCollector2.collect(1)); TopDocs topDocs = collector.topDocs(); - assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); - assertEquals(4, topDocs.totalHits.value); + assertEquals(new TotalHits(4, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), topDocs.totalHits); continue; } else { leafCollector2.collect(1); } TopDocs topDocs = collector.topDocs(); - assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); - assertEquals(4, topDocs.totalHits.value); + assertEquals(new TotalHits(4, TotalHits.Relation.EQUAL_TO), topDocs.totalHits); } } @@ -324,9 +321,8 @@ public class TestTopFieldCollector extends LuceneTestCase { leafCollector.collect(1); TopDocs topDocs = collector.topDocs(); - assertEquals(4, topDocs.totalHits.value); assertEquals(totalHitsThreshold < 4, scorer.minCompetitiveScore != null); - assertEquals(totalHitsThreshold < 4 ? TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO : TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); + assertEquals(new TotalHits(4, totalHitsThreshold < 4 ? TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO : TotalHits.Relation.EQUAL_TO), topDocs.totalHits); } reader.close(); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTotalHits.java b/lucene/core/src/test/org/apache/lucene/search/TestTotalHits.java new file mode 100644 index 00000000000..f975f4114e3 --- /dev/null +++ b/lucene/core/src/test/org/apache/lucene/search/TestTotalHits.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.search; + +import com.carrotsearch.randomizedtesting.RandomizedTest; +import org.apache.lucene.util.LuceneTestCase; + +public class TestTotalHits extends LuceneTestCase { + + public void testEqualsAndHashcode() { + TotalHits totalHits1 = randomTotalHits(); + assertFalse(totalHits1.equals(null)); + assertFalse(totalHits1.equals(totalHits1.value)); + assertEquals(totalHits1, totalHits1); + assertEquals(totalHits1.hashCode(), totalHits1.hashCode()); + + TotalHits totalHits2 = new TotalHits(totalHits1.value, totalHits1.relation); + assertEquals(totalHits1, totalHits2); + assertEquals(totalHits2, totalHits1); + assertEquals(totalHits1.hashCode(), totalHits2.hashCode()); + + TotalHits totalHits4 = randomTotalHits(); + if (totalHits4.value == totalHits1.value && totalHits4.relation == totalHits1.relation) { + assertEquals(totalHits1, totalHits4); + assertEquals(totalHits2, totalHits4); + assertEquals(totalHits1.hashCode(), totalHits4.hashCode()); + assertEquals(totalHits2.hashCode(), totalHits4.hashCode()); + } else { + assertNotEquals(totalHits1, totalHits4); + assertNotEquals(totalHits2, totalHits4); + assertNotEquals(totalHits1.hashCode(), totalHits4.hashCode()); + assertNotEquals(totalHits2.hashCode(), totalHits4.hashCode()); + } + } + + private static TotalHits randomTotalHits() { + long value = RandomizedTest.randomLongBetween(0, Long.MAX_VALUE); + TotalHits.Relation relation = RandomizedTest.randomFrom(TotalHits.Relation.values()); + return new TotalHits(value, relation); + } +} diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestBM25FQuery.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestBM25FQuery.java index 1dce7da363f..4158dee80b1 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/search/TestBM25FQuery.java +++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestBM25FQuery.java @@ -99,8 +99,7 @@ public class TestBM25FQuery extends LuceneTestCase { TopScoreDocCollector collector = TopScoreDocCollector.create(Math.min(reader.numDocs(), Integer.MAX_VALUE), null, Integer.MAX_VALUE); searcher.search(query, collector); TopDocs topDocs = collector.topDocs(); - assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); - assertEquals(11, topDocs.totalHits.value); + assertEquals(new TotalHits(11, TotalHits.Relation.EQUAL_TO), topDocs.totalHits); // All docs must have the same score for (int i = 0; i < topDocs.scoreDocs.length; ++i) { assertEquals(topDocs.scoreDocs[0].score, topDocs.scoreDocs[i].score, 0.0f);