Make InDependsOnOperator like a ChangeDataSource
To make InDependsOnOperator behave like a ChangesDataSource, make it
return an ORed list of ChangeIndexPredicates which will be processed as
a ChangeDataSource. Although ORing together a bunch of
ChangeIndexPredicates results in slower match()s then the previous
implementation, this is negligible with only a few changes (likely
unmeasurable in real life), as a ChangeDataSource it will not have to
get ANDed with status predicates when unqualifed, and even better, it
will get selected when ANDed with status sources as the source.
Change-Id: I0d4487ceef47e8b8416ea8403072d331de4d9d88
diff --git a/src/main/java/com/googlesource/gerrit/plugins/depends/on/InDependsOnOperator.java b/src/main/java/com/googlesource/gerrit/plugins/depends/on/InDependsOnOperator.java
index 35fde51..df52117 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/depends/on/InDependsOnOperator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/depends/on/InDependsOnOperator.java
@@ -15,18 +15,17 @@
package com.googlesource.gerrit.plugins.depends.on;
import com.google.gerrit.entities.Change;
-import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.index.query.PostFilterPredicate;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.ChangeIndexPredicate;
+import com.google.gerrit.server.query.change.ChangePredicates;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.ChangeQueryBuilder.ChangeOperatorFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import java.util.Collections;
+import java.util.List;
import java.util.Optional;
-import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,33 +34,8 @@
public class InDependsOnOperator implements ChangeOperatorFactory {
private static final Logger log = LoggerFactory.getLogger(InDependsOnOperator.class);
- public class InDependsOnPredicate extends PostFilterPredicate<ChangeData> {
- protected final Set<Change.Id> dependentChanges;
-
- public InDependsOnPredicate(String value) {
- super(InDependsOnOperator.FIELD, value);
- Optional<Change.Id> changeId = Change.Id.tryParse(value);
- dependentChanges =
- changeId.isPresent()
- ? changeMessageStore.load(changeId.get()).stream()
- .filter(DependsOn::isResolved)
- .map(d -> d.id())
- .collect(Collectors.toSet())
- : Collections.emptySet();
- }
-
- @Override
- public int getCost() {
- return 1;
- }
-
- @Override
- public boolean match(ChangeData changeData) throws StorageException {
- return dependentChanges.contains(changeData.getId());
- }
- }
-
public static final String FIELD = "in";
+
protected final ChangeMessageStore changeMessageStore;
@Inject
@@ -72,14 +46,17 @@
@Override
public Predicate<ChangeData> create(ChangeQueryBuilder builder, String value)
throws QueryParseException {
- try {
- return new InDependsOnPredicate(value);
- } catch (NumberFormatException ex) {
- throw new QueryParseException("Error in operator " + FIELD + ":" + value, ex);
- } catch (StorageException ex) {
- String message = "Error in operator " + FIELD + ":" + value;
- log.error(message, ex);
- throw new QueryParseException(message, ex);
+ Optional<Change.Id> changeId = Change.Id.tryParse(value);
+ if (changeId.isPresent()) {
+ List<Predicate<ChangeData>> predicates =
+ changeMessageStore.load(changeId.get()).stream()
+ .filter(DependsOn::isResolved)
+ .map(d -> ChangePredicates.idStr(d.id()))
+ .collect(Collectors.toList());
+ if (!predicates.isEmpty()) {
+ return Predicate.or(predicates);
+ }
}
+ return ChangeIndexPredicate.none();
}
}