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 Collector collector;
private final Filter filter; private final Filter filter;
private Bits docSet;
private LeafCollector leafCollector;
public FilteredCollector(Collector collector, Filter filter) { public FilteredCollector(Collector collector, Filter filter) {
this.collector = collector; this.collector = collector;
this.filter = filter; this.filter = filter;
@ -49,25 +46,65 @@ public class FilteredCollector extends SimpleCollector implements XCollector {
} }
@Override @Override
public void setScorer(Scorer scorer) throws IOException { public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {
leafCollector.setScorer(scorer); final DocIdSet set = filter.getDocIdSet(context, null);
} final LeafCollector in = collector.getLeafCollector(context);
final Bits bits = set == null ? null : set.bits();
@Override if (bits != null) {
public void collect(int doc) throws IOException { // the filter supports random-access
if (docSet.get(doc)) { return new FilterLeafCollector(in) {
leafCollector.collect(doc); 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();
}
} }