@@ -69,4 +69,61 @@ public void rangeIntoBitSet(
6969 }
7070 }
7171 }
72+
73+ @ Override
74+ public void sortedNumericRangeIntoBitSet (
75+ LongValues values ,
76+ int fromDoc ,
77+ int toDoc ,
78+ int cardinality ,
79+ long minValue ,
80+ long maxValue ,
81+ FixedBitSet bitSet ,
82+ int offset ) {
83+ assert cardinality > 0 : "cardinality must be positive: " + cardinality ;
84+ final int vectorLen = LONG_SPECIES .length ();
85+ final int docsPerVector = vectorLen / cardinality ;
86+ if (docsPerVector == 0 || vectorLen % cardinality != 0 ) {
87+ DocValuesRangeSupport .super .sortedNumericRangeIntoBitSet (
88+ values , fromDoc , toDoc , cardinality , minValue , maxValue , bitSet , offset );
89+ return ;
90+ }
91+
92+ final long [] scratch = new long [vectorLen ];
93+ final int vectorDocEnd = fromDoc + (toDoc - fromDoc ) / docsPerVector * docsPerVector ;
94+ int doc = fromDoc ;
95+ for (; doc < vectorDocEnd ; doc += docsPerVector ) {
96+ long valueOffset = (long ) doc * cardinality ;
97+ for (int lane = 0 ; lane < vectorLen ; lane ++) {
98+ scratch [lane ] = values .get (valueOffset + lane );
99+ }
100+ LongVector vector = LongVector .fromArray (LONG_SPECIES , scratch , 0 );
101+ // Flat range check on all lanes. Equivalent to the scalar early-break on sorted values:
102+ // a value outside [min,max] that is >= min must be > max, so its lane stays unset, and
103+ // collapseToDocMask OR-reduces lanes per doc to match "any value in range" semantics.
104+ VectorMask <Long > inRange =
105+ vector
106+ .compare (VectorOperators .GE , minValue )
107+ .and (vector .compare (VectorOperators .LE , maxValue ));
108+ long docMask = collapseToDocMask (inRange .toLong (), cardinality , docsPerVector );
109+ if (docMask != 0 ) {
110+ bitSet .orMask (doc - offset , docMask , docsPerVector );
111+ }
112+ }
113+
114+ DocValuesRangeSupport .super .sortedNumericRangeIntoBitSet (
115+ values , doc , toDoc , cardinality , minValue , maxValue , bitSet , offset );
116+ }
117+
118+ private static long collapseToDocMask (long valueMask , int cardinality , int docsPerVector ) {
119+ final long valueMaskPerDoc = (1L << cardinality ) - 1L ;
120+ long docMask = 0L ;
121+ for (int d = 0 ; d < docsPerVector ; d ++) {
122+ long perDoc = (valueMask >>> (d * cardinality )) & valueMaskPerDoc ;
123+ if (perDoc != 0 ) {
124+ docMask |= 1L << d ;
125+ }
126+ }
127+ return docMask ;
128+ }
72129}
0 commit comments