From 0acf74420c1322687a6857c46043377384b05100 Mon Sep 17 00:00:00 2001 From: Jim Ferenczi Date: Thu, 28 Sep 2017 13:57:10 +0200 Subject: [PATCH] Change VersionFetchSubPhase to create doc values iterator once per segment (#26809) --- .../fetch/subphase/VersionFetchSubPhase.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/search/fetch/subphase/VersionFetchSubPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/subphase/VersionFetchSubPhase.java index 5f69230ca42..baa0c6e9551 100644 --- a/core/src/main/java/org/elasticsearch/search/fetch/subphase/VersionFetchSubPhase.java +++ b/core/src/main/java/org/elasticsearch/search/fetch/subphase/VersionFetchSubPhase.java @@ -18,32 +18,45 @@ */ package org.elasticsearch.search.fetch.subphase; +import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.NumericDocValues; -import org.elasticsearch.ElasticsearchException; +import org.apache.lucene.index.ReaderUtil; import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.index.mapper.VersionFieldMapper; +import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.internal.SearchContext; import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; public final class VersionFetchSubPhase implements FetchSubPhase { - @Override - public void hitExecute(SearchContext context, HitContext hitContext) { + public void hitsExecute(SearchContext context, SearchHit[] hits) throws IOException { if (context.version() == false || (context.storedFieldsContext() != null && context.storedFieldsContext().fetchFields() == false)) { return; } - long version = Versions.NOT_FOUND; - try { - NumericDocValues versions = hitContext.reader().getNumericDocValues(VersionFieldMapper.NAME); - if (versions != null && versions.advanceExact(hitContext.docId())) { + + hits = hits.clone(); // don't modify the incoming hits + Arrays.sort(hits, Comparator.comparingInt(SearchHit::docId)); + + int lastReaderId = -1; + NumericDocValues versions = null; + for (SearchHit hit : hits) { + int readerId = ReaderUtil.subIndex(hit.docId(), context.searcher().getIndexReader().leaves()); + LeafReaderContext subReaderContext = context.searcher().getIndexReader().leaves().get(readerId); + if (lastReaderId != readerId) { + versions = subReaderContext.reader().getNumericDocValues(VersionFieldMapper.NAME); + lastReaderId = readerId; + } + int docId = hit.docId() - subReaderContext.docBase; + long version = Versions.NOT_FOUND; + if (versions != null && versions.advanceExact(docId)) { version = versions.longValue(); } - } catch (IOException e) { - throw new ElasticsearchException("Could not retrieve version", e); + hit.version(version < 0 ? -1 : version); } - hitContext.hit().version(version < 0 ? -1 : version); } }