Join starred changes with other operators in Lucene
Express the starredby:X operator as an OR tree of each legacy ID the user has starred. We assume users star relatively few changes and therefore the number of candidates that Lucene will need to lookup is low. Passing in the legacy IDs allows the starred table in the SQL database to remain the source of truth, until we find a strong case for users having hundreds of starred changes and needing to modify the query processing. Extending OrPredicate allows this operator to be seen by the query rewriters and ChangeIndex as though the user had searched for the specific ids, "(change:1 OR change:2 OR change:3)". Change-Id: I2b8f85891c0f5266507eabd75f53bc1ad056f142
This commit is contained in:
@@ -45,9 +45,6 @@ public class OrPredicate<T> extends Predicate<T> {
|
||||
c += p.getCost();
|
||||
}
|
||||
}
|
||||
if (t.size() < 2) {
|
||||
throw new IllegalArgumentException("Need at least two predicates");
|
||||
}
|
||||
children = t;
|
||||
cost = c;
|
||||
}
|
||||
@@ -101,7 +98,7 @@ public class OrPredicate<T> extends Predicate<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
public String toString() {
|
||||
final StringBuilder r = new StringBuilder();
|
||||
r.append("(");
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
|
||||
@@ -14,15 +14,21 @@
|
||||
|
||||
package com.google.gerrit.server.query.change;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||
import com.google.gerrit.server.CurrentUser;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.query.OperatorPredicate;
|
||||
import com.google.gerrit.server.query.OrPredicate;
|
||||
import com.google.gerrit.server.query.Predicate;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
import com.google.gwtorm.server.ResultSet;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
class IsStarredByPredicate extends OperatorPredicate<ChangeData> implements
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
class IsStarredByPredicate extends OrPredicate<ChangeData> implements
|
||||
ChangeDataSource {
|
||||
private static String describe(CurrentUser user) {
|
||||
if (user instanceof IdentifiedUser) {
|
||||
@@ -31,11 +37,21 @@ class IsStarredByPredicate extends OperatorPredicate<ChangeData> implements
|
||||
return user.toString();
|
||||
}
|
||||
|
||||
private static List<Predicate<ChangeData>> predicates(
|
||||
Provider<ReviewDb> db,
|
||||
Set<Change.Id> ids) {
|
||||
List<Predicate<ChangeData>> r = Lists.newArrayListWithCapacity(ids.size());
|
||||
for (Change.Id id : ids) {
|
||||
r.add(new LegacyChangeIdPredicate(db, id));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private final Provider<ReviewDb> db;
|
||||
private final CurrentUser user;
|
||||
|
||||
IsStarredByPredicate(Provider<ReviewDb> db, CurrentUser user) {
|
||||
super(ChangeQueryBuilder.FIELD_STARREDBY, describe(user));
|
||||
super(predicates(db, user.getStarredChanges()));
|
||||
this.db = db;
|
||||
this.user = user;
|
||||
}
|
||||
@@ -65,4 +81,14 @@ class IsStarredByPredicate extends OperatorPredicate<ChangeData> implements
|
||||
public int getCost() {
|
||||
return ChangeCosts.cost(ChangeCosts.IDS_MEMORY, getCardinality());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String val = describe(user);
|
||||
if (val.indexOf(' ') < 0) {
|
||||
return ChangeQueryBuilder.FIELD_STARREDBY + ":" + val;
|
||||
} else {
|
||||
return ChangeQueryBuilder.FIELD_STARREDBY + ":\"" + val + "\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user