diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 8a094e695c9..c2a3cca1c82 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -168,6 +168,9 @@ Bug Fixes: * LUCENE-8381: Fix IndexWriter incorrectly interprets hard-deletes as soft-deletes while wrapping reader for merges. (Simon Willnauer, Nhat Nguyen) + * LUCENE-8384: Fix missing advance docValues generation while handling docValues + update in PendingSoftDeletes. (Simon Willnauer, Nhat Nguyen) + ======================= Lucene 7.4.0 ======================= Upgrading 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 4074903a363..eb6e4ff3604 100644 --- a/lucene/core/src/java/org/apache/lucene/index/PendingSoftDeletes.java +++ b/lucene/core/src/java/org/apache/lucene/index/PendingSoftDeletes.java @@ -146,12 +146,12 @@ final class PendingSoftDeletes extends PendingDeletes { if (this.field.equals(info.name)) { pendingDeleteCount += applySoftDeletes(iterator, getMutableBits()); assert assertPendingDeletes(); - assert dvGeneration < info.getDocValuesGen() : "we have seen this generation update already: " + dvGeneration + " vs. " + info.getDocValuesGen(); - assert dvGeneration != -2 : "docValues generation is still uninitialized"; - dvGeneration = info.getDocValuesGen(); this.info.setSoftDelCount(this.info.getSoftDelCount() + pendingDeleteCount); super.dropChanges(); } + assert dvGeneration < info.getDocValuesGen() : "we have seen this generation update already: " + dvGeneration + " vs. " + info.getDocValuesGen(); + assert dvGeneration != -2 : "docValues generation is still uninitialized"; + dvGeneration = info.getDocValuesGen(); } private boolean assertPendingDeletes() { diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentCommitInfo.java b/lucene/core/src/java/org/apache/lucene/index/SegmentCommitInfo.java index 954a1382a48..69117574698 100644 --- a/lucene/core/src/java/org/apache/lucene/index/SegmentCommitInfo.java +++ b/lucene/core/src/java/org/apache/lucene/index/SegmentCommitInfo.java @@ -328,7 +328,7 @@ public class SegmentCommitInfo { if (delCount < 0 || delCount > info.maxDoc()) { throw new IllegalArgumentException("invalid delCount=" + delCount + " (maxDoc=" + info.maxDoc() + ")"); } - assert softDelCount + delCount <= info.maxDoc(); + assert softDelCount + delCount <= info.maxDoc() : "maxDoc=" + info.maxDoc() + ",delCount=" + delCount + ",softDelCount=" + softDelCount; this.delCount = delCount; } @@ -336,7 +336,7 @@ public class SegmentCommitInfo { if (softDelCount < 0 || softDelCount > info.maxDoc()) { throw new IllegalArgumentException("invalid softDelCount=" + softDelCount + " (maxDoc=" + info.maxDoc() + ")"); } - assert softDelCount + delCount <= info.maxDoc(); + assert softDelCount + delCount <= info.maxDoc() : "maxDoc=" + info.maxDoc() + ",delCount=" + delCount + ",softDelCount=" + softDelCount; this.softDelCount = softDelCount; } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesRetentionMergePolicy.java b/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesRetentionMergePolicy.java index bb36ba300f0..ee2b6508585 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesRetentionMergePolicy.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestSoftDeletesRetentionMergePolicy.java @@ -40,6 +40,8 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; +import org.apache.lucene.search.SearcherFactory; +import org.apache.lucene.search.SearcherManager; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; @@ -607,6 +609,26 @@ public class TestSoftDeletesRetentionMergePolicy extends LuceneTestCase { IOUtils.close(writer, dir); } + public void testSoftDeleteWithTryUpdateDocValue() throws Exception { + Directory dir = newDirectory(); + IndexWriterConfig config = newIndexWriterConfig().setSoftDeletesField("soft_delete") + .setMergePolicy(new SoftDeletesRetentionMergePolicy("soft_delete", MatchAllDocsQuery::new, newLogMergePolicy())); + IndexWriter writer = new IndexWriter(dir, config); + SearcherManager sm = new SearcherManager(writer, new SearcherFactory()); + Document d = new Document(); + d.add(new StringField("id", "0", Field.Store.YES)); + writer.addDocument(d); + sm.maybeRefreshBlocking(); + doUpdate(new Term("id", "0"), writer, + new NumericDocValuesField("soft_delete", 1), new NumericDocValuesField("other-field", 1)); + sm.maybeRefreshBlocking(); + assertEquals(1, writer.segmentInfos.asList().size()); + SegmentCommitInfo si = writer.segmentInfos.asList().get(0); + assertEquals(1, si.getSoftDelCount()); + assertEquals(1, si.info.maxDoc()); + IOUtils.close(sm, writer, dir); + } + static void doUpdate(Term doc, IndexWriter writer, Field... fields) throws IOException { long seqId = -1; do { // retry if we just committing a merge