You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2022/09/16 15:00:18 UTC

[lucene] branch branch_9_4 updated: LUCENE-10674: Ensure BitSetConjDISI returns NO_MORE_DOCS when sub-iterator exhausts. (#1068)

This is an automated email from the ASF dual-hosted git repository.

jpountz pushed a commit to branch branch_9_4
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/branch_9_4 by this push:
     new 7b3e78d6696 LUCENE-10674: Ensure BitSetConjDISI returns NO_MORE_DOCS when sub-iterator exhausts. (#1068)
7b3e78d6696 is described below

commit 7b3e78d6696aa886307af5db24536ac379a95038
Author: John Mazanec <jm...@amazon.com>
AuthorDate: Thu Sep 15 02:21:39 2022 -0700

    LUCENE-10674: Ensure BitSetConjDISI returns NO_MORE_DOCS when sub-iterator exhausts. (#1068)
    
    Signed-off-by: John Mazanec <jm...@amazon.com>
---
 lucene/CHANGES.txt                                 |  2 ++
 .../org/apache/lucene/search/ConjunctionDISI.java  |  3 +++
 .../apache/lucene/search/TestConjunctionDISI.java  | 31 +++++++++++++++++++---
 3 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 04e46a2ee33..e1ad168aee3 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -61,6 +61,8 @@ Bug Fixes
 * LUCENE-10665, GITHUB#11701: Fix classloading deadlock in analysis factories / AnalysisSPILoader
   initialization.  (Uwe Schindler)
 
+* LUCENE-10674: Ensure BitSetConjDISI returns NO_MORE_DOCS when sub-iterator exhausts. (Jack Mazanec)
+
 Build
 ---------------------
 
diff --git a/lucene/core/src/java/org/apache/lucene/search/ConjunctionDISI.java b/lucene/core/src/java/org/apache/lucene/search/ConjunctionDISI.java
index e00bc752394..b70224f1ec5 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ConjunctionDISI.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ConjunctionDISI.java
@@ -281,6 +281,9 @@ final class ConjunctionDISI extends DocIdSetIterator {
       advanceLead:
       for (; ; doc = lead.nextDoc()) {
         if (doc >= minLength) {
+          if (doc != NO_MORE_DOCS) {
+            lead.advance(NO_MORE_DOCS);
+          }
           return NO_MORE_DOCS;
         }
         for (BitSet bitSet : bitSets) {
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java b/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java
index 436982ffc59..429c84c891a 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java
@@ -16,6 +16,8 @@
  */
 package org.apache.lucene.search;
 
+import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS;
+
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -213,9 +215,7 @@ public class TestConjunctionDISI extends LuceneTestCase {
 
   private static FixedBitSet toBitSet(int maxDoc, DocIdSetIterator iterator) throws IOException {
     final FixedBitSet set = new FixedBitSet(maxDoc);
-    for (int doc = iterator.nextDoc();
-        doc != DocIdSetIterator.NO_MORE_DOCS;
-        doc = iterator.nextDoc()) {
+    for (int doc = iterator.nextDoc(); doc != NO_MORE_DOCS; doc = iterator.nextDoc()) {
       set.set(doc);
     }
     return set;
@@ -459,4 +459,29 @@ public class TestConjunctionDISI extends LuceneTestCase {
     AssertionError ex = expectThrows(AssertionError.class, () -> conjunction.nextDoc());
     assertEquals("Sub-iterators of ConjunctionDISI are not on the same document!", ex.getMessage());
   }
+
+  public void testBitSetConjunctionDISIDocIDOnExhaust() throws IOException {
+    int numBitSetIterators = TestUtil.nextInt(random(), 2, 5);
+    DocIdSetIterator[] iterators = new DocIdSetIterator[numBitSetIterators + 1];
+
+    // Create sparse DocIdSetIterator with a single match that is greater than lengths of bitset
+    // iterators
+    int maxBitSetLength = 1000;
+    int minBitSetLength = 2;
+    int leadMaxDoc = maxBitSetLength + 1;
+    iterators[iterators.length - 1] = DocIdSetIterator.range(leadMaxDoc, leadMaxDoc + 1);
+
+    for (int i = 0; i < numBitSetIterators; i++) {
+      int bitSetLength = TestUtil.nextInt(random(), minBitSetLength, maxBitSetLength);
+      FixedBitSet bitSet = new FixedBitSet(bitSetLength);
+      bitSet.set(0, bitSetLength - 1);
+      iterators[i] = new BitDocIdSet(bitSet).iterator();
+    }
+
+    final DocIdSetIterator conjunction =
+        ConjunctionUtils.intersectIterators(Arrays.asList(iterators));
+
+    assertEquals(NO_MORE_DOCS, conjunction.nextDoc());
+    assertEquals(NO_MORE_DOCS, conjunction.docID());
+  }
 }