lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sim...@apache.org
Subject svn commit: r1388392 - in /lucene/dev/trunk/lucene/core/src: java/org/apache/lucene/search/FilteredQuery.java test/org/apache/lucene/search/TestFilteredQuery.java
Date Fri, 21 Sep 2012 09:37:29 GMT
Author: simonw
Date: Fri Sep 21 09:37:28 2012
New Revision: 1388392

URL: http://svn.apache.org/viewvc?rev=1388392&view=rev
Log:
LUCENE-4410: Fix LeapFrog initialization & add santiy test cases for individual strategies

Modified:
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java?rev=1388392&r1=1388391&r2=1388392&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/FilteredQuery.java Fri
Sep 21 09:37:28 2012
@@ -222,7 +222,7 @@ public class FilteredQuery extends Query
     private final DocIdSetIterator secondary;
     private final DocIdSetIterator primary;
     private final Scorer scorer;
-    private int primaryDoc = -1;
+    protected int primaryDoc = -1;
     protected int secondaryDoc = -1;
 
     protected LeapFrogScorer(Weight weight, DocIdSetIterator primary, DocIdSetIterator secondary,
Scorer scorer) {
@@ -289,8 +289,7 @@ public class FilteredQuery extends Query
 
     @Override
     public final int docID() {
-      assert scorer.docID() == primaryDoc;
-      return primaryDoc;
+      return secondaryDoc;
     }
     
     @Override
@@ -314,6 +313,7 @@ public class FilteredQuery extends Query
     protected PrimaryAdvancedLeapFrogScorer(Weight weight, int firstFilteredDoc, DocIdSetIterator
filterIter, Scorer other) {
       super(weight, filterIter, other, other);
       this.firstFilteredDoc = firstFilteredDoc;
+      this.primaryDoc = firstFilteredDoc; // initialize to prevent and advance call to move
it further
     }
 
     @Override
@@ -564,9 +564,9 @@ public class FilteredQuery extends Query
       // we pass null as acceptDocs, as our filter has already respected acceptDocs, no need
to do twice
       final Scorer scorer = weight.scorer(context, true, false, null);
       if (scorerFirst) {
-        return (scorer == null) ? null : new LeapFrogScorer(weight, filterIter, scorer, scorer);
 
-      } else {
         return (scorer == null) ? null : new LeapFrogScorer(weight, scorer, filterIter, scorer);
 
+      } else {
+        return (scorer == null) ? null : new LeapFrogScorer(weight, filterIter, scorer, scorer);
 
       }
     }
     

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java?rev=1388392&r1=1388391&r2=1388392&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
(original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestFilteredQuery.java
Fri Sep 21 09:37:28 2012
@@ -17,13 +17,16 @@ package org.apache.lucene.search;
  * limitations under the License.
  */
 
+import java.io.IOException;
 import java.util.BitSet;
 import java.util.Random;
 
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
+import org.apache.lucene.index.AtomicReader;
 import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.DocsEnum;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Term;
@@ -31,6 +34,7 @@ import org.apache.lucene.search.BooleanC
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.DocIdBitSet;
+import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util._TestUtil;
 
@@ -377,6 +381,151 @@ public class TestFilteredQuery extends L
     }
     return _TestUtil.randomFilterStrategy(random);
   }
