From 4ef67b86724b61f82fd97ff6a26ca227bf393a5b Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Fri, 6 Sep 2024 15:22:40 +0200 Subject: [PATCH 1/2] Make two SubReaderWrapper implementations singletons No state in either of these, no need to recreate them for every directory. Saves a few cycles and makes it more obvious that there's no state in these. --- .../elasticsearch/common/lucene/Lucene.java | 36 ++++++++++--------- .../elasticsearch/index/shard/IndexShard.java | 21 +++++++---- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java index acdc3e32ea31a..86cd34dd9dfd9 100644 --- a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java +++ b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java @@ -884,24 +884,26 @@ protected StoredFieldsReader doGetSequentialStoredFieldsReader(StoredFieldsReade } } - DirectoryReaderWithAllLiveDocs(DirectoryReader in) throws IOException { - super(in, new SubReaderWrapper() { - @Override - public LeafReader wrap(LeafReader leaf) { - final SegmentReader segmentReader = segmentReader(leaf); - final Bits hardLiveDocs = segmentReader.getHardLiveDocs(); - if (hardLiveDocs == null) { - return new LeafReaderWithLiveDocs(leaf, null, leaf.maxDoc()); - } - // Once soft-deletes is enabled, we no longer hard-update or hard-delete documents directly. - // Two scenarios that we have hard-deletes: (1) from old segments where soft-deletes was disabled, - // (2) when IndexWriter hits non-aborted exceptions. These two cases, IW flushes SegmentInfos - // before exposing the hard-deletes, thus we can use the hard-delete count of SegmentInfos. - final int numDocs = segmentReader.maxDoc() - segmentReader.getSegmentInfo().getDelCount(); - assert numDocs == popCount(hardLiveDocs) : numDocs + " != " + popCount(hardLiveDocs); - return new LeafReaderWithLiveDocs(segmentReader, hardLiveDocs, numDocs); + private static final SubReaderWrapper SUB_READER_WRAPPER = new SubReaderWrapper() { + @Override + public LeafReader wrap(LeafReader leaf) { + final SegmentReader segmentReader = segmentReader(leaf); + final Bits hardLiveDocs = segmentReader.getHardLiveDocs(); + if (hardLiveDocs == null) { + return new LeafReaderWithLiveDocs(leaf, null, leaf.maxDoc()); } - }); + // Once soft-deletes is enabled, we no longer hard-update or hard-delete documents directly. + // Two scenarios that we have hard-deletes: (1) from old segments where soft-deletes was disabled, + // (2) when IndexWriter hits non-aborted exceptions. These two cases, IW flushes SegmentInfos + // before exposing the hard-deletes, thus we can use the hard-delete count of SegmentInfos. + final int numDocs = segmentReader.maxDoc() - segmentReader.getSegmentInfo().getDelCount(); + assert numDocs == popCount(hardLiveDocs) : numDocs + " != " + popCount(hardLiveDocs); + return new LeafReaderWithLiveDocs(segmentReader, hardLiveDocs, numDocs); + } + }; + + DirectoryReaderWithAllLiveDocs(DirectoryReader in) throws IOException { + super(in, SUB_READER_WRAPPER); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java index b7d1beb4d1e06..8f1ae42a7475c 100644 --- a/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java +++ b/server/src/main/java/org/elasticsearch/index/shard/IndexShard.java @@ -1700,13 +1700,22 @@ public void setGlobalCheckpointIfUnpromotable(long globalCheckpoint) { private static final class NonClosingReaderWrapper extends FilterDirectoryReader { + private static final LeafReader[] EMPTY_LEAF_READERS = new LeafReader[0]; + + private static final FilterDirectoryReader.SubReaderWrapper SUB_READER_WRAPPER = new SubReaderWrapper() { + @Override + public LeafReader wrap(LeafReader reader) { + return reader; + } + + @Override + protected LeafReader[] wrap(List readers) { + return readers.toArray(EMPTY_LEAF_READERS); + } + }; + private NonClosingReaderWrapper(DirectoryReader in) throws IOException { - super(in, new SubReaderWrapper() { - @Override - public LeafReader wrap(LeafReader reader) { - return reader; - } - }); + super(in, SUB_READER_WRAPPER); } @Override From 4ad224583d0db900ec1c927c20096c0fe772a886 Mon Sep 17 00:00:00 2001 From: Armin Braun Date: Wed, 11 Sep 2024 10:57:31 +0200 Subject: [PATCH 2/2] rename --- .../src/main/java/org/elasticsearch/common/lucene/Lucene.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java index 86cd34dd9dfd9..95552fa508f72 100644 --- a/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java +++ b/server/src/main/java/org/elasticsearch/common/lucene/Lucene.java @@ -884,7 +884,7 @@ protected StoredFieldsReader doGetSequentialStoredFieldsReader(StoredFieldsReade } } - private static final SubReaderWrapper SUB_READER_WRAPPER = new SubReaderWrapper() { + private static final SubReaderWrapper ALL_LIVE_DOCS_SUB_READER_WRAPPER = new SubReaderWrapper() { @Override public LeafReader wrap(LeafReader leaf) { final SegmentReader segmentReader = segmentReader(leaf); @@ -903,7 +903,7 @@ public LeafReader wrap(LeafReader leaf) { }; DirectoryReaderWithAllLiveDocs(DirectoryReader in) throws IOException { - super(in, SUB_READER_WRAPPER); + super(in, ALL_LIVE_DOCS_SUB_READER_WRAPPER); } @Override