You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by gu...@apache.org on 2025/06/06 05:47:01 UTC

(lucene) branch main updated: Implement IndexedDISI#docIDRunEnd (#14753)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new a039d907c54 Implement IndexedDISI#docIDRunEnd (#14753)
a039d907c54 is described below

commit a039d907c54665780a63095bdd20c177bfd6f017
Author: Samuel.G <11...@qq.com>
AuthorDate: Fri Jun 6 14:46:55 2025 +0900

    Implement IndexedDISI#docIDRunEnd (#14753)
---
 lucene/CHANGES.txt                                 |  2 +
 .../apache/lucene/codecs/lucene90/IndexedDISI.java | 25 +++++++++
 .../codecs/lucene90/Lucene90DocValuesProducer.java | 60 ++++++++++++++++++++++
 .../lucene/codecs/lucene90/TestIndexedDISI.java    | 28 ++++++++++
 4 files changed, 115 insertions(+)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 1a9a5aa3854..8a6f1939079 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -144,6 +144,8 @@ Optimizations
 
 * GITHUB#14720: Cache high-order bits of hashcode to speed up BytesRefHash. (Pan Guixin)
 
+* GITHUB#14753: Implement IndexedDISI#docIDRunEnd. (Ge Song)
+
 Bug Fixes
 ---------------------
 * GITHUB#14654: ValueSource.fromDoubleValuesSource(dvs).getSortField() would throw errors when
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene90/IndexedDISI.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene90/IndexedDISI.java
index f9c14484cec..1d64be1a928 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene90/IndexedDISI.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene90/IndexedDISI.java
@@ -568,6 +568,11 @@ public final class IndexedDISI extends AbstractDocIdSetIterator {
     return cost;
   }
 
+  @Override
+  public int docIDRunEnd() throws IOException {
+    return method.docIDRunEnd(this);
+  }
+
   enum Method {
     SPARSE {
       @Override
@@ -634,6 +639,11 @@ public final class IndexedDISI extends AbstractDocIdSetIterator {
         }
         return false;
       }
+
+      @Override
+      int docIDRunEnd(IndexedDISI disi) throws IOException {
+        return disi.doc + 1;
+      }
     },
     DENSE {
       @Override
@@ -730,6 +740,14 @@ public final class IndexedDISI extends AbstractDocIdSetIterator {
           return advanceWithinBlock(disi, upTo);
         }
       }
+
+      @Override
+      int docIDRunEnd(IndexedDISI disi) throws IOException {
+        if (disi.word == -1L) {
+          return (disi.doc | 0x3F) + 1;
+        }
+        return disi.doc + 1;
+      }
     },
     ALL {
       @Override
@@ -757,6 +775,11 @@ public final class IndexedDISI extends AbstractDocIdSetIterator {
           return false;
         }
       }
+
+      @Override
+      int docIDRunEnd(IndexedDISI disi) throws IOException {
+        return (disi.doc | 0xFFFF) + 1;
+      }
     };
 
     /**
@@ -783,6 +806,8 @@ public final class IndexedDISI extends AbstractDocIdSetIterator {
      */
     abstract boolean intoBitSetWithinBlock(
         IndexedDISI disi, int upTo, FixedBitSet bitSet, int offset) throws IOException;