+  
+  /*
+   * Test if the QueryFirst strategy calls the bits only if
+   * the document has been matched by the query and not otherwise
+   */
+  public void testQueryFirstFilterStrategy() throws IOException {
+    Directory directory = newDirectory();
+    RandomIndexWriter writer = new RandomIndexWriter (random(), directory, newIndexWriterConfig(TEST_VERSION_CURRENT,
new MockAnalyzer(random())));
+    int numDocs = atLeast(50);
+    int totalDocsWithZero = 0;
+    for (int i = 0; i < numDocs; i++) {
+      Document doc = new Document();
+      int num = random().nextInt(5);
+      if (num == 0) {
+        totalDocsWithZero++;
+      }
+      doc.add (newTextField("field", ""+num, Field.Store.YES));
+      writer.addDocument (doc);  
+    }
+    IndexReader reader = writer.getReader();
+    writer.close ();
+    
+    IndexSearcher searcher = newSearcher(reader);
+    Query query = new FilteredQuery(new TermQuery(new Term("field", "0")), new Filter() {
+      @Override
+      public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs)
+          throws IOException {
+        final boolean nullBitset = random().nextInt(10) == 5;
+        final AtomicReader reader = context.reader();
+        DocsEnum termDocsEnum = reader.termDocsEnum(new Term("field", "0"));
+        final BitSet bitSet = new BitSet(reader.maxDoc());
+        if (termDocsEnum != null) {
+          int d;
+          while((d = termDocsEnum.nextDoc()) != DocsEnum.NO_MORE_DOCS) {
+            bitSet.set(d, true);
+          }
+        }
+        return new DocIdSet() {
+          
+          @Override
+          public Bits bits() throws IOException {
+            if (nullBitset) {
+              return null;
+            }
+            return new Bits() {
+
+              @Override
+              public boolean get(int index) {
+                assertTrue("filter was called for a non-matching doc", bitSet.get(index));
+                return bitSet.get(index);
+              }
+
+              @Override
+              public int length() {
+                return bitSet.length();
+              }
+              
+            };
+          }
+          @Override
+          public DocIdSetIterator iterator() throws IOException {
+            assertTrue("iterator should not be called if bitset is present", nullBitset);
+            return reader.termDocsEnum(new Term("field", "0"));
+          }
+          
+        };
+      }
+    }, FilteredQuery.QUERY_FIRST_FILTER_STRATEGY);
+    
+    TopDocs search = searcher.search(query, 10);
+    assertEquals(totalDocsWithZero, search.totalHits);
+    IOUtils.close(reader, writer, directory);
+     
+  }
+  
+  /*
+   * Test if the leapfrog strategy works correctly in terms
+   * of advancing / next the right thing first
+   */
+  public void testLeapFrogStrategy() throws IOException {
+    Directory directory = newDirectory();
+    RandomIndexWriter writer = new RandomIndexWriter (random(), directory, newIndexWriterConfig(TEST_VERSION_CURRENT,
new MockAnalyzer(random())));
+    int numDocs = atLeast(50);
+    int totalDocsWithZero = 0;
+    for (int i = 0; i < numDocs; i++) {
+      Document doc = new Document();
+      int num = random().nextInt(10);
+      if (num == 0) {
+        totalDocsWithZero++;
+      }
+      doc.add (newTextField("field", ""+num, Field.Store.YES));
+      writer.addDocument (doc);  
+    }
+    IndexReader reader = writer.getReader();
+    writer.close ();
+    final boolean queryFirst = random().nextBoolean();
+    IndexSearcher searcher = newSearcher(reader);
+    Query query = new FilteredQuery(new TermQuery(new Term("field", "0")), new Filter() {
+      @Override
+      public DocIdSet getDocIdSet(final AtomicReaderContext context, Bits acceptDocs)
+          throws IOException {
+        return new DocIdSet() {
+          
+          @Override
+          public Bits bits() throws IOException {
+             return null;
+          }
+          @Override
+          public DocIdSetIterator iterator() throws IOException {
+            final DocsEnum termDocsEnum = context.reader().termDocsEnum(new Term("field",
"0"));
+            return new DocIdSetIterator() {
+              boolean nextCalled;
+              boolean advanceCalled;
+              @Override
+              public int nextDoc() throws IOException {
+                assertTrue("queryFirst: "+ queryFirst + " advanced: " + advanceCalled + "
next: "+ nextCalled, nextCalled || advanceCalled ^ !queryFirst);  
+                nextCalled = true;
+                return termDocsEnum.nextDoc();
+              }
+              
+              @Override
+              public int docID() {
+                return termDocsEnum.docID();
+              }
+              
+              @Override
+              public int advance(int target) throws IOException {
+                assertTrue("queryFirst: "+ queryFirst + " advanced: " + advanceCalled + "
next: "+ nextCalled, advanceCalled || nextCalled ^ queryFirst);  
+                advanceCalled = true;
+                return termDocsEnum.advance(target);
+              }
+            };
+          }
+          
+        };
+      }
+        }, queryFirst ? FilteredQuery.LEAP_FROG_QUERY_FIRST_STRATEGY : random()
+            .nextBoolean() ? FilteredQuery.RANDOM_ACCESS_FILTER_STRATEGY
+            : FilteredQuery.LEAP_FROG_FILTER_FIRST_STRATEGY);  // if filterFirst, we can
use random here since bits are null
+    
+    TopDocs search = searcher.search(query, 10);
+    assertEquals(totalDocsWithZero, search.totalHits);
+    IOUtils.close(reader, writer, directory);
+     
+  }
 }
 
 



Mime
View raw message