LUCENE-8384: Fix missing advance DVGen in PendingSoftDeletes

Today we only advance the docValues update generation in
PendingSoftDeletes for the soft-deletes field. If we update a
soft-deletes DV field, then update a non-soft-deletes DV field, then
onNewReader will consider that we never update DV field although we did.

This commit makes sure that we always advance the docValues update
generation when handling docValues update in PendingSoftDeletes.

Co-authored-by: Simon Willnauer <simonw@apache.org>
This commit is contained in:
Nhat Nguyen 2018-07-04 12:46:42 -04:00
parent 2aae3fb3d2
commit 7e548ba860
4 changed files with 30 additions and 5 deletions
lucene
CHANGES.txt
core/src

View File

@ -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

View File

@ -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() {

View File

@ -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;
}

View File

@ -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