Skip to content

Commit eec258e

Browse files
Extrace leaf-slice calculation path from IndexSearch#slices (#14336)
Extracting the mechanical movement of this logic that is at least for the time being often unused/cold to help the compiler out a bit. Extracted from #13860
1 parent 84267c8 commit eec258e

File tree

1 file changed

+55
-51
lines changed

1 file changed

+55
-51
lines changed

lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -363,57 +363,7 @@ public static LeafSlice[] slices(
363363
sortedLeaves.sort(Collections.reverseOrder(Comparator.comparingInt(l -> l.reader().maxDoc())));
364364

365365
if (allowSegmentPartitions) {
366-
final List<List<LeafReaderContextPartition>> groupedLeafPartitions = new ArrayList<>();
367-
int currentSliceNumDocs = 0;
368-
List<LeafReaderContextPartition> group = null;
369-
for (LeafReaderContext ctx : sortedLeaves) {
370-
if (ctx.reader().maxDoc() > maxDocsPerSlice) {
371-
assert group == null;
372-
// if the segment does not fit in a single slice, we split it into maximum 5 partitions of
373-
// equal size
374-
int numSlices = Math.min(5, Math.ceilDiv(ctx.reader().maxDoc(), maxDocsPerSlice));
375-
int numDocs = ctx.reader().maxDoc() / numSlices;
376-
int maxDocId = numDocs;
377-
int minDocId = 0;
378-
for (int i = 0; i < numSlices - 1; i++) {
379-
groupedLeafPartitions.add(
380-
Collections.singletonList(
381-
LeafReaderContextPartition.createFromAndTo(ctx, minDocId, maxDocId)));
382-
minDocId = maxDocId;
383-
maxDocId += numDocs;
384-
}
385-
// the last slice gets all the remaining docs
386-
groupedLeafPartitions.add(
387-
Collections.singletonList(
388-
LeafReaderContextPartition.createFromAndTo(
389-
ctx, minDocId, ctx.reader().maxDoc())));
390-
} else {
391-
if (group == null) {
392-
group = new ArrayList<>();
393-
groupedLeafPartitions.add(group);
394-
}
395-
group.add(LeafReaderContextPartition.createForEntireSegment(ctx));
396-
397-
currentSliceNumDocs += ctx.reader().maxDoc();
398-
// We only split a segment when it does not fit entirely in a slice. We don't partition
399-
// the
400-
// segment that makes the current slice (which holds multiple segments) go over
401-
// maxDocsPerSlice. This means that a slice either contains multiple entire segments, or a
402-
// single partition of a segment.
403-
if (group.size() >= maxSegmentsPerSlice || currentSliceNumDocs > maxDocsPerSlice) {
404-
group = null;
405-
currentSliceNumDocs = 0;
406-
}
407-
}
408-
}
409-
410-
LeafSlice[] slices = new LeafSlice[groupedLeafPartitions.size()];
411-
int upto = 0;
412-
for (List<LeafReaderContextPartition> currentGroup : groupedLeafPartitions) {
413-
slices[upto] = new LeafSlice(currentGroup);
414-
++upto;
415-
}
416-
return slices;
366+
return slicesWithSegmentPartitions(maxDocsPerSlice, maxSegmentsPerSlice, sortedLeaves);
417367
}
418368

419369
final List<List<LeafReaderContext>> groupedLeaves = new ArrayList<>();
@@ -456,6 +406,60 @@ public static LeafSlice[] slices(
456406
return slices;
457407
}
458408

409+
private static LeafSlice[] slicesWithSegmentPartitions(
410+
int maxDocsPerSlice, int maxSegmentsPerSlice, List<LeafReaderContext> sortedLeaves) {
411+
final List<List<LeafReaderContextPartition>> groupedLeafPartitions = new ArrayList<>();
412+
int currentSliceNumDocs = 0;
413+
List<LeafReaderContextPartition> group = null;
414+
for (LeafReaderContext ctx : sortedLeaves) {
415+
if (ctx.reader().maxDoc() > maxDocsPerSlice) {
416+
assert group == null;
417+
// if the segment does not fit in a single slice, we split it into maximum 5 partitions of
418+
// equal size
419+
int numSlices = Math.min(5, Math.ceilDiv(ctx.reader().maxDoc(), maxDocsPerSlice));
420+
int numDocs = ctx.reader().maxDoc() / numSlices;
421+
int maxDocId = numDocs;
422+
int minDocId = 0;
423+
for (int i = 0; i < numSlices - 1; i++) {
424+
groupedLeafPartitions.add(
425+
Collections.singletonList(
426+
LeafReaderContextPartition.createFromAndTo(ctx, minDocId, maxDocId)));
427+
minDocId = maxDocId;
428+
maxDocId += numDocs;
429+
}
430+
// the last slice gets all the remaining docs
431+
groupedLeafPartitions.add(
432+
Collections.singletonList(
433+
LeafReaderContextPartition.createFromAndTo(ctx, minDocId, ctx.reader().maxDoc())));
434+
} else {
435+
if (group == null) {
436+
group = new ArrayList<>();
437+
groupedLeafPartitions.add(group);
438+
}
439+
group.add(LeafReaderContextPartition.createForEntireSegment(ctx));
440+
441+
currentSliceNumDocs += ctx.reader().maxDoc();
442+
// We only split a segment when it does not fit entirely in a slice. We don't partition
443+
// the
444+
// segment that makes the current slice (which holds multiple segments) go over
445+
// maxDocsPerSlice. This means that a slice either contains multiple entire segments, or a
446+
// single partition of a segment.
447+
if (group.size() >= maxSegmentsPerSlice || currentSliceNumDocs > maxDocsPerSlice) {
448+
group = null;
449+
currentSliceNumDocs = 0;
450+
}
451+
}
452+
}
453+
454+
LeafSlice[] slices = new LeafSlice[groupedLeafPartitions.size()];
455+
int upto = 0;
456+
for (List<LeafReaderContextPartition> currentGroup : groupedLeafPartitions) {
457+
slices[upto] = new LeafSlice(currentGroup);
458+
++upto;
459+
}
460+
return slices;
461+
}
462+
459463
/** Return the {@link IndexReader} this searches. */
460464
public IndexReader getIndexReader() {
461465
return reader;

0 commit comments

Comments
 (0)