21
21
import org .apache .lucene .util .BitSetIterator ;
22
22
import org .apache .lucene .util .Bits ;
23
23
import org .apache .lucene .util .FixedBitSet ;
24
+ import org .opensearch .common .Nullable ;
25
+ import org .opensearch .common .StopWatch ;
24
26
import org .opensearch .common .lucene .Lucene ;
25
27
import org .opensearch .knn .common .FieldInfoExtractor ;
26
28
import org .opensearch .knn .common .KNNConstants ;
@@ -143,7 +145,13 @@ public long cost() {
143
145
* @return A Map of docId to scores for top k results
144
146
*/
145
147
public PerLeafResult searchLeaf (LeafReaderContext context , int k ) throws IOException {
148
+ final SegmentReader reader = Lucene .segmentReader (context .reader ());
149
+ final String segmentName = reader .getSegmentName ();
150
+
151
+ StopWatch stopWatch = startStopWatch ();
146
152
final BitSet filterBitSet = getFilteredDocsBitSet (context );
153
+ stopStopWatchAndLog (stopWatch , "FilterBitSet creation" , segmentName );
154
+
147
155
final int maxDoc = context .reader ().maxDoc ();
148
156
int cardinality = filterBitSet .cardinality ();
149
157
// We don't need to go to JNI layer if no documents are found which satisfy the filters
@@ -167,7 +175,10 @@ public PerLeafResult searchLeaf(LeafReaderContext context, int k) throws IOExcep
167
175
* so that it will not do a bitset look up in bottom search layer.
168
176
*/
169
177
final BitSet annFilter = (filterWeight != null && cardinality == maxDoc ) ? null : filterBitSet ;
170
- final Map <Integer , Float > docIdsToScoreMap = doANNSearch (context , annFilter , cardinality , k );
178
+
179
+ StopWatch annStopWatch = startStopWatch ();
180
+ final Map <Integer , Float > docIdsToScoreMap = doANNSearch (reader , context , annFilter , cardinality , k );
181
+ stopStopWatchAndLog (annStopWatch , "ANN search" , segmentName );
171
182
172
183
// See whether we have to perform exact search based on approx search results
173
184
// This is required if there are no native engine files or if approximate search returned
@@ -180,6 +191,14 @@ public PerLeafResult searchLeaf(LeafReaderContext context, int k) throws IOExcep
180
191
return new PerLeafResult (filterWeight == null ? null : filterBitSet , docIdsToScoreMap );
181
192
}
182
193
194
+ private void stopStopWatchAndLog (@ Nullable final StopWatch stopWatch , final String prefixMessage , String segmentName ) {
195
+ if (log .isDebugEnabled () && stopWatch != null ) {
196
+ stopWatch .stop ();
197
+ final String logMessage = prefixMessage + " shard: [{}], segment: [{}], field: [{}], time in nanos:[{}] " ;
198
+ log .debug (logMessage , knnQuery .getShardId (), segmentName , knnQuery .getField (), stopWatch .totalTime ().nanos ());
199
+ }
200
+ }
201
+
183
202
private BitSet getFilteredDocsBitSet (final LeafReaderContext ctx ) throws IOException {
184
203
if (this .filterWeight == null ) {
185
204
return new FixedBitSet (0 );
@@ -236,7 +255,7 @@ private Map<Integer, Float> doExactSearch(
236
255
final LeafReaderContext context ,
237
256
final DocIdSetIterator acceptedDocs ,
238
257
final long numberOfAcceptedDocs ,
239
- int k
258
+ final int k
240
259
) throws IOException {
241
260
final ExactSearcherContextBuilder exactSearcherContextBuilder = ExactSearcher .ExactSearcherContext .builder ()
242
261
.isParentHits (true )
@@ -251,13 +270,12 @@ private Map<Integer, Float> doExactSearch(
251
270
}
252
271
253
272
private Map <Integer , Float > doANNSearch (
273
+ final SegmentReader reader ,
254
274
final LeafReaderContext context ,
255
275
final BitSet filterIdsBitSet ,
256
276
final int cardinality ,
257
277
final int k
258
278
) throws IOException {
259
- final SegmentReader reader = Lucene .segmentReader (context .reader ());
260
-
261
279
FieldInfo fieldInfo = FieldInfoExtractor .getFieldInfo (reader , knnQuery .getField ());
262
280
263
281
if (fieldInfo == null ) {
@@ -416,7 +434,11 @@ public Map<Integer, Float> exactSearch(
416
434
final LeafReaderContext leafReaderContext ,
417
435
final ExactSearcher .ExactSearcherContext exactSearcherContext
418
436
) throws IOException {
419
- return exactSearcher .searchLeaf (leafReaderContext , exactSearcherContext );
437
+ StopWatch stopWatch = startStopWatch ();
438
+ Map <Integer , Float > exactSearchResults = exactSearcher .searchLeaf (leafReaderContext , exactSearcherContext );
439
+ final SegmentReader reader = Lucene .segmentReader (leafReaderContext .reader ());
440
+ stopStopWatchAndLog (stopWatch , "Exact search" , reader .getSegmentName ());
441
+ return exactSearchResults ;
420
442
}
421
443
422
444
@ Override
@@ -523,4 +545,11 @@ private boolean isMissingNativeEngineFiles(LeafReaderContext context) {
523
545
);
524
546
return engineFiles .isEmpty ();
525
547
}
548
+
549
+ private StopWatch startStopWatch () {
550
+ if (log .isDebugEnabled ()) {
551
+ return new StopWatch ().start ();
552
+ }
553
+ return null ;
554
+ }
526
555
}
0 commit comments