Implement Paginated interface for index searches
To support pagination, we need to be able to restart a search from a particular sort key. In the SQL index implementation, this is done using a combination of rewrite rules and ChangeAccess methods for scanning around the sort key. This approach does not quite work for the secondary index, which is much less rewrite-heavy. Teach IndexedChangeQuery to replace SortKeyPredicate leaves in a predicate tree with a new predicate having a different cut point. This is a simple recursive algorithm since we explicitly do not try to deal with the case of multiple sort key predicates in different subtrees. Such queries are already documented to have unpredictable behavior (since in the SQL implementation it is non-obvious which of a number of such predicates is chosen as the source and which are used for filtering). Change-Id: Ia839eb21086b64be2bebdcc71aa579b8c99a2fd8
This commit is contained in:
@@ -214,7 +214,7 @@ public class IndexRewriteTest extends TestCase {
|
||||
|
||||
private IndexedChangeQuery query(Predicate<ChangeData> p, int limit)
|
||||
throws QueryParseException {
|
||||
return new IndexedChangeQuery(index, p, limit);
|
||||
return new IndexedChangeQuery(null, index, p, limit);
|
||||
}
|
||||
|
||||
private Set<Change.Status> status(String query) throws QueryParseException {
|
||||
|
@@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2013 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.package com.google.gerrit.server.git;
|
||||
|
||||
package com.google.gerrit.server.index;
|
||||
|
||||
import static com.google.gerrit.server.index.IndexedChangeQuery.replaceSortKeyPredicates;
|
||||
|
||||
import com.google.gerrit.server.query.Predicate;
|
||||
import com.google.gerrit.server.query.QueryParseException;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class IndexedChangeQueryTest extends TestCase {
|
||||
private FakeIndex index;
|
||||
private ChangeQueryBuilder queryBuilder;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
index = new FakeIndex(FakeIndex.V2);
|
||||
IndexCollection indexes = new IndexCollection();
|
||||
indexes.setSearchIndex(index);
|
||||
queryBuilder = new FakeQueryBuilder(indexes);
|
||||
}
|
||||
|
||||
public void testReplaceSortKeyPredicate_NoSortKey() throws Exception {
|
||||
Predicate<ChangeData> p = parse("foo:a bar:b OR (foo:b bar:a)");
|
||||
assertSame(p, replaceSortKeyPredicates(p, "1234"));
|
||||
}
|
||||
|
||||
public void testReplaceSortKeyPredicate_TopLevelSortKey() throws Exception {
|
||||
Predicate<ChangeData> p;
|
||||
p = parse("foo:a bar:b sortkey_before:1234 OR (foo:b bar:a)");
|
||||
assertEquals(parse("foo:a bar:b sortkey_before:5678 OR (foo:b bar:a)"),
|
||||
replaceSortKeyPredicates(p, "5678"));
|
||||
p = parse("foo:a bar:b sortkey_after:1234 OR (foo:b bar:a)");
|
||||
assertEquals(parse("foo:a bar:b sortkey_after:5678 OR (foo:b bar:a)"),
|
||||
replaceSortKeyPredicates(p, "5678"));
|
||||
}
|
||||
|
||||
public void testReplaceSortKeyPredicate_NestedSortKey() throws Exception {
|
||||
Predicate<ChangeData> p;
|
||||
p = parse("foo:a bar:b OR (foo:b bar:a AND sortkey_before:1234)");
|
||||
assertEquals(parse("foo:a bar:b OR (foo:b bar:a sortkey_before:5678)"),
|
||||
replaceSortKeyPredicates(p, "5678"));
|
||||
p = parse("foo:a bar:b OR (foo:b bar:a AND sortkey_after:1234)");
|
||||
assertEquals(parse("foo:a bar:b OR (foo:b bar:a sortkey_after:5678)"),
|
||||
replaceSortKeyPredicates(p, "5678"));
|
||||
}
|
||||
|
||||
private Predicate<ChangeData> parse(String query) throws QueryParseException {
|
||||
return queryBuilder.parse(query);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user