1818
1919import java .io .IOException ;
2020import java .util .ArrayList ;
21+ import java .util .Arrays ;
2122import java .util .Collection ;
2223import java .util .HashSet ;
2324import java .util .List ;
2425import java .util .Objects ;
2526import java .util .Set ;
2627import org .apache .lucene .index .LeafReader ;
2728import org .apache .lucene .index .NumericDocValues ;
29+ import org .apache .lucene .internal .hppc .FloatArrayList ;
2830import org .apache .lucene .search .CombinedFieldQuery .FieldAndWeight ;
2931import org .apache .lucene .search .similarities .Similarity .BulkSimScorer ;
3032import org .apache .lucene .search .similarities .Similarity .SimScorer ;
@@ -127,8 +129,10 @@ public float score(int doc, float freq) throws IOException {
127129 */
128130 public void scoreRange (DocAndFloatFeatureBuffer buffer ) throws IOException {
129131 normValues = ArrayUtil .growNoCopy (normValues , buffer .size );
130- for (int i = 0 ; i < buffer .size ; i ++) {
131- normValues [i ] = getNormValue (buffer .docs [i ]);
132+ if (norms != null ) {
133+ norms .longValues (buffer .size , buffer .docs , normValues , 1L );
134+ } else {
135+ Arrays .fill (normValues , 0 , buffer .size , 1L );
132136 }
133137 bulkScorer .score (buffer .size , buffer .features , normValues , buffer .features );
134138 }
@@ -145,6 +149,7 @@ public Explanation explain(int doc, Explanation freqExpl) throws IOException {
145149
146150 private static class MultiFieldNormValues extends NumericDocValues {
147151 private final NumericDocValues [] normsArr ;
152+ private float [] accBuf = FloatArrayList .EMPTY_ARRAY ;
148153 private final float [] weightArr ;
149154 private long current ;
150155 private int docID = -1 ;
@@ -193,5 +198,33 @@ public int advance(int target) {
193198 public long cost () {
194199 throw new UnsupportedOperationException ();
195200 }
201+
202+ @ Override
203+ public void longValues (int size , int [] docs , long [] values , long defaultValue )
204+ throws IOException {
205+ if (accBuf .length < size ) {
206+ accBuf = new float [ArrayUtil .oversize (size , Float .BYTES )];
207+ } else {
208+ Arrays .fill (accBuf , 0f );
209+ }
210+
211+ for (int i = 0 ; i < normsArr .length ; i ++) {
212+ // this code relies on the assumption that document length can never be equal to 0,
213+ // so we can use 0L to indicate whether we have a norm value or not
214+ normsArr [i ].longValues (size , docs , values , 0L );
215+ float weight = weightArr [i ];
216+ for (int j = 0 ; j < size ; j ++) {
217+ accBuf [j ] += weight * LENGTH_TABLE [Byte .toUnsignedInt ((byte ) values [j ])];
218+ }
219+ }
220+
221+ for (int i = 0 ; i < size ; i ++) {
222+ if (accBuf [i ] == 0f ) {
223+ values [i ] = defaultValue ;
224+ } else {
225+ values [i ] = SmallFloat .intToByte4 (Math .round (accBuf [i ]));
226+ }
227+ }
228+ }
196229 }
197230}
0 commit comments