lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sh...@apache.org
Subject svn commit: r1505909 - in /lucene/dev/trunk/lucene: ./ core/src/java/org/apache/lucene/search/ core/src/test/org/apache/lucene/search/ test-framework/src/java/org/apache/lucene/search/
Date Tue, 23 Jul 2013 06:25:38 GMT
Author: shaie
Date: Tue Jul 23 06:25:37 2013
New Revision: 1505909

URL: http://svn.apache.org/r1505909
Log:
LUCENE-5128: IndexSearcher.searchAfter should throw IllegalArgumentException if after.doc
>= reader.maxDoc()

Modified:
    lucene/dev/trunk/lucene/CHANGES.txt
    lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
    lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
    lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java

Modified: lucene/dev/trunk/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/CHANGES.txt?rev=1505909&r1=1505908&r2=1505909&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/CHANGES.txt (original)
+++ lucene/dev/trunk/lucene/CHANGES.txt Tue Jul 23 06:25:37 2013
@@ -80,6 +80,10 @@ API Changes
 * LUCENE-5114: Remove unused boolean useCache parameter from
   TermsEnum.seekCeil and .seekExact (Mike McCandless)
 
+* LUCENE-5128: IndexSearcher.searchAfter throws IllegalArgumentException if 
+  searchAfter exceeds the number of documents in the reader. 
+  (Crocket via Shai Erera)
+
 Optimizations
 
 * LUCENE-5088: Added TermFilter to filter docs by a specific term.

Modified: lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java?rev=1505909&r1=1505908&r2=1505909&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java (original)
+++ lucene/dev/trunk/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java Tue
Jul 23 06:25:37 2013
@@ -430,6 +430,10 @@ public class IndexSearcher {
     if (limit == 0) {
       limit = 1;
     }
+    if (after != null && after.doc >= limit) {
+      throw new IllegalArgumentException("after.doc exceeds the number of documents in that
reader: after.doc="
+          + after.doc + " limit=" + limit);
+    }
     nDocs = Math.min(nDocs, limit);
     
     if (executor == null) {
@@ -440,8 +444,7 @@ public class IndexSearcher {
       final ExecutionHelper<TopDocs> runner = new ExecutionHelper<TopDocs>(executor);
     
       for (int i = 0; i < leafSlices.length; i++) { // search each sub
-        runner.submit(
-                      new SearcherCallableNoSort(lock, this, leafSlices[i], weight, after,
nDocs, hq));
+        runner.submit(new SearcherCallableNoSort(lock, this, leafSlices[i], weight, after,
nDocs, hq));
       }
 
       int totalHits = 0;
@@ -920,7 +923,7 @@ public class IndexSearcher {
    */
   public TermStatistics termStatistics(Term term, TermContext context) throws IOException
{
     return new TermStatistics(term.bytes(), context.docFreq(), context.totalTermFreq());
-  };
+  }
   
   /**
    * Returns {@link CollectionStatistics} for a field.

Modified: lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java?rev=1505909&r1=1505908&r2=1505909&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
(original)
+++ lucene/dev/trunk/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
Tue Jul 23 06:25:37 2013
@@ -29,9 +29,11 @@ import org.apache.lucene.index.RandomInd
 import org.apache.lucene.index.Term;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.NamedThreadFactory;
 import org.apache.lucene.util._TestUtil;
+import org.junit.Test;
 
 public class TestIndexSearcher extends LuceneTestCase {
   Directory dir;
@@ -116,4 +118,25 @@ public class TestIndexSearcher extends L
     
     _TestUtil.shutdownExecutorService(service);
   }
+  
+  @Test
+  public void testSearchAfterPassedMaxDoc() throws Exception {
+    // LUCENE-5128: ensure we get a meaningful message if searchAfter exceeds maxDoc
+    Directory dir = newDirectory();
+    RandomIndexWriter w = new RandomIndexWriter(random(), dir);
+    w.addDocument(new Document());
+    IndexReader r = w.getReader();
+    w.close();
+    
+    IndexSearcher s = new IndexSearcher(r);
+    try {
+      s.searchAfter(new ScoreDoc(r.maxDoc(), 0.54f), new MatchAllDocsQuery(), 10);
+      fail("should have hit IllegalArgumentException when searchAfter exceeds maxDoc");
+    } catch (IllegalArgumentException e) {
+      // ok
+    } finally {
+      IOUtils.close(r, dir);
+    }
+  }
+  
 }

Modified: lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java?rev=1505909&r1=1505908&r2=1505909&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
(original)
+++ lucene/dev/trunk/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
Tue Jul 23 06:25:37 2013
@@ -370,20 +370,35 @@ public abstract class ShardSearchingTest
       @Override
       public TopDocs searchAfter(ScoreDoc after, Query query, int numHits) throws IOException
{
         final TopDocs[] shardHits = new TopDocs[nodeVersions.length];
+        // results are merged in that order: score, shardIndex, doc. therefore we set
+        // after to after.score and depending on the nodeID we set doc to either:
+        // - not collect any more documents with that score (only with worse score)
+        // - collect more documents with that score (and worse) following the last collected
document
+        // - collect all documents with that score (and worse)
         ScoreDoc shardAfter = new ScoreDoc(after.doc, after.score);
-        for(int nodeID=0;nodeID<nodeVersions.length;nodeID++) {
+        for (int nodeID = 0; nodeID < nodeVersions.length; nodeID++) {
           if (nodeID < after.shardIndex) {
-            // If score is tied then no docs in this shard
-            // should be collected:
-            shardAfter.doc = Integer.MAX_VALUE;
+            // all documents with after.score were already collected, so collect
+            // only documents with worse scores.
+            final NodeState.ShardIndexSearcher s = nodes[nodeID].acquire(nodeVersions);
+            try {
+              // Setting after.doc to reader.maxDoc-1 is a way to tell
+              // TopScoreDocCollector that no more docs with that score should
+              // be collected. note that in practice the shard which sends the
+              // request to a remote shard won't have reader.maxDoc at hand, so
+              // it will send some arbitrary value which will be fixed on the
+              // other end.
+              shardAfter.doc = s.getIndexReader().maxDoc() - 1;
+            } finally {
+              nodes[nodeID].release(s);
+            }
           } else if (nodeID == after.shardIndex) {
-            // If score is tied then we break according to
-            // docID (like normal):  
+            // collect all documents following the last collected doc with
+            // after.score + documents with worse scores.  
             shardAfter.doc = after.doc;
           } else {
-            // If score is tied then all docs in this shard
-            // should be collected, because they come after
-            // the previous bottom:
+            // all documents with after.score (and worse) should be collected
+            // because they didn't make it to top-N in the previous round.
             shardAfter.doc = -1;
           }
           if (nodeID == myNodeID) {



Mime
View raw message