From 518c76b51a79b29a940fe5808c1274c1cab44fe0 Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Mon, 14 Oct 2024 07:39:31 -0700 Subject: [PATCH] Avoid allocating liveDocs for no soft-deletes (#13895) (#13903) Backport of #13895 to 10x This is a continuation of #13588, where we avoided allocating liveDocs for segments that have the __soft_deletes field but no values in it. However, that PR only addressed the reading side. This change fixes the writing scenario with IndexWriter. Relates #13588 --- .../org/apache/lucene/index/PendingSoftDeletes.java | 11 +++++------ .../index/TestSoftDeletesDirectoryReaderWrapper.java | 6 ++++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/PendingSoftDeletes.java b/lucene/core/src/java/org/apache/lucene/index/PendingSoftDeletes.java index 557d31ad441..4147493353b 100644 --- a/lucene/core/src/java/org/apache/lucene/index/PendingSoftDeletes.java +++ b/lucene/core/src/java/org/apache/lucene/index/PendingSoftDeletes.java @@ -76,15 +76,14 @@ final class PendingSoftDeletes extends PendingDeletes { hardDeletes.onNewReader(reader, info); // only re-calculate this if we haven't seen this generation if (dvGeneration < info.getDocValuesGen()) { - final DocIdSetIterator iterator = - FieldExistsQuery.getDocValuesDocIdSetIterator(field, reader); - int newDelCount; - if (iterator - != null) { // nothing is deleted we don't have a soft deletes field in this segment - assert info.info.maxDoc() > 0 : "maxDoc is 0"; + final int newDelCount; + var iterator = FieldExistsQuery.getDocValuesDocIdSetIterator(field, reader); + if (iterator != null && iterator.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { + iterator = FieldExistsQuery.getDocValuesDocIdSetIterator(field, reader); newDelCount = applySoftDeletes(iterator, getMutableBits()); assert newDelCount >= 0 : " illegal pending delete count: " + newDelCount; } else { + // nothing is deleted we don't have a soft deletes field in this segment newDelCount = 0; } assert info.getSoftDelCount() == newDelCount diff --git a/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesDirectoryReaderWrapper.java b/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesDirectoryReaderWrapper.java index 2098f57910d..5214b97fdc5 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesDirectoryReaderWrapper.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesDirectoryReaderWrapper.java @@ -306,6 +306,12 @@ public class TestSoftDeletesDirectoryReaderWrapper extends LuceneTestCase { softDeletesField, MatchNoDocsQuery::new, mergePolicy)); writer.forceMerge(1); try (DirectoryReader reader = DirectoryReader.open(writer)) { + for (LeafReaderContext leafContext : reader.leaves()) { + assertThat(leafContext.reader(), instanceOf(SegmentReader.class)); + SegmentReader segmentReader = (SegmentReader) leafContext.reader(); + assertNull(segmentReader.getLiveDocs()); + assertNull(segmentReader.getHardLiveDocs()); + } SoftDeletesDirectoryReaderWrapper wrapped = new SoftDeletesDirectoryReaderWrapper(reader, softDeletesField); assertEquals(numDocs, wrapped.numDocs());