diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java index 37f2539d0f0..ec6ced68002 100644 --- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriter.java @@ -167,7 +167,11 @@ final class DocumentsWriter implements Closeable, Accountable { private boolean applyAllDeletes() throws IOException { final DocumentsWriterDeleteQueue deleteQueue = this.deleteQueue; - if (flushControl.isFullFlush() == false + // Check the applyAllDeletes flag first. This helps exit early most of the time without checking + // isFullFlush(), which takes a lock and introduces contention on small documents that are quick + // to index. + if (flushControl.getApplyAllDeletes() + && flushControl.isFullFlush() == false // never apply deletes during full flush this breaks happens before relationship. && deleteQueue.isOpen() // if it's closed then it's already fully applied and we have a new delete queue diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java index 64acae6ec7b..9021a588f10 100644 --- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java +++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java @@ -509,6 +509,14 @@ final class DocumentsWriterFlushControl implements Accountable, Closeable { return flushDeletes.getAndSet(false); } + /** + * Check whether deletes need to be applied. This can be used as a pre-flight check before calling + * {@link #getAndResetApplyAllDeletes()} to make sure that a single thread applies deletes. + */ + public boolean getApplyAllDeletes() { + return flushDeletes.get(); + } + public void setApplyAllDeletes() { flushDeletes.set(true); }