You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2025/03/12 01:05:51 UTC

(lucene) branch branch_10x updated: Speedup slice calculation in IndexSearcher (#14343)

This is an automated email from the ASF dual-hosted git repository.

abr pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/branch_10x by this push:
     new 745602c9a0e Speedup slice calculation in IndexSearcher (#14343)
745602c9a0e is described below

commit 745602c9a0e232cac82a6a56ece0d70538d8ae5f
Author: Armin Braun <me...@obrown.io>
AuthorDate: Wed Mar 12 01:59:15 2025 +0100

    Speedup slice calculation in IndexSearcher (#14343)
    
    It's in the title, some obvious speedups. This is fairly expensive logic
    for Elasticsearch when run over a larger number of shards.
    No need for streams, creating comparator instances and so much copying here.
---
 .../org/apache/lucene/search/IndexSearcher.java    | 52 +++++++++++-----------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
index ff241c3ead7..9359b05224a 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -233,13 +233,7 @@ public class IndexSearcher {
       leafSlices =
           leafContexts.isEmpty()
               ? new LeafSlice[0]
-              : new LeafSlice[] {
-                new LeafSlice(
-                    new ArrayList<>(
-                        leafContexts.stream()
-                            .map(LeafReaderContextPartition::createForEntireSegment)
-                            .toList()))
-              };
+              : new LeafSlice[] {LeafSlice.entireSegments(leafContexts)};
     }
   }
 
@@ -394,12 +388,7 @@ public class IndexSearcher {
     LeafSlice[] slices = new LeafSlice[groupedLeaves.size()];
     int upto = 0;
     for (List<LeafReaderContext> currentLeaf : groupedLeaves) {
-      slices[upto] =
-          new LeafSlice(
-              new ArrayList<>(
-                  currentLeaf.stream()
-                      .map(LeafReaderContextPartition::createForEntireSegment)
-                      .toList()));
+      slices[upto] = LeafSlice.entireSegments(currentLeaf);
       ++upto;
     }
 
@@ -1013,6 +1002,10 @@ public class IndexSearcher {
    */
   public static class LeafSlice {
 
+    private static final Comparator<LeafReaderContextPartition> COMPARATOR =
+        Comparator.<LeafReaderContextPartition>comparingInt(l -> l.ctx.docBase)
+            .thenComparingInt(l -> l.minDocId);
+
     /**
      * The leaves that make up this slice.
      *
@@ -1022,18 +1015,27 @@ public class IndexSearcher {
 
     private final int maxDocs;
 
-    public LeafSlice(List<LeafReaderContextPartition> leafReaderContextPartitions) {
-      Comparator<LeafReaderContextPartition> docBaseComparator =
-          Comparator.comparingInt(l -> l.ctx.docBase);
-      Comparator<LeafReaderContextPartition> minDocIdComparator =
-          Comparator.comparingInt(l -> l.minDocId);
-      leafReaderContextPartitions.sort(docBaseComparator.thenComparing(minDocIdComparator));
-      this.partitions = leafReaderContextPartitions.toArray(new LeafReaderContextPartition[0]);
-      this.maxDocs =
-          Arrays.stream(partitions)
-              .map(leafPartition -> leafPartition.maxDocs)
-              .reduce(Integer::sum)
-              .get();
+    public LeafSlice(List<LeafReaderContextPartition> partitions) {
+      this(partitions.toArray(new LeafReaderContextPartition[0]));
+    }
+
+    private static LeafSlice entireSegments(List<LeafReaderContext> contexts) {
+      int count = contexts.size();
+      LeafReaderContextPartition[] parts = new LeafReaderContextPartition[count];
+      for (int i = 0; i < count; i++) {
+        parts[i] = LeafReaderContextPartition.createForEntireSegment(contexts.get(i));
+      }
+      return new LeafSlice(parts);
+    }
+
+    private LeafSlice(LeafReaderContextPartition... leafReaderContextPartitions) {
+      Arrays.sort(leafReaderContextPartitions, COMPARATOR);
+      this.partitions = leafReaderContextPartitions;
+      int maxDocs = 0;
+      for (LeafReaderContextPartition partition : partitions) {
+        maxDocs += partition.maxDocs;
+      }
+      this.maxDocs = maxDocs;
     }
 
     /**