LUCENE-6038: Re-enable FieldValueFilter optimizations based on the way the docsWithField bits are implemented.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1636827 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrien Grand 2014-11-05 09:04:53 +00:00
parent 5b00b2e981
commit e0227b516c
2 changed files with 56 additions and 4 deletions

View File

@ -20,6 +20,8 @@ import java.io.IOException;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.Bits.MatchAllBits;
import org.apache.lucene.util.Bits.MatchNoBits;
@ -93,10 +95,10 @@ public class FieldValueFilter extends Filter {
if (docsWithField instanceof MatchNoBits) {
return null;
}
if (docsWithField instanceof DocIdSet) {
if (docsWithField instanceof BitSet) {
// UweSays: this is always the case for our current impl - but who knows
// :-)
return BitsFilteredDocIdSet.wrap((DocIdSet) docsWithField, acceptDocs);
return BitsFilteredDocIdSet.wrap(new BitDocIdSet((BitSet) docsWithField), acceptDocs);
}
return new DocValuesDocIdSet(context.reader().maxDoc(), acceptDocs) {
@Override

View File

@ -23,12 +23,20 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.SortedDocValuesField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.FilterLeafReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.SparseFixedBitSet;
/**
*
@ -77,8 +85,8 @@ public class TestFieldValueFilter extends LuceneTestCase {
}
IndexReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = newSearcher(reader);
TopDocs search = searcher.search(new TermQuery(new Term("all", "test")),
new FieldValueFilter("some"), docs);
Filter filter = new FieldValueFilter("some");
TopDocs search = searcher.search(new TermQuery(new Term("all", "test")), filter, docs);
assertEquals(search.totalHits, numDocsWithValue);
ScoreDoc[] scoreDocs = search.scoreDocs;
@ -90,6 +98,48 @@ public class TestFieldValueFilter extends LuceneTestCase {
directory.close();
}
public void testOptimizations() throws IOException {
Directory directory = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
newIndexWriterConfig(new MockAnalyzer(random())));
final int docs = atLeast(10);
buildIndex(writer, docs);
IndexReader reader = DirectoryReader.open(directory);
LeafReader leafReader = reader.leaves().get(0).reader();
FilterLeafReader filterReader = new FilterLeafReader(leafReader) {
@Override
public Bits getDocsWithField(String field) throws IOException {
switch (field) {
case "with_matchall":
return new Bits.MatchAllBits(maxDoc());
case "with_matchno":
return new Bits.MatchNoBits(maxDoc());
case "with_bitset":
BitSet b = random().nextBoolean() ? new SparseFixedBitSet(maxDoc()) : new FixedBitSet(maxDoc());
b.set(random().nextInt(maxDoc()));
return b;
}
return super.getDocsWithField(field);
}
};
Filter filter = new FieldValueFilter("with_matchall", true);
DocIdSet set = filter.getDocIdSet(filterReader.getContext(), null);
assertNull(set);
filter = new FieldValueFilter("with_matchno");
set = filter.getDocIdSet(filterReader.getContext(), null);
assertNull(set);
filter = new FieldValueFilter("with_bitset");
set = filter.getDocIdSet(filterReader.getContext(), null);
assertTrue(set instanceof BitDocIdSet);
reader.close();
directory.close();
}
private int[] buildIndex(RandomIndexWriter writer, int docs)
throws IOException {
int[] docStates = new int[docs];