CavalliumDBEngine/src/main/java/it/cavallium/dbengine/lucene/collector/ScoringShardsCollectorManag...

133 lines
4.3 KiB
Java
Raw Normal View History

package it.cavallium.dbengine.lucene.collector;
2021-07-08 18:54:53 +02:00
import static it.cavallium.dbengine.lucene.searcher.CurrentPageInfo.TIE_BREAKER;
import it.cavallium.dbengine.lucene.LuceneUtils;
import java.io.IOException;
import java.util.Collection;
2021-10-15 22:03:53 +02:00
import java.util.List;
import java.util.Objects;
2021-07-08 18:54:53 +02:00
import org.apache.lucene.search.CollectorManager;
import org.apache.lucene.search.FieldDoc;
2021-10-15 22:03:53 +02:00
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
2021-07-08 18:54:53 +02:00
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopFieldCollector;
import org.apache.lucene.search.TopFieldDocs;
import org.jetbrains.annotations.Nullable;
import reactor.core.scheduler.Schedulers;
2021-07-08 18:54:53 +02:00
public class ScoringShardsCollectorManager implements CollectorManager<TopFieldCollector, TopDocs> {
2021-10-15 22:03:53 +02:00
private final Query query;
@Nullable
2021-07-08 18:54:53 +02:00
private final Sort sort;
private final int numHits;
private final FieldDoc after;
private final int totalHitsThreshold;
private final @Nullable Integer startN;
private final @Nullable Integer topN;
private final CollectorManager<TopFieldCollector, TopFieldDocs> sharedCollectorManager;
2021-10-15 22:03:53 +02:00
private List<IndexSearcher> indexSearchers;
2021-07-08 18:54:53 +02:00
2021-10-15 22:03:53 +02:00
public ScoringShardsCollectorManager(Query query,
@Nullable final Sort sort,
2021-07-08 18:54:53 +02:00
final int numHits,
final FieldDoc after,
final int totalHitsThreshold,
int startN,
int topN) {
2021-10-15 22:03:53 +02:00
this(query, sort, numHits, after, totalHitsThreshold, (Integer) startN, (Integer) topN);
2021-07-08 18:54:53 +02:00
}
2021-10-15 22:03:53 +02:00
public ScoringShardsCollectorManager(Query query,
@Nullable final Sort sort,
2021-09-22 11:03:39 +02:00
final int numHits,
final FieldDoc after,
final int totalHitsThreshold,
int startN) {
2021-10-15 22:03:53 +02:00
this(query, sort, numHits, after, totalHitsThreshold, (Integer) startN, (Integer) 2147483630);
2021-09-22 11:03:39 +02:00
}
2021-10-15 22:03:53 +02:00
public ScoringShardsCollectorManager(Query query,
@Nullable final Sort sort,
2021-07-08 18:54:53 +02:00
final int numHits,
final FieldDoc after,
final int totalHitsThreshold) {
2021-10-15 22:03:53 +02:00
this(query, sort, numHits, after, totalHitsThreshold, null, null);
2021-07-08 18:54:53 +02:00
}
2021-10-15 22:03:53 +02:00
private ScoringShardsCollectorManager(Query query,
@Nullable final Sort sort,
2021-07-08 18:54:53 +02:00
final int numHits,
final FieldDoc after,
final int totalHitsThreshold,
@Nullable Integer startN,
@Nullable Integer topN) {
2021-10-15 22:03:53 +02:00
this.query = query;
2021-07-08 18:54:53 +02:00
this.sort = sort;
this.numHits = numHits;
this.after = after;
this.totalHitsThreshold = totalHitsThreshold;
this.startN = startN;
2021-09-22 11:03:39 +02:00
if (topN != null && startN != null && (long) topN + (long) startN > 2147483630) {
this.topN = 2147483630 - startN;
} else if (topN != null && topN > 2147483630) {
this.topN = 2147483630;
} else {
this.topN = topN;
}
this.sharedCollectorManager = TopFieldCollector.createSharedManager(sort == null ? Sort.RELEVANCE : sort, numHits, after, totalHitsThreshold);
2021-07-08 18:54:53 +02:00
}
@Override
public TopFieldCollector newCollector() throws IOException {
return sharedCollectorManager.newCollector();
}
2021-10-15 22:03:53 +02:00
public void setIndexSearchers(List<IndexSearcher> indexSearcher) {
this.indexSearchers = indexSearcher;
}
2021-07-08 18:54:53 +02:00
@Override
public TopDocs reduce(Collection<TopFieldCollector> collectors) throws IOException {
if (Schedulers.isInNonBlockingThread()) {
throw new UnsupportedOperationException("Called reduce in a nonblocking thread");
}
2021-07-08 18:54:53 +02:00
TopDocs result;
if (sort != null) {
TopFieldDocs[] topDocs = new TopFieldDocs[collectors.size()];
var i = 0;
for (TopFieldCollector collector : collectors) {
topDocs[i] = collector.topDocs();
2021-10-15 22:03:53 +02:00
// Populate scores of topfieldcollector. By default it doesn't popupate the scores
if (topDocs[i].scoreDocs.length > 0 && Float.isNaN(topDocs[i].scoreDocs[0].score) && sort.needsScores()) {
Objects.requireNonNull(indexSearchers, "You must call setIndexSearchers before calling reduce!");
TopFieldCollector.populateScores(topDocs[i].scoreDocs, indexSearchers.get(i), query);
}
2021-07-08 18:54:53 +02:00
for (ScoreDoc scoreDoc : topDocs[i].scoreDocs) {
scoreDoc.shardIndex = i;
}
i++;
}
2021-09-09 23:00:16 +02:00
result = LuceneUtils.mergeTopDocs(sort, startN, topN, topDocs, TIE_BREAKER);
2021-07-08 18:54:53 +02:00
} else {
TopDocs[] topDocs = new TopDocs[collectors.size()];
var i = 0;
for (TopFieldCollector collector : collectors) {
topDocs[i] = collector.topDocs();
for (ScoreDoc scoreDoc : topDocs[i].scoreDocs) {
scoreDoc.shardIndex = i;
}
i++;
}
2021-09-09 23:00:16 +02:00
result = LuceneUtils.mergeTopDocs(null, startN, topN, topDocs, TIE_BREAKER);
2021-07-08 18:54:53 +02:00
}
return result;
}
}