2021-10-13 00:23:56 +02:00
|
|
|
package it.cavallium.dbengine.lucene.collector;
|
2021-07-26 19:21:17 +02:00
|
|
|
|
|
|
|
import static it.cavallium.dbengine.lucene.searcher.PaginationInfo.ALLOW_UNSCORED_PAGINATION_MODE;
|
|
|
|
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntList;
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntLists;
|
|
|
|
import org.apache.lucene.index.LeafReaderContext;
|
|
|
|
import org.apache.lucene.search.LeafCollector;
|
|
|
|
import org.apache.lucene.search.Scorable;
|
|
|
|
import org.apache.lucene.search.ScoreDoc;
|
|
|
|
import org.apache.lucene.search.ScoreMode;
|
|
|
|
|
|
|
|
import org.apache.lucene.search.SimpleCollector;
|
|
|
|
import org.apache.lucene.search.TopDocs;
|
|
|
|
import org.apache.lucene.search.TopDocsCollector;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
|
|
|
|
public class UnscoredCollector extends TopDocsCollector<ScoreDoc> implements LeafCollector {
|
|
|
|
private final IntArrayList docIds = new IntArrayList();
|
|
|
|
private final int limit;
|
|
|
|
private LeafReaderContext currentLeafReaderContext;
|
|
|
|
|
2021-07-27 19:34:51 +02:00
|
|
|
public UnscoredCollector(int limit) {
|
2021-07-26 19:21:17 +02:00
|
|
|
super(null);
|
|
|
|
if (!ALLOW_UNSCORED_PAGINATION_MODE) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
if (limit <= 0) {
|
|
|
|
throw new IllegalArgumentException();
|
|
|
|
}
|
|
|
|
this.limit = limit;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setScorer(Scorable scorable) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void collect(int localDocId) {
|
|
|
|
totalHits++;
|
2021-07-27 19:34:51 +02:00
|
|
|
boolean canCollect = limit == -1 || docIds.size() < limit;
|
2021-07-26 19:21:17 +02:00
|
|
|
if (canCollect) {
|
|
|
|
int docId = currentLeafReaderContext.docBase + localDocId;
|
2021-07-27 19:34:51 +02:00
|
|
|
docIds.add(docId);
|
2021-07-26 19:21:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public LeafCollector getLeafCollector(LeafReaderContext leafReaderContext) {
|
|
|
|
this.currentLeafReaderContext = leafReaderContext;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public IntList unscoredDocs() {
|
|
|
|
return IntLists.unmodifiable(this.docIds);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ScoreMode scoreMode() {
|
|
|
|
return ScoreMode.COMPLETE_NO_SCORES;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected int topDocsSize() {
|
|
|
|
return Math.min(this.totalHits, this.docIds.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public TopDocs topDocs(int start, int howMany) {
|
|
|
|
int size = this.topDocsSize();
|
|
|
|
if (howMany < 0) {
|
|
|
|
throw new IllegalArgumentException("Number of hits requested must be greater than 0 but value was " + howMany);
|
|
|
|
} else if (start < 0) {
|
|
|
|
throw new IllegalArgumentException("Expected value of starting position is between 0 and " + size + ", got " + start);
|
|
|
|
} else if (start < size && howMany != 0) {
|
|
|
|
howMany = Math.min(size - start, howMany);
|
|
|
|
ScoreDoc[] results = new ScoreDoc[howMany];
|
|
|
|
|
|
|
|
this.populateResults(results, start, howMany);
|
|
|
|
return this.newTopDocs(results, start);
|
|
|
|
} else {
|
|
|
|
return this.newTopDocs((ScoreDoc[])null, start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TopDocs newTopDocs(ScoreDoc[] results, int start) {
|
|
|
|
return super.newTopDocs(results, start);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void populateResults(ScoreDoc[] results, int start, int howMany) {
|
|
|
|
int i = 0;
|
|
|
|
for (int docId : docIds.subList(start, start + howMany)) {
|
2021-10-15 22:03:53 +02:00
|
|
|
results[i] = new ScoreDoc(docId, Float.NaN);
|
2021-07-26 19:21:17 +02:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void populateResults(ScoreDoc[] results, int howMany) {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
}
|