From e0227b516cd06900cd8127fc762448efa1147386 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Wed, 5 Nov 2014 09:04:53 +0000 Subject: [PATCH] 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 --- .../lucene/search/FieldValueFilter.java | 6 ++- .../lucene/search/TestFieldValueFilter.java | 54 ++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java b/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java index 88d683e6147..c2cf116a94f 100644 --- a/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java +++ b/lucene/core/src/java/org/apache/lucene/search/FieldValueFilter.java @@ -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 diff --git a/lucene/core/src/test/org/apache/lucene/search/TestFieldValueFilter.java b/lucene/core/src/test/org/apache/lucene/search/TestFieldValueFilter.java index 59ccf894067..052bd43eca0 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestFieldValueFilter.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestFieldValueFilter.java @@ -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];