+
+    abstract int docIDRunEnd(IndexedDISI disi) throws IOException;
   }
 
   /**
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene90/Lucene90DocValuesProducer.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene90/Lucene90DocValuesProducer.java
index e1b5b2cf672..2a99bd59b92 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene90/Lucene90DocValuesProducer.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene90/Lucene90DocValuesProducer.java
@@ -465,6 +465,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
     public long cost() {
       return maxDoc;
     }
+
+    @Override
+    public int docIDRunEnd() throws IOException {
+      return maxDoc;
+    }
   }
 
   private abstract static class SparseNumericDocValues extends NumericDocValues {
@@ -504,6 +509,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
     public long cost() {
       return disi.cost();
     }
+
+    @Override
+    public int docIDRunEnd() throws IOException {
+      return disi.docIDRunEnd();
+    }
   }
 
   private LongValues getDirectReaderInstance(
@@ -747,6 +757,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
       doc = target;
       return true;
     }
+
+    @Override
+    public int docIDRunEnd() throws IOException {
+      return maxDoc;
+    }
   }
 
   private abstract static class SparseBinaryDocValues extends BinaryDocValues {
@@ -786,6 +801,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
     public void intoBitSet(int upTo, FixedBitSet bitSet, int offset) throws IOException {
       disi.intoBitSet(upTo, bitSet, offset);
     }
+
+    @Override
+    public int docIDRunEnd() throws IOException {
+      return disi.docIDRunEnd();
+    }
   }
 
   @Override
@@ -954,6 +974,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
           public long cost() {
             return maxDoc;
           }
+
+          @Override
+          public int docIDRunEnd() throws IOException {
+            return maxDoc;
+          }
         };
       } else if (ordsEntry.docsWithFieldOffset >= 0) { // sparse but non-empty
         final IndexedDISI disi =
@@ -1001,6 +1026,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
           public long cost() {
             return disi.cost();
           }
+
+          @Override
+          public int docIDRunEnd() throws IOException {
+            return disi.docIDRunEnd();
+          }
         };
       }
     }
@@ -1037,6 +1067,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
       public long cost() {
         return ords.cost();
       }
+
+      @Override
+      public int docIDRunEnd() throws IOException {
+        return ords.docIDRunEnd();
+      }
     };
   }
 
@@ -1444,6 +1479,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
         public int docValueCount() {
           return count;
         }
+
+        @Override
+        public int docIDRunEnd() throws IOException {
+          return maxDoc;
+        }
       };
     } else {
       // sparse
@@ -1516,6 +1556,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
             set = true;
           }
         }
+
+        @Override
+        public int docIDRunEnd() throws IOException {
+          return disi.docIDRunEnd();
+        }
       };
     }
   }
@@ -1605,6 +1650,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
           public long cost() {
             return maxDoc;
           }
+
+          @Override
+          public int docIDRunEnd() throws IOException {
+            return maxDoc;
+          }
         };
       } else if (ordsEntry.docsWithFieldOffset >= 0) { // sparse but non-empty
         final IndexedDISI disi =
@@ -1677,6 +1727,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
               set = true;
             }
           }
+
+          @Override
+          public int docIDRunEnd() throws IOException {
+            return disi.docIDRunEnd();
+          }
         };
       }
     }
@@ -1718,6 +1773,11 @@ final class Lucene90DocValuesProducer extends DocValuesProducer {
       public long cost() {
         return ords.cost();
       }
+
+      @Override
+      public int docIDRunEnd() throws IOException {
+        return ords.docIDRunEnd();
+      }
     };
   }
 
diff --git a/lucene/core/src/test/org/apache/lucene/codecs/lucene90/TestIndexedDISI.java b/lucene/core/src/test/org/apache/lucene/codecs/lucene90/TestIndexedDISI.java
index eddd3a98bfb..135019fe387 100644
--- a/lucene/core/src/test/org/apache/lucene/codecs/lucene90/TestIndexedDISI.java
+++ b/lucene/core/src/test/org/apache/lucene/codecs/lucene90/TestIndexedDISI.java
@@ -536,6 +536,16 @@ public class TestIndexedDISI extends LuceneTestCase {
       }
     }
 
+    for (int step : new int[] {100, 1000, 10000, 100000}) {
+      try (IndexInput in = dir.openInput("foo", IOContext.DEFAULT)) {
+        IndexedDISI disi =
+            new IndexedDISI(in, 0L, length, jumpTableentryCount, denseRankPower, cardinality);
+        BitSetIterator disi2 = new BitSetIterator(set, cardinality);
+        int disi2length = set.length();
+        assertDocIDRunEndRandomized(disi, disi2, disi2length, step);
+      }
+    }
+
     dir.deleteFile("foo");
   }
 
@@ -614,6 +624,24 @@ public class TestIndexedDISI extends LuceneTestCase {
     }
   }
 
+  private void assertDocIDRunEndRandomized(
+      IndexedDISI disi, BitSetIterator disi2, int disi2length, int step) throws IOException {
+    for (int target = 0; target < disi2length; ) {
+      target += TestUtil.nextInt(random(), 0, step);
+      if (disi.docID() < target) {
+        disi.advance(target);
+        disi2.advance(target);
+        assertEquals(disi2.docID(), disi.docID());
+        int end = disi.docIDRunEnd();
+        assertNotEquals(0, end);
+        for (int it = disi.docID(); it != DocIdSetIterator.NO_MORE_DOCS && it + 1 < end; it++) {
+          assertEquals(it + 1, disi.nextDoc());
+          assertEquals(it + 1, disi2.nextDoc());
+        }
+      }
+    }
+  }
+
   private void assertSingleStepEquality(IndexedDISI disi, BitSetIterator disi2) throws IOException {
     int i = 0;
     for (int doc = disi2.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = disi2.nextDoc()) {