Search: Do not force the post-filter to be loaded into a BitSet.

Close #8488
This commit is contained in:
Adrien Grand 2014-11-14 17:57:13 +01:00
parent a2c93304f8
commit e70b4d835b
1 changed files with 58 additions and 21 deletions

View File

@ -28,14 +28,11 @@ import java.io.IOException;
/**
*
*/
public class FilteredCollector extends SimpleCollector implements XCollector {
public class FilteredCollector implements XCollector {
private final Collector collector;
private final Filter filter;
private Bits docSet;
private LeafCollector leafCollector;
public FilteredCollector(Collector collector, Filter filter) {
this.collector = collector;
this.filter = filter;
@ -49,25 +46,65 @@ public class FilteredCollector extends SimpleCollector implements XCollector {
}
@Override
public void setScorer(Scorer scorer) throws IOException {
leafCollector.setScorer(scorer);
}
public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
final DocIdSet set = filter.getDocIdSet(context, null);
final LeafCollector in = collector.getLeafCollector(context);
final Bits bits = set == null ? null : set.bits();
@Override
public void collect(int doc) throws IOException {
if (docSet.get(doc)) {
leafCollector.collect(doc);
if (bits != null) {
// the filter supports random-access
return new FilterLeafCollector(in) {
public void collect(int doc) throws IOException {
if (bits.get(doc)) {
in.collect(doc);
}
}
};
}
// No random-access support, use the iterator and force in-order scoring
final DocIdSetIterator iterator;
if (DocIdSets.isEmpty(set)) {
iterator = null;
} else {
// DIS.iterator might still return null here
iterator = set.iterator();
}
if (iterator == null) {
return new FilterLeafCollector(in) {
@Override
public void collect(int doc) throws IOException {
// no-op
}
@Override
public boolean acceptsDocsOutOfOrder() {
return true;
}
};
}
return new FilterLeafCollector(in) {
@Override
public void collect(int doc) throws IOException {
final int itDoc = iterator.docID();
if (itDoc > doc) {
return;
} else if (itDoc < doc) {
if (iterator.advance(doc) == doc) {
in.collect(doc);
}
} else {
in.collect(doc);
}
}
@Override
public boolean acceptsDocsOutOfOrder() {
// we only support iterating in order because the iterator can only advance
return false;
}
};
}
@Override
public void doSetNextReader(LeafReaderContext context) throws IOException {
leafCollector = collector.getLeafCollector(context);
docSet = DocIdSets.toSafeBits(context.reader(), filter.getDocIdSet(context, null));
}
@Override
public boolean acceptsDocsOutOfOrder() {
return leafCollector.acceptsDocsOutOfOrder();
}
}