summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/lucene/LuceneChangeIndex.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/gerrit/lucene/LuceneChangeIndex.java')
-rw-r--r--java/com/google/gerrit/lucene/LuceneChangeIndex.java73
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) {