Change VersionFetchSubPhase to create doc values iterator once per segment (#26809)

This commit is contained in:
Jim Ferenczi 2017-09-28 13:57:10 +02:00 committed by GitHub
parent 1ccb497c0d
commit 0acf74420c
1 changed files with 23 additions and 10 deletions

View File

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