Project index: Add parent predicate

Enabling the search by parent enables the rewrite
of the ListChildProjects REST-API that extracts the children
of a project. Using the Lucene index avoids the full scan
of the ProjectCache and thus speedup the extraction and
reduce the JVM heap consumption.

Bug: Issue 10401
Change-Id: I568d6ba0e5a0bff391f57e2357de6d059d77fe5d
This commit is contained in:
David Ostrovsky 2019-01-29 20:42:38 +01:00 committed by Luca Milanesio
parent ef655ff6a4
commit 30b0a80290
4 changed files with 48 additions and 0 deletions

View File

@ -12,6 +12,11 @@ name:'NAME'::
+
Matches projects that have exactly the name 'NAME'.
[[parent]]
parent:'PARENT'::
+
Matches projects that have 'PARENT' as parent project.
[[inname]]
inname:'NAME'::
+

View File

@ -27,6 +27,10 @@ public class ProjectPredicates {
return new ProjectPredicate(ProjectField.NAME, nameKey.get());
}
public static Predicate<ProjectData> parent(Project.NameKey parentNameKey) {
return new ProjectPredicate(ProjectField.PARENT_NAME, parentNameKey.get());
}
public static Predicate<ProjectData> inname(String name) {
return new ProjectPredicate(ProjectField.NAME_PART, name.toLowerCase(Locale.US));
}

View File

@ -44,6 +44,11 @@ public class ProjectQueryBuilder extends QueryBuilder<ProjectData> {
return ProjectPredicates.name(new Project.NameKey(name));
}
@Operator
public Predicate<ProjectData> parent(String parentName) {
return ProjectPredicates.parent(new Project.NameKey(parentName));
}
@Operator
public Predicate<ProjectData> inname(String namePart) {
if (namePart.isEmpty()) {

View File

@ -20,6 +20,7 @@ import static java.util.stream.Collectors.toList;
import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.access.AccessSectionInfo;
import com.google.gerrit.extensions.api.access.PermissionInfo;
@ -49,6 +50,7 @@ import com.google.gerrit.server.account.Accounts;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.ManualRequestContext;
@ -65,6 +67,7 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@ -98,6 +101,8 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
@Inject protected AllProjectsName allProjects;
@Inject protected AllUsersName allUsers;
protected LifecycleManager lifecycle;
protected Injector injector;
protected ReviewDb db;
@ -192,6 +197,28 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
assertQuery("name:" + projectWithHyphen.name, projectWithHyphen);
}
@Test
public void byParent() throws Exception {
assertQuery("parent:project");
ProjectInfo parent = createProject(name("parent"));
assertQuery("parent:" + parent.name);
ProjectInfo child = createProject(name("child"), parent.name);
assertQuery("parent:" + parent.name, child);
}
@Test
public void byParentOfAllProjects() throws Exception {
Set<String> excludedProjects = ImmutableSet.of(allProjects.get(), allUsers.get());
ProjectInfo[] projects =
gApi.projects()
.list()
.get()
.stream()
.filter(p -> !excludedProjects.contains(p.name))
.toArray(s -> new ProjectInfo[s]);
assertQuery("parent:" + allProjects.get(), projects);
}
@Test
public void byInname() throws Exception {
String namePart = getSanitizedMethodName();
@ -329,6 +356,13 @@ public abstract class AbstractQueryProjectsTest extends GerritServerTests {
return gApi.projects().create(in).get();
}
protected ProjectInfo createProject(String name, String parent) throws Exception {
ProjectInput in = new ProjectInput();
in.name = name;
in.parent = parent;
return gApi.projects().create(in).get();
}
protected ProjectInfo createProjectWithDescription(String name, String description)
throws Exception {
ProjectInput in = new ProjectInput();