Skip to content

Commit 2eea5f2

Browse files
authored
Speed up InternalEngine#resolveDocVersion(...) method (#122374) (#122641)
Use reference manager to get index reader instead of acquiring a searcher. The latter involves creating an index searcher, which is not used and expensive as part of the `resolveDocVersion(...)` method, because this method is invoked for each document that gets indexed.
1 parent 55ac929 commit 2eea5f2

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import org.elasticsearch.common.util.concurrent.ThreadContext;
6868
import org.elasticsearch.core.Assertions;
6969
import org.elasticsearch.core.Booleans;
70+
import org.elasticsearch.core.CheckedFunction;
7071
import org.elasticsearch.core.IOUtils;
7172
import org.elasticsearch.core.Nullable;
7273
import org.elasticsearch.core.Releasable;
@@ -1020,24 +1021,17 @@ private VersionValue resolveDocVersion(final Operation op, boolean loadSeqNo) th
10201021
VersionValue versionValue = getVersionFromMap(op.uid());
10211022
if (versionValue == null) {
10221023
assert incrementIndexVersionLookup(); // used for asserting in tests
1023-
final VersionsAndSeqNoResolver.DocIdAndVersion docIdAndVersion;
1024-
try (Searcher searcher = acquireSearcher("load_version", SearcherScope.INTERNAL)) {
1025-
if (engineConfig.getIndexSettings().getMode() == IndexMode.TIME_SERIES) {
1026-
assert engineConfig.getLeafSorter() == DataStream.TIMESERIES_LEAF_READERS_SORTER;
1027-
docIdAndVersion = VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(
1028-
searcher.getIndexReader(),
1029-
op.uid(),
1030-
op.id(),
1031-
loadSeqNo
1032-
);
1033-
} else {
1034-
docIdAndVersion = VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(
1035-
searcher.getIndexReader(),
1036-
op.uid(),
1037-
loadSeqNo
1038-
);
1024+
final VersionsAndSeqNoResolver.DocIdAndVersion docIdAndVersion = performActionWithDirectoryReader(
1025+
SearcherScope.INTERNAL,
1026+
directoryReader -> {
1027+
if (engineConfig.getIndexSettings().getMode() == IndexMode.TIME_SERIES) {
1028+
assert engineConfig.getLeafSorter() == DataStream.TIMESERIES_LEAF_READERS_SORTER;
1029+
return VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(directoryReader, op.uid(), op.id(), loadSeqNo);
1030+
} else {
1031+
return VersionsAndSeqNoResolver.timeSeriesLoadDocIdAndVersion(directoryReader, op.uid(), loadSeqNo);
1032+
}
10391033
}
1040-
}
1034+
);
10411035
if (docIdAndVersion != null) {
10421036
versionValue = new IndexVersionValue(null, docIdAndVersion.version, docIdAndVersion.seqNo, docIdAndVersion.primaryTerm);
10431037
}
@@ -3454,4 +3448,26 @@ public LiveVersionMap getLiveVersionMap() {
34543448
protected long getPreCommitSegmentGeneration() {
34553449
return preCommitSegmentGeneration.get();
34563450
}
3451+
3452+
<T> T performActionWithDirectoryReader(SearcherScope scope, CheckedFunction<DirectoryReader, T, IOException> action)
3453+
throws EngineException {
3454+
assert scope == SearcherScope.INTERNAL : "performActionWithDirectoryReader(...) isn't prepared for external usage";
3455+
assert store.hasReferences();
3456+
try {
3457+
ReferenceManager<ElasticsearchDirectoryReader> referenceManager = getReferenceManager(scope);
3458+
ElasticsearchDirectoryReader acquire = referenceManager.acquire();
3459+
try {
3460+
return action.apply(acquire);
3461+
} finally {
3462+
referenceManager.release(acquire);
3463+
}
3464+
} catch (AlreadyClosedException ex) {
3465+
throw ex;
3466+
} catch (Exception ex) {
3467+
maybeFailEngine("perform_action_directory_reader", ex);
3468+
ensureOpen(ex); // throw EngineCloseException here if we are already closed
3469+
logger.error("failed to perform action with directory reader", ex);
3470+
throw new EngineException(shardId, "failed to perform action with directory reader", ex);
3471+
}
3472+
}
34573473
}

0 commit comments

Comments
 (0)