Skip to content

Commit 0b05c38

Browse files
committed
HSEARCH-5160 Address Lucene 10 changes
1 parent 72b16f3 commit 0b05c38

File tree

39 files changed

+434
-62
lines changed

39 files changed

+434
-62
lines changed

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/codec/impl/HibernateSearchLuceneCodec.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
import org.apache.lucene.codecs.Codec;
1414
import org.apache.lucene.codecs.FilterCodec;
1515
import org.apache.lucene.codecs.KnnVectorsFormat;
16-
import org.apache.lucene.codecs.lucene912.Lucene912Codec;
16+
import org.apache.lucene.codecs.lucene100.Lucene100Codec;
1717
import org.apache.lucene.codecs.perfield.PerFieldKnnVectorsFormat;
1818

1919
public class HibernateSearchLuceneCodec extends FilterCodec {
2020

21-
public static final Codec DEFAULT_CODEC = new Lucene912Codec();
21+
public static final Codec DEFAULT_CODEC = new Lucene100Codec();
2222

2323
private final KnnVectorsFormat knnVectorsFormat;
2424

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/facet/impl/LongMultiValueFacetCounts.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ private void count(LongMultiValuesSource valueSource, List<FacetsCollector.Match
4949
LongProcedure incrementCountForDocumentId = this::increment;
5050

5151
for ( FacetsCollector.MatchingDocs hits : matchingDocs ) {
52-
LongMultiValues fv = valueSource.getValues( hits.context );
52+
LongMultiValues fv = valueSource.getValues( hits.context() );
5353

54-
DocIdSetIterator docs = hits.bits.iterator();
54+
DocIdSetIterator docs = hits.bits().iterator();
5555
for ( int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = docs.nextDoc() ) {
5656
if ( fv.advanceExact( doc ) ) {
5757
totCount++;

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/facet/impl/LongMultiValueRangeFacetCounts.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,17 @@ private void count(LongMultiValuesSource valueSource, List<FacetsCollector.Match
5353

5454
int missingCount = 0;
5555
for ( FacetsCollector.MatchingDocs hits : matchingDocs ) {
56-
LongMultiValues fv = valueSource.getValues( hits.context );
56+
LongMultiValues fv = valueSource.getValues( hits.context() );
5757

58-
totCount += hits.totalHits;
58+
totCount += hits.totalHits();
5959
final DocIdSetIterator fastMatchDocs;
6060
if ( fastMatchQuery != null ) {
61-
final IndexReaderContext topLevelContext = ReaderUtil.getTopLevelContext( hits.context );
61+
final IndexReaderContext topLevelContext = ReaderUtil.getTopLevelContext( hits.context() );
6262
final IndexSearcher searcher = new IndexSearcher( topLevelContext );
6363
searcher.setQueryCache( null );
6464
final Weight fastMatchWeight =
6565
searcher.createWeight( searcher.rewrite( fastMatchQuery ), ScoreMode.COMPLETE_NO_SCORES, 1 );
66-
Scorer s = fastMatchWeight.scorer( hits.context );
66+
Scorer s = fastMatchWeight.scorer( hits.context() );
6767
if ( s == null ) {
6868
continue;
6969
}
@@ -73,7 +73,7 @@ private void count(LongMultiValuesSource valueSource, List<FacetsCollector.Match
7373
fastMatchDocs = null;
7474
}
7575

76-
DocIdSetIterator docs = hits.bits.iterator();
76+
DocIdSetIterator docs = hits.bits().iterator();
7777
for ( int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; ) {
7878
if ( fastMatchDocs != null ) {
7979
int fastMatchDoc = fastMatchDocs.docID();

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/facet/impl/TextMultiValueFacetCounts.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.lucene.search.DocIdSetIterator;
3030
import org.apache.lucene.util.BytesRef;
3131
import org.apache.lucene.util.LongValues;
32+
import org.apache.lucene.util.PriorityQueue;
3233

3334
/**
3435
* Copied with some changes from {@code org.apache.lucene.facet.sortedset.SortedSetDocValuesFacetCounts}
@@ -84,33 +85,33 @@ private FacetResult getTopChildrenSortByCount(int topN) throws IOException {
8485
topN = ordCount;
8586
}
8687

87-
TopOrdAndIntQueue q = null;
88+
HibernateSearchTopOrdAndIntQueue q = null;
8889

8990
int bottomCount = 0;
9091

9192
int totCount = 0;
9293
int childCount = 0;
9394

94-
TopOrdAndIntQueue.OrdAndValue reuse = null;
95+
TopOrdAndIntQueue.OrdAndInt reuse = null;
9596

9697
for ( int ord = 0; ord < ordCount; ord++ ) {
9798
if ( counts[ord] > 0 ) {
9899
totCount += counts[ord];
99100
childCount++;
100101
if ( counts[ord] > bottomCount ) {
101102
if ( reuse == null ) {
102-
reuse = new TopOrdAndIntQueue.OrdAndValue();
103+
reuse = new TopOrdAndIntQueue.OrdAndInt();
103104
}
104105
reuse.ord = ord;
105106
reuse.value = counts[ord];
106107
if ( q == null ) {
107108
// Lazy init, so we don't create this for the
108109
// sparse case unnecessarily
109-
q = new TopOrdAndIntQueue( topN );
110+
q = new HibernateSearchTopOrdAndIntQueue( topN );
110111
}
111112
reuse = q.insertWithOverflow( reuse );
112113
if ( q.size() == topN ) {
113-
bottomCount = q.top().value;
114+
bottomCount = ( q.top() ).value;
114115
}
115116
}
116117
}
@@ -122,7 +123,7 @@ private FacetResult getTopChildrenSortByCount(int topN) throws IOException {
122123

123124
LabelAndValue[] labelValues = new LabelAndValue[q.size()];
124125
for ( int i = labelValues.length - 1; i >= 0; i-- ) {
125-
TopOrdAndIntQueue.OrdAndValue ordAndValue = q.pop();
126+
TopOrdAndIntQueue.OrdAndInt ordAndValue = q.pop();
126127
final BytesRef term = dv.lookupOrd( ordAndValue.ord );
127128
labelValues[i] = new LabelAndValue( term.utf8ToString(), ordAndValue.value );
128129
}
@@ -138,7 +139,7 @@ private void countOneSegment(OrdinalMap ordinalMap, TextMultiValues segValues, i
138139
}
139140
IntHashSet uniqueOrdinalsForDocument = new IntHashSet();
140141

141-
DocIdSetIterator docs = hits.bits.iterator();
142+
DocIdSetIterator docs = hits.bits().iterator();
142143

143144
// TODO: yet another option is to count all segs
144145
// first, only in seg-ord space, and then do a
@@ -154,7 +155,7 @@ private void countOneSegment(OrdinalMap ordinalMap, TextMultiValues segValues, i
154155

155156
int numSegOrds = (int) segValues.getValueCount();
156157

157-
if ( hits.totalHits < numSegOrds / 10 ) {
158+
if ( hits.totalHits() < numSegOrds / 10 ) {
158159
IntProcedure incrementCountForOrdinal = ord -> counts[ord]++;
159160
// Remap every ord to global ord as we iterate:
160161
for ( int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = docs.nextDoc() ) {
@@ -236,12 +237,12 @@ private void count(IndexReader reader, TextMultiValuesSource valuesSource, List<
236237
// the top-level reader passed to the
237238
// SortedSetDocValuesReaderState, else cryptic
238239
// AIOOBE can happen:
239-
if ( ReaderUtil.getTopLevelContext( hits.context ).reader() != reader ) {
240+
if ( ReaderUtil.getTopLevelContext( hits.context() ).reader() != reader ) {
240241
throw new IllegalStateException(
241242
"the SortedSetDocValuesReaderState provided to this class does not match the reader being searched; you must create a new SortedSetDocValuesReaderState every time you open a new IndexReader" );
242243
}
243244

244-
countOneSegment( ordinalMap, valuesSource.getValues( hits.context ), hits.context.ord, hits );
245+
countOneSegment( ordinalMap, valuesSource.getValues( hits.context() ), hits.context().ord, hits );
245246
}
246247
}
247248

@@ -255,4 +256,20 @@ public List<FacetResult> getAllDims(int topN) throws IOException {
255256
return Collections.singletonList( getTopChildren( topN, field ) );
256257
}
257258

259+
/**
260+
* While there is a `TopOrdAndIntQueue` in Lucene, unfortunately it works with OrdAndValue objects (in API).
261+
* And there's no access to the value, leading to casting any type value has to be accessed. Hence, this impl:
262+
*/
263+
private static class HibernateSearchTopOrdAndIntQueue extends PriorityQueue<TopOrdAndIntQueue.OrdAndInt> {
264+
265+
public HibernateSearchTopOrdAndIntQueue(int maxSize) {
266+
super( maxSize );
267+
}
268+
269+
@Override
270+
protected boolean lessThan(TopOrdAndIntQueue.OrdAndInt a, TopOrdAndIntQueue.OrdAndInt b) {
271+
return a.lessThan( b );
272+
}
273+
}
274+
258275
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.search.backend.lucene.lowlevel.query.impl;
6+
7+
import java.io.IOException;
8+
9+
import org.apache.lucene.search.ConstantScoreScorer;
10+
import org.apache.lucene.search.DocIdSetIterator;
11+
import org.apache.lucene.search.ScoreMode;
12+
import org.apache.lucene.search.Scorer;
13+
import org.apache.lucene.search.ScorerSupplier;
14+
15+
class ConstantScorerSupplier extends ScorerSupplier {
16+
private final float score;
17+
private final ScoreMode scoreMode;
18+
private final DocIdSetIterator matchingDocs;
19+
20+
public ConstantScorerSupplier(float score, ScoreMode scoreMode, DocIdSetIterator matchingDocs) {
21+
this.score = score;
22+
this.scoreMode = scoreMode;
23+
this.matchingDocs = matchingDocs;
24+
}
25+
26+
@Override
27+
public Scorer get(long leadCost) throws IOException {
28+
return new ConstantScoreScorer( score, scoreMode, matchingDocs );
29+
}
30+
31+
@Override
32+
public long cost() {
33+
return matchingDocs.cost();
34+
}
35+
}

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/query/impl/ExplicitDocIdsQuery.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
import java.util.Arrays;
88

99
import org.apache.lucene.index.LeafReaderContext;
10-
import org.apache.lucene.search.ConstantScoreScorer;
1110
import org.apache.lucene.search.ConstantScoreWeight;
1211
import org.apache.lucene.search.DocIdSetIterator;
1312
import org.apache.lucene.search.IndexSearcher;
1413
import org.apache.lucene.search.Query;
1514
import org.apache.lucene.search.QueryVisitor;
1615
import org.apache.lucene.search.ScoreDoc;
1716
import org.apache.lucene.search.ScoreMode;
18-
import org.apache.lucene.search.Scorer;
17+
import org.apache.lucene.search.ScorerSupplier;
1918
import org.apache.lucene.search.Weight;
2019

2120
public final class ExplicitDocIdsQuery extends Query {
@@ -56,15 +55,16 @@ public int hashCode() {
5655
@Override
5756
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) {
5857
return new ConstantScoreWeight( this, 1.0f ) {
58+
5959
@Override
60-
public Scorer scorer(LeafReaderContext context) {
60+
public ScorerSupplier scorerSupplier(LeafReaderContext context) {
6161
DocIdSetIterator matchingDocs = ExplicitDocIdSetIterator.of(
6262
sortedDocIds, context.docBase, context.reader().maxDoc()
6363
);
6464
if ( matchingDocs == null ) {
6565
return null; // Skip this leaf
6666
}
67-
return new ConstantScoreScorer( this, this.score(), scoreMode, matchingDocs );
67+
return new ConstantScorerSupplier( this.score(), scoreMode, matchingDocs );
6868
}
6969

7070
@Override

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/query/impl/MappedTypeNameQuery.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44
*/
55
package org.hibernate.search.backend.lucene.lowlevel.query.impl;
66

7+
import java.io.IOException;
8+
79
import org.hibernate.search.backend.lucene.lowlevel.reader.impl.IndexReaderMetadataResolver;
810

911
import org.apache.lucene.index.LeafReaderContext;
10-
import org.apache.lucene.search.ConstantScoreScorer;
1112
import org.apache.lucene.search.ConstantScoreWeight;
1213
import org.apache.lucene.search.DocIdSetIterator;
1314
import org.apache.lucene.search.IndexSearcher;
1415
import org.apache.lucene.search.Query;
1516
import org.apache.lucene.search.QueryVisitor;
1617
import org.apache.lucene.search.ScoreMode;
17-
import org.apache.lucene.search.Scorer;
18+
import org.apache.lucene.search.ScorerSupplier;
1819
import org.apache.lucene.search.Weight;
1920

2021
public final class MappedTypeNameQuery extends Query {
@@ -51,8 +52,9 @@ public int hashCode() {
5152
@Override
5253
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) {
5354
return new ConstantScoreWeight( this, 1.0f ) {
55+
5456
@Override
55-
public Scorer scorer(LeafReaderContext context) {
57+
public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOException {
5658
String leafMappedTypeName = metadataResolver.resolveMappedTypeName( context );
5759
DocIdSetIterator matchingDocs;
5860
if ( mappedTypeName.equals( leafMappedTypeName ) ) {
@@ -61,7 +63,8 @@ public Scorer scorer(LeafReaderContext context) {
6163
else {
6264
matchingDocs = DocIdSetIterator.empty();
6365
}
64-
return new ConstantScoreScorer( this, this.score(), scoreMode, matchingDocs );
66+
67+
return new ConstantScorerSupplier( this.score(), scoreMode, matchingDocs );
6568
}
6669

6770
@Override

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/lowlevel/query/impl/VectorSimilarityFilterQuery.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.apache.lucene.search.QueryVisitor;
1919
import org.apache.lucene.search.ScoreMode;
2020
import org.apache.lucene.search.Scorer;
21+
import org.apache.lucene.search.ScorerSupplier;
2122
import org.apache.lucene.search.TwoPhaseIterator;
2223
import org.apache.lucene.search.Weight;
2324

@@ -104,12 +105,37 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
104105
}
105106

106107
@Override
107-
public Scorer scorer(LeafReaderContext context) throws IOException {
108-
Scorer scorer = super.scorer( context );
108+
public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOException {
109+
ScorerSupplier scorerSupplier = super.scorerSupplier( context );
110+
if ( scorerSupplier == null ) {
111+
return null;
112+
}
113+
return new MinScoreScorerSupplier( scorerSupplier, similarityAsScore );
114+
}
115+
}
116+
117+
private static class MinScoreScorerSupplier extends ScorerSupplier {
118+
119+
private final ScorerSupplier delegate;
120+
private final float similarityAsScore;
121+
122+
private MinScoreScorerSupplier(ScorerSupplier delegate, float similarityAsScore) {
123+
this.delegate = delegate;
124+
this.similarityAsScore = similarityAsScore;
125+
}
126+
127+
@Override
128+
public Scorer get(long leadCost) throws IOException {
129+
Scorer scorer = delegate.get( leadCost );
109130
if ( scorer == null ) {
110131
return null;
111132
}
112-
return new MinScoreScorer( this, scorer, similarityAsScore );
133+
return new MinScoreScorer( scorer, similarityAsScore );
134+
}
135+
136+
@Override
137+
public long cost() {
138+
return delegate.cost();
113139
}
114140
}
115141

@@ -119,8 +145,7 @@ private static class MinScoreScorer extends Scorer {
119145
private final float minScore;
120146
private float curScore;
121147

122-
MinScoreScorer(Weight weight, Scorer scorer, float minScore) {
123-
super( weight );
148+
MinScoreScorer(Scorer scorer, float minScore) {
124149
this.in = scorer;
125150
this.minScore = minScore;
126151
}

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/search/extraction/impl/ExtractionRequirements.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ public LuceneCollectors createCollectors(IndexSearcher indexSearcher, Query orig
104104
// but if it's not there and not all docs are matched, we need a separate collector.
105105
// Note that adding this collector can have a significant cost in some situations
106106
// (e.g. for queries matching many hits), so we only add it if it's really necessary.
107-
TotalHitCountCollectorManager totalHitCountCollectorManager = new TotalHitCountCollectorManager();
107+
TotalHitCountCollectorManager totalHitCountCollectorManager =
108+
new TotalHitCountCollectorManager( indexSearcher.getSlices() );
108109
collectorsForAllMatchingDocsBuilder.add( LuceneCollectors.TOTAL_HIT_COUNT_KEY, totalHitCountCollectorManager );
109110
}
110111
collectorsForAllMatchingDocsBuilder.addAll( requiredCollectorForAllMatchingDocsFactories );

backend/lucene10/src/main/java/org/hibernate/search/backend/lucene/search/extraction/impl/LuceneCollectors.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ private void processCollectedMatchingDocs() throws IOException {
119119
}
120120

121121
if ( resultTotal == null ) {
122-
boolean exact = TotalHits.Relation.EQUAL_TO.equals( topDocs.totalHits.relation )
122+
boolean exact = TotalHits.Relation.EQUAL_TO.equals( topDocs.totalHits.relation() )
123123
&& !timeoutManager.isTimedOut();
124-
resultTotal = SimpleSearchResultTotal.of( topDocs.totalHits.value, exact );
124+
resultTotal = SimpleSearchResultTotal.of( topDocs.totalHits.value(), exact );
125125
}
126126
else if ( resultTotal.isHitCountExact() ) {
127127
// Update the total hit count of the topDocs, which might not be precise enough,

0 commit comments

Comments
 (0)