LUCENE-9535: Commit DWPT bytes used before locking indexing (#1918)

Currently we calculate the ramBytesUsed by the DWPT under the flushControl
lock. We can do this calculation safely outside of the lock without any downside.
The FlushControl lock should be used with care since it's a central part of indexing
and might block all indexing.
This commit is contained in:
Simon Willnauer 2020-09-24 09:39:33 +02:00 committed by GitHub
parent cafa449769
commit c258905bd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 32 deletions

View File

@ -145,20 +145,6 @@ final class DocumentsWriterFlushControl implements Accountable, Closeable {
return true; return true;
} }
private synchronized void commitPerThreadBytes(DocumentsWriterPerThread perThread) {
final long delta = perThread.commitLastBytesUsed();
/*
* We need to differentiate here if we are pending since setFlushPending
* moves the perThread memory to the flushBytes and we could be set to
* pending during a delete
*/
if (perThread.isFlushPending()) {
flushBytes += delta;
} else {
activeBytes += delta;
}
assert updatePeaks(delta);
}
// only for asserts // only for asserts
private boolean updatePeaks(long delta) { private boolean updatePeaks(long delta) {
@ -170,10 +156,26 @@ final class DocumentsWriterFlushControl implements Accountable, Closeable {
return true; return true;
} }
synchronized DocumentsWriterPerThread doAfterDocument(DocumentsWriterPerThread perThread, boolean isUpdate) { DocumentsWriterPerThread doAfterDocument(DocumentsWriterPerThread perThread, boolean isUpdate) {
final long delta = perThread.getCommitLastBytesUsedDelta();
synchronized (this) {
// we need to commit this under lock but calculate it outside of the lock to minimize the time this lock is held
// per document. The reason we update this under lock is that we mark DWPTs as pending without acquiring it's
// lock in #setFlushPending and this also reads the committed bytes and modifies the flush/activeBytes.
// In the future we can clean this up to be more intuitive.
perThread.commitLastBytesUsed(delta);
try { try {
commitPerThreadBytes(perThread); /*
if (!perThread.isFlushPending()) { * We need to differentiate here if we are pending since setFlushPending
* moves the perThread memory to the flushBytes and we could be set to
* pending during a delete
*/
if (perThread.isFlushPending()) {
flushBytes += delta;
assert updatePeaks(delta);
} else {
activeBytes += delta;
assert updatePeaks(delta);
if (isUpdate) { if (isUpdate) {
flushPolicy.onUpdate(this, perThread); flushPolicy.onUpdate(this, perThread);
} else { } else {
@ -191,6 +193,7 @@ final class DocumentsWriterFlushControl implements Accountable, Closeable {
assert assertNumDocsSinceStalled(stalled) && assertMemory(); assert assertNumDocsSinceStalled(stalled) && assertMemory();
} }
} }
}
private DocumentsWriterPerThread checkout(DocumentsWriterPerThread perThread, boolean markPending) { private DocumentsWriterPerThread checkout(DocumentsWriterPerThread perThread, boolean markPending) {
assert Thread.holdsLock(this); assert Thread.holdsLock(this);

View File

@ -540,12 +540,21 @@ final class DocumentsWriterPerThread implements Accountable {
/** /**
* Commits the current {@link #ramBytesUsed()} and stores it's value for later reuse. * Commits the current {@link #ramBytesUsed()} and stores it's value for later reuse.
* The last committed bytes used can be retrieved via {@link #getLastCommittedBytesUsed()} * The last committed bytes used can be retrieved via {@link #getLastCommittedBytesUsed()}
*/
void commitLastBytesUsed(long delta) {
assert isHeldByCurrentThread();
assert getCommitLastBytesUsedDelta() == delta : "delta has changed";
lastCommittedBytesUsed += delta;
}
/**
* Calculates the delta between the last committed bytes used and the currently used ram.
* @see #commitLastBytesUsed(long)
* @return the delta between the current {@link #ramBytesUsed()} and the current {@link #getLastCommittedBytesUsed()} * @return the delta between the current {@link #ramBytesUsed()} and the current {@link #getLastCommittedBytesUsed()}
*/ */
long commitLastBytesUsed() { long getCommitLastBytesUsedDelta() {
assert isHeldByCurrentThread(); assert isHeldByCurrentThread();
long delta = ramBytesUsed() - lastCommittedBytesUsed; long delta = ramBytesUsed() - lastCommittedBytesUsed;
lastCommittedBytesUsed += delta;
return delta; return delta;
} }