@@ -163,9 +163,9 @@ private static byte[] createRank(FixedBitSet buffer, byte denseRankPower) {
163163 *
164164 * @param it the document IDs.
165165 * @param out destination for the blocks.
166- * @throws IOException if there was an error writing to out.
167166 * @return the number of jump-table entries following the blocks, -1 for no entries. This should
168167 * be stored in meta and used when creating an instance of IndexedDISI.
168+ * @throws IOException if there was an error writing to out.
169169 */
170170 static short writeBitSet (DocIdSetIterator it , IndexOutput out ) throws IOException {
171171 return writeBitSet (it , out , DEFAULT_DENSE_RANK_POWER );
@@ -184,9 +184,9 @@ static short writeBitSet(DocIdSetIterator it, IndexOutput out) throws IOExceptio
184184 * disables DENSE rank. Recommended values are 8-12: Every 256-4096 docIDs or 4-64 longs.
185185 * {@link #DEFAULT_DENSE_RANK_POWER} is 9: Every 512 docIDs. This should be stored in meta and
186186 * used when creating an instance of IndexedDISI.
187- * @throws IOException if there was an error writing to out.
188187 * @return the number of jump-table entries following the blocks, -1 for no entries. This should
189188 * be stored in meta and used when creating an instance of IndexedDISI.
189+ * @throws IOException if there was an error writing to out.
190190 */
191191 public static short writeBitSet (DocIdSetIterator it , IndexOutput out , byte denseRankPower )
192192 throws IOException {
@@ -436,6 +436,7 @@ public static RandomAccessInput createJumpTable(
436436 int numberOfOnes ;
437437 // Used with rank for jumps inside of DENSE as they are absolute instead of relative
438438 int denseOrigoIndex ;
439+ FixedBitSet bitSet ;
439440
440441 // ALL variables
441442 int gap ;
@@ -491,6 +492,16 @@ public int advance(int target) throws IOException {
491492 return doc ;
492493 }
493494
495+ @ Override
496+ public void intoBitSet (int upTo , FixedBitSet bitSet , int offset ) throws IOException {
497+ assert doc >= offset ;
498+ while (doc < upTo && method .intoBitSetWithinBlock (this , upTo , bitSet , offset ) == false ) {
499+ readBlockHeader ();
500+ boolean found = method .advanceWithinBlock (this , block );
501+ assert found ;
502+ }
503+ }
504+
494505 public boolean advanceExact (int target ) throws IOException {
495506 final int targetBlock = target & 0xFFFF0000 ;
496507 if (block < targetBlock ) {
@@ -625,6 +636,25 @@ boolean advanceExactWithinBlock(IndexedDISI disi, int target) throws IOException
625636 disi .exists = false ;
626637 return false ;
627638 }
639+
640+ @ Override
641+ boolean intoBitSetWithinBlock (IndexedDISI disi , int upTo , FixedBitSet bitSet , int offset )
642+ throws IOException {
643+ bitSet .set (disi .doc - offset );
644+ for (; disi .index < disi .nextBlockIndex ; ) {
645+ int docInBlock = disi .slice .readShort () & 0xFFFF ;
646+ int doc = disi .block | docInBlock ;
647+ disi .index ++;
648+ if (doc >= upTo ) {
649+ disi .doc = doc ;
650+ disi .exists = true ;
651+ disi .nextExistDocInBlock = docInBlock ;
652+ return true ;
653+ }
654+ bitSet .set (doc - offset );
655+ }
656+ return false ;
657+ }
628658 },
629659 DENSE {
630660 @ Override
@@ -693,6 +723,34 @@ boolean advanceExactWithinBlock(IndexedDISI disi, int target) throws IOException
693723 disi .index = disi .numberOfOnes - Long .bitCount (leftBits );
694724 return (leftBits & 1L ) != 0 ;
695725 }
726+
727+ @ Override
728+ boolean intoBitSetWithinBlock (IndexedDISI disi , int upTo , FixedBitSet bitSet , int offset )
729+ throws IOException {
730+ if (disi .bitSet == null ) {
731+ disi .bitSet = new FixedBitSet (BLOCK_SIZE );
732+ }
733+
734+ int sourceFrom = disi .doc & 0xFFFF ;
735+ int sourceTo = Math .min (upTo - disi .block , BLOCK_SIZE );
736+ int destFrom = disi .doc - offset ;
737+
738+ long fp = disi .slice .getFilePointer ();
739+ disi .slice .seek (fp - Long .BYTES ); // seek back a long to include current word (disi.word).
740+ int numWords = FixedBitSet .bits2words (sourceTo ) - disi .wordIndex ;
741+ disi .slice .readLongs (disi .bitSet .getBits (), disi .wordIndex , numWords );
742+ FixedBitSet .orRange (disi .bitSet , sourceFrom , bitSet , destFrom , sourceTo - sourceFrom );
743+
744+ int blockEnd = disi .block | 0xFFFF ;
745+ if (upTo > blockEnd ) {
746+ disi .slice .seek (disi .blockEnd );
747+ disi .index += disi .bitSet .cardinality (sourceFrom , sourceTo );
748+ return false ;
749+ } else {
750+ disi .slice .seek (fp );
751+ return advanceWithinBlock (disi , upTo );
752+ }
753+ }
696754 },
697755 ALL {
698756 @ Override
@@ -707,6 +765,19 @@ boolean advanceExactWithinBlock(IndexedDISI disi, int target) {
707765 disi .index = target - disi .gap ;
708766 return true ;
709767 }
768+
769+ @ Override
770+ boolean intoBitSetWithinBlock (IndexedDISI disi , int upTo , FixedBitSet bitSet , int offset ) {
771+ final int blockEnd = disi .block | 0xFFFF ;
772+ if (upTo <= blockEnd ) {
773+ bitSet .set (disi .doc - offset , upTo - offset );
774+ advanceWithinBlock (disi , upTo );
775+ return true ;
776+ } else {
777+ bitSet .set (disi .doc - offset , blockEnd - offset + 1 );
778+ return false ;
779+ }
780+ }
710781 };
711782
712783 /**
@@ -720,6 +791,19 @@ boolean advanceExactWithinBlock(IndexedDISI disi, int target) {
720791 * return whether this document exists.
721792 */
722793 abstract boolean advanceExactWithinBlock (IndexedDISI disi , int target ) throws IOException ;
794+
795+ /**
796+ * Similar to {@link DocIdSetIterator#intoBitSet}, load docs in this block into a bitset. This
797+ * method returns true if there are remaining docs (gte upTo) in the block, otherwise false.
798+ * When false return, fp of {@link IndexedDISI#slice} is at {@link IndexedDISI#blockEnd} and
799+ * {@link IndexedDISI#index} is correct but other status vars are undefined. Caller should
800+ * decode the header of next block by {@link #readBlockHeader()}.
801+ *
802+ * <p>Caller need to make sure {@link IndexedDISI#doc} greater than or equals to {@link
803+ * IndexedDISI#block} and less than {@code upTo} when calling this.
804+ */
805+ abstract boolean intoBitSetWithinBlock (
806+ IndexedDISI disi , int upTo , FixedBitSet bitSet , int offset ) throws IOException ;
723807 }
724808
725809 /**
0 commit comments