diff options
Diffstat (limited to 'java/com/google/gerrit/lucene/LuceneChangeIndex.java')
-rw-r--r-- | java/com/google/gerrit/lucene/LuceneChangeIndex.java | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/java/com/google/gerrit/lucene/LuceneChangeIndex.java index e7d47d0778..23ffdace48 100644 --- a/java/com/google/gerrit/lucene/LuceneChangeIndex.java +++ b/java/com/google/gerrit/lucene/LuceneChangeIndex.java @@ -64,8 +64,11 @@ import com.google.protobuf.MessageLite; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -360,9 +363,9 @@ public class LuceneChangeIndex implements ChangeIndex { final Set<String> fields = IndexUtils.changeFields(opts, schema.useLegacyNumericFields()); return new ChangeDataResults( executor.submit( - new Callable<List<Document>>() { + new Callable<Results>() { @Override - public List<Document> call() throws IOException { + public Results call() throws IOException { return doRead(fields); } @@ -377,8 +380,12 @@ public class LuceneChangeIndex implements ChangeIndex { @Override public ResultSet<FieldBundle> readRaw() { List<Document> documents; + Map<ChangeSubIndex, ScoreDoc> searchAfterBySubIndex; + try { - documents = doRead(IndexUtils.changeFields(opts, schema.useLegacyNumericFields())); + Results r = doRead(IndexUtils.changeFields(opts, schema.useLegacyNumericFields())); + documents = r.docs; + searchAfterBySubIndex = r.searchAfterBySubIndex; } catch (IOException e) { throw new StorageException(e); } @@ -399,29 +406,49 @@ public class LuceneChangeIndex implements ChangeIndex { public void close() { // Do nothing. } + + @Override + public Object searchAfter() { + return searchAfterBySubIndex; + } }; } - private List<Document> doRead(Set<String> fields) throws IOException { + private Results doRead(Set<String> fields) throws IOException { IndexSearcher[] searchers = new IndexSearcher[indexes.size()]; + Map<ChangeSubIndex, ScoreDoc> searchAfterBySubIndex = new HashMap<>(); try { - int realLimit = opts.start() + opts.limit(); - if (Integer.MAX_VALUE - opts.limit() < opts.start()) { - realLimit = Integer.MAX_VALUE; + int realPageSize = opts.start() + opts.pageSize(); + if (Integer.MAX_VALUE - opts.pageSize() < opts.start()) { + realPageSize = Integer.MAX_VALUE; } TopFieldDocs[] hits = new TopFieldDocs[indexes.size()]; for (int i = 0; i < indexes.size(); i++) { - searchers[i] = indexes.get(i).acquire(); - hits[i] = searchers[i].search(query, realLimit, sort); + ChangeSubIndex subIndex = indexes.get(i); + searchers[i] = subIndex.acquire(); + if (opts.searchAfter() != null && opts.searchAfter() instanceof HashMap) { + hits[i] = + searchers[i].searchAfter( + ((HashMap<ChangeSubIndex, ScoreDoc>) opts.searchAfter()).get(subIndex), + query, + realPageSize, + sort, + /* doDocScores= */ false, + /* doMaxScore= */ false); + } else { + hits[i] = searchers[i].search(query, realPageSize, sort); + } + searchAfterBySubIndex.put( + subIndex, Iterables.getLast(Arrays.asList(hits[i].scoreDocs), null)); } - TopDocs docs = TopDocs.merge(sort, realLimit, hits); + TopDocs docs = TopDocs.merge(sort, realPageSize, hits); List<Document> result = new ArrayList<>(docs.scoreDocs.length); for (int i = opts.start(); i < docs.scoreDocs.length; i++) { ScoreDoc sd = docs.scoreDocs[i]; result.add(searchers[sd.shardIndex].doc(sd.doc, fields)); } - return result; + return new Results(result, searchAfterBySubIndex); } finally { for (int i = 0; i < indexes.size(); i++) { if (searchers[i] != null) { @@ -436,11 +463,22 @@ public class LuceneChangeIndex implements ChangeIndex { } } + private static class Results { + List<Document> docs; + Map<ChangeSubIndex, ScoreDoc> searchAfterBySubIndex; + + public Results(List<Document> docs, Map<ChangeSubIndex, ScoreDoc> searchAfterBySubIndex) { + this.docs = docs; + this.searchAfterBySubIndex = searchAfterBySubIndex; + } + } + private class ChangeDataResults implements ResultSet<ChangeData> { - private final Future<List<Document>> future; + private final Future<Results> future; private final Set<String> fields; + private Map<ChangeSubIndex, ScoreDoc> searchAfterBySubIndex; - ChangeDataResults(Future<List<Document>> future, Set<String> fields) { + ChangeDataResults(Future<Results> future, Set<String> fields) { this.future = future; this.fields = fields; } @@ -453,7 +491,9 @@ public class LuceneChangeIndex implements ChangeIndex { @Override public ImmutableList<ChangeData> toList() { try { - List<Document> docs = future.get(); + Results r = future.get(); + List<Document> docs = r.docs; + searchAfterBySubIndex = r.searchAfterBySubIndex; ImmutableList.Builder<ChangeData> result = ImmutableList.builderWithExpectedSize(docs.size()); for (Document doc : docs) { @@ -473,6 +513,11 @@ public class LuceneChangeIndex implements ChangeIndex { public void close() { future.cancel(false /* do not interrupt Lucene */); } + + @Override + public Object searchAfter() { + return searchAfterBySubIndex; + } } private static ListMultimap<String, IndexableField> fields(Document doc, Set<String> fields) { |