When we already know query evaluation will produce unique results, don't bother
using a Uniquifier in BatchStreamedCallback.
RELNOTES: None
PiperOrigin-RevId: 214807126
diff --git a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
index ca2ff3d..9bb1e30 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
@@ -76,6 +76,7 @@
import com.google.devtools.build.lib.query2.engine.QueryExpressionMapper;
import com.google.devtools.build.lib.query2.engine.QueryUtil.MinDepthUniquifierImpl;
import com.google.devtools.build.lib.query2.engine.QueryUtil.MutableKeyExtractorBackedMapImpl;
+import com.google.devtools.build.lib.query2.engine.QueryUtil.NonExceptionalUniquifier;
import com.google.devtools.build.lib.query2.engine.QueryUtil.ThreadSafeMutableKeyExtractorBackedSetImpl;
import com.google.devtools.build.lib.query2.engine.QueryUtil.UniquifierImpl;
import com.google.devtools.build.lib.query2.engine.StreamableQueryEnvironment;
@@ -402,7 +403,7 @@
BatchStreamedCallback batchCallback = new BatchStreamedCallback(
callback,
BATCH_CALLBACK_SIZE,
- createUniquifier());
+ createUniquifierForOuterBatchStreamedCallback(expr));
return super.evaluateQuery(expr, batchCallback);
}
@@ -633,8 +634,14 @@
}
@ThreadSafe
+ protected NonExceptionalUniquifier<Target> createUniquifierForOuterBatchStreamedCallback(
+ QueryExpression expr) {
+ return createUniquifier();
+ }
+
+ @ThreadSafe
@Override
- public UniquifierImpl<Target, ?> createUniquifier() {
+ public NonExceptionalUniquifier<Target> createUniquifier() {
return new UniquifierImpl<>(TargetKeyExtractor.INSTANCE);
}
@@ -1168,7 +1175,7 @@
// memory. We should have a threshold for when to invoke the callback with a batch, and also a
// separate, larger, bound on the number of targets being processed at the same time.
private final ThreadSafeOutputFormatterCallback<Target> callback;
- private final UniquifierImpl<Target, ?> uniquifier;
+ private final NonExceptionalUniquifier<Target> uniquifier;
private final Object pendingLock = new Object();
private List<Target> pending = new ArrayList<>();
private int batchThreshold;
@@ -1176,7 +1183,7 @@
private BatchStreamedCallback(
ThreadSafeOutputFormatterCallback<Target> callback,
int batchThreshold,
- UniquifierImpl<Target, ?> uniquifier) {
+ NonExceptionalUniquifier<Target> uniquifier) {
this.callback = callback;
this.batchThreshold = batchThreshold;
this.uniquifier = uniquifier;
diff --git a/src/main/java/com/google/devtools/build/lib/query2/engine/QueryUtil.java b/src/main/java/com/google/devtools/build/lib/query2/engine/QueryUtil.java
index 120d53b..fe072b6 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/engine/QueryUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/engine/QueryUtil.java
@@ -218,8 +218,48 @@
}
}
+ /** A {@link Uniquifier} whose methods do not throw {@link QueryException}. */
+ public interface NonExceptionalUniquifier<T> extends Uniquifier<T> {
+ @Override
+ boolean unique(T newElement);
+
+ @Override
+ ImmutableList<T> unique(Iterable<T> newElements);
+ }
+
+ /**
+ * A {@link NonExceptionalUniquifier} that doesn't do anything and always says an element is
+ * unique.
+ */
+ public static class NullUniquifierImpl<T> implements NonExceptionalUniquifier<T> {
+ private static final NullUniquifierImpl<Object> INSTANCE = new NullUniquifierImpl<>();
+
+ private NullUniquifierImpl() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> NullUniquifierImpl<T> instance() {
+ return (NullUniquifierImpl<T>) INSTANCE;
+ }
+
+ @Override
+ public boolean uniquePure(T newElement) {
+ return true;
+ }
+
+ @Override
+ public boolean unique(T newElement) {
+ return true;
+ }
+
+ @Override
+ public ImmutableList<T> unique(Iterable<T> newElements) {
+ return ImmutableList.copyOf(newElements);
+ }
+ }
+
/** A trivial {@link Uniquifier} implementation. */
- public static class UniquifierImpl<T, K> implements Uniquifier<T> {
+ public static class UniquifierImpl<T, K> implements NonExceptionalUniquifier<T> {
private final KeyExtractor<T, K> extractor;
private final Set<K> alreadySeen;