Skip to content

Commit 584cafa

Browse files
committed
map -> multiMap for pullUp rules
1 parent fe71920 commit 584cafa

File tree

18 files changed

+156
-97
lines changed

18 files changed

+156
-97
lines changed

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/AggregateIndexExpansionVisitor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.google.common.collect.ImmutableList;
5454
import com.google.common.collect.ImmutableMap;
5555
import com.google.common.collect.ImmutableSet;
56+
import com.google.common.collect.Iterables;
5657
import com.google.common.collect.Lists;
5758
import com.google.common.collect.Sets;
5859

@@ -246,7 +247,7 @@ protected NonnullPair<Quantifier, List<Placeholder>> constructGroupBy(@Nonnull f
246247
throw new RecordCoreException("could not pull grouped value " + groupedValue)
247248
.addLogInfo(LogMessageKeys.VALUE, groupedValue);
248249
}
249-
argument = result.get(groupedValue);
250+
argument = Iterables.getOnlyElement(result.get(groupedValue));
250251
} else {
251252
throw new RecordCoreException("unable to plan group by with non-field value")
252253
.addLogInfo(LogMessageKeys.VALUE, groupedValue);
@@ -272,7 +273,7 @@ protected NonnullPair<Quantifier, List<Placeholder>> constructGroupBy(@Nonnull f
272273
throw new RecordCoreException("could not pull grouping value " + groupingValue)
273274
.addLogInfo(LogMessageKeys.VALUE, groupingValue);
274275
}
275-
return pulledUpGroupingValuesMap.get(groupingValue);
276+
return Iterables.getOnlyElement(pulledUpGroupingValuesMap.get(groupingValue));
276277
}).collect(ImmutableList.toImmutableList());
277278

278279
final var groupingColsValue = RecordConstructorValue.ofUnnamed(pulledUpGroupingValues);

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/BitmapAggregateIndexExpansionVisitor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.google.common.base.Verify;
4242
import com.google.common.collect.ImmutableList;
4343
import com.google.common.collect.ImmutableSet;
44+
import com.google.common.collect.Iterables;
4445
import com.google.common.collect.Sets;
4546

4647
import javax.annotation.Nonnull;
@@ -82,7 +83,7 @@ protected NonnullPair<Quantifier, List<Placeholder>> constructGroupBy(@Nonnull f
8283
throw new RecordCoreException("could not pull grouped value " + groupedValue)
8384
.addLogInfo(LogMessageKeys.VALUE, groupedValue);
8485
}
85-
argument = result.get(groupedValue);
86+
argument = Iterables.getOnlyElement(result.get(groupedValue));
8687
} else {
8788
throw new UnsupportedOperationException("unable to plan group by with non-field value " + groupedValue);
8889
}
@@ -114,7 +115,7 @@ protected NonnullPair<Quantifier, List<Placeholder>> constructGroupBy(@Nonnull f
114115
throw new RecordCoreException("could not pull grouping value " + groupingValue)
115116
.addLogInfo(LogMessageKeys.VALUE, groupingValue);
116117
}
117-
return pulledUpGroupingValuesMap.get(groupingValue);
118+
return Iterables.getOnlyElement(pulledUpGroupingValuesMap.get(groupingValue));
118119
}).collect(ImmutableList.toImmutableList());
119120

120121
final var pulledUpGroupingValues = ImmutableList.<Value>builder().addAll(explicitPulledUpGroupingValues).add(implicitGroupingValue).build();

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/KeyExpressionExpansionVisitor.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.google.common.base.Verify;
4545
import com.google.common.collect.ImmutableList;
4646
import com.google.common.collect.ImmutableSet;
47+
import com.google.common.collect.Iterables;
4748
import com.google.common.collect.Lists;
4849

4950
import javax.annotation.Nonnull;
@@ -349,7 +350,7 @@ private static ImmutableList<Placeholder> pullUpPlaceholders(@Nonnull final Grap
349350
final var pulledUpValue = pulledUpPlaceholderValuesMap.get(value);
350351
final var parameterAlias =
351352
Objects.requireNonNull(childExpansionPlaceholderValuesMap.get(value));
352-
return Placeholder.newInstanceWithoutRanges(pulledUpValue, parameterAlias);
353+
return Placeholder.newInstanceWithoutRanges(Iterables.getOnlyElement(pulledUpValue), parameterAlias);
353354
})
354355
.collect(ImmutableList.toImmutableList());
355356
}
@@ -372,7 +373,7 @@ private static ImmutableList<Column<? extends Value>> pullUpResultColumns(@Nonnu
372373
throw new RecordCoreException("could not pull expansion value " + value)
373374
.addLogInfo(LogMessageKeys.VALUE, value);
374375
}
375-
return pulledUpValuesMap.get(value);
376+
return Iterables.getOnlyElement(pulledUpValuesMap.get(value));
376377
})
377378
.map(Column::unnamedOf)
378379
.collect(ImmutableList.toImmutableList());

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/MatchInfo.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ static ImmutableBiMap<Value, Value> adjustMatchedValueMap(@Nonnull final Correla
121121
candidateLowerExpression.getCorrelatedTo()),
122122
candidateAlias);
123123
final var pulledUpCandidateAggregateValue = candidatePullUpMap.get(candidateAggregateValue);
124-
if (pulledUpCandidateAggregateValue != null) {
125-
adjustedMatchedAggregateMapBuilder.put(queryAggregateValue, pulledUpCandidateAggregateValue);
124+
if (!pulledUpCandidateAggregateValue.isEmpty()) {
125+
adjustedMatchedAggregateMapBuilder.put(queryAggregateValue, Iterables.getOnlyElement(pulledUpCandidateAggregateValue));
126126
}
127127
}
128128
return adjustedMatchedAggregateMapBuilder.build();
@@ -506,10 +506,10 @@ public static GroupByMappings pullUpGroupByMappings(@Nonnull final PartialMatch
506506
Sets.difference(queryAggregateValue.getCorrelatedToWithoutChildren(),
507507
queryExpression.getCorrelatedTo()), queryAlias);
508508
final var pulledUpQueryAggregateValue = pullUpMap.get(queryAggregateValue);
509-
if (pulledUpQueryAggregateValue == null) {
509+
if (pulledUpQueryAggregateValue.isEmpty()) {
510510
return GroupByMappings.empty();
511511
}
512-
unmatchedAggregateMapBuilder.put(unmatchedAggregateMapEntry.getKey(), pulledUpQueryAggregateValue);
512+
unmatchedAggregateMapBuilder.put(unmatchedAggregateMapEntry.getKey(), Iterables.getOnlyElement(pulledUpQueryAggregateValue));
513513
}
514514

515515
return GroupByMappings.of(matchedGroupingsMap, matchedAggregatesMap, unmatchedAggregateMapBuilder.build());
@@ -527,8 +527,8 @@ private static ImmutableBiMap<Value, Value> pullUpMatchedValueMap(@Nonnull final
527527
final var pullUpMap =
528528
queryResultValue.pullUp(ImmutableList.of(queryValue), EvaluationContext.empty(),
529529
AliasMap.emptyMap(), constantAliases, queryAlias);
530-
final Value pulledUpQueryValue = pullUpMap.get(queryValue);
531-
if (pulledUpQueryValue == null) {
530+
final var pulledUpQueryValue = pullUpMap.get(queryValue);
531+
if (pulledUpQueryValue.isEmpty()) {
532532
continue;
533533
}
534534

@@ -544,10 +544,10 @@ private static ImmutableBiMap<Value, Value> pullUpMatchedValueMap(@Nonnull final
544544
candidateLowerExpression.getCorrelatedTo()),
545545
candidateAlias);
546546
final var pulledUpCandidateAggregateValue = candidatePullUpMap.get(candidateAggregateValue);
547-
if (pulledUpCandidateAggregateValue == null) {
547+
if (pulledUpCandidateAggregateValue.isEmpty()) {
548548
continue;
549549
}
550-
matchedAggregatesMapBuilder.put(pulledUpQueryValue, pulledUpCandidateAggregateValue);
550+
matchedAggregatesMapBuilder.put(Iterables.getOnlyElement(pulledUpQueryValue), Iterables.getOnlyElement(pulledUpCandidateAggregateValue));
551551
}
552552
return matchedAggregatesMapBuilder.build();
553553
}

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/Ordering.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import java.util.function.BiPredicate;
5858
import java.util.function.Function;
5959
import java.util.function.Supplier;
60+
import java.util.stream.Collectors;
6061

6162
/**
6263
* This class captures an ordering property.
@@ -400,15 +401,24 @@ public Ordering pullUp(@Nonnull final Value value, @Nonnull EvaluationContext ev
400401
final var pulledUpBindings =
401402
translateBindings(entry.getValue(),
402403
toBePulledUpValues -> value.pullUp(toBePulledUpValues, evaluationContext,
403-
aliasMap, constantAliases, Quantifier.current()));
404+
aliasMap, constantAliases, Quantifier.current()).asMap().entrySet().stream()
405+
.collect(Collectors.toMap(
406+
Map.Entry::getKey,
407+
e -> e.getValue().iterator().next() // first element
408+
)));
404409
pulledUpBindingMapBuilder.putAll(entry.getKey(), pulledUpBindings);
405410
}
406411

407412
// pull up the values we actually could also pull up some of the bindings for
408413
final var pulledUpBindingMap = pulledUpBindingMapBuilder.build();
409414
final var pulledUpValuesMap =
410415
value.pullUp(pulledUpBindingMap.keySet(), evaluationContext, aliasMap, constantAliases,
411-
Quantifier.current());
416+
Quantifier.current())
417+
.asMap().entrySet().stream()
418+
.collect(Collectors.toMap(
419+
Map.Entry::getKey,
420+
e -> e.getValue().iterator().next() // first element
421+
));
412422

413423
final var mappedOrderingSet = getOrderingSet().mapAll(pulledUpValuesMap);
414424
final var mappedValues = mappedOrderingSet.getSet();

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/values/QuantifiedValue.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
import com.apple.foundationdb.record.query.plan.cascades.ConstrainedBoolean;
2727
import com.apple.foundationdb.record.query.plan.cascades.CorrelationIdentifier;
2828
import com.apple.foundationdb.record.query.plan.cascades.values.translation.TranslationMap;
29-
import com.google.common.collect.ImmutableMap;
29+
import com.google.common.collect.ImmutableMultimap;
3030
import com.google.common.collect.ImmutableSet;
31+
import com.google.common.collect.Multimap;
3132
import com.google.common.collect.Streams;
3233

3334
import javax.annotation.Nonnull;
34-
import java.util.Map;
3535
import java.util.Set;
3636

3737
/**
@@ -58,11 +58,11 @@ default ConstrainedBoolean equalsWithoutChildren(@Nonnull final Value other) {
5858

5959
@Nonnull
6060
@Override
61-
default Map<Value, Value> pullUp(@Nonnull final Iterable<? extends Value> toBePulledUpValues,
62-
@Nonnull final EvaluationContext evaluationContext,
63-
@Nonnull final AliasMap aliasMap,
64-
@Nonnull final Set<CorrelationIdentifier> constantAliases,
65-
@Nonnull final CorrelationIdentifier upperBaseAlias) {
61+
default Multimap<Value, Value> pullUp(@Nonnull final Iterable<? extends Value> toBePulledUpValues,
62+
@Nonnull final EvaluationContext evaluationContext,
63+
@Nonnull final AliasMap aliasMap,
64+
@Nonnull final Set<CorrelationIdentifier> constantAliases,
65+
@Nonnull final CorrelationIdentifier upperBaseAlias) {
6666
final var alias = getAlias();
6767
final var areSimpleReferences =
6868
Streams.stream(toBePulledUpValues)
@@ -71,7 +71,7 @@ default Map<Value, Value> pullUp(@Nonnull final Iterable<? extends Value> toBePu
7171
if (areSimpleReferences) {
7272
final var translationMap =
7373
TranslationMap.rebaseWithAliasMap(AliasMap.ofAliases(alias, upperBaseAlias));
74-
final var translatedMapBuilder = ImmutableMap.<Value, Value>builder();
74+
final var translatedMapBuilder = ImmutableMultimap.<Value, Value>builder();
7575
for (final var toBePulledUpValue : toBePulledUpValues) {
7676
translatedMapBuilder.put(toBePulledUpValue, toBePulledUpValue.translateCorrelations(translationMap));
7777
}

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/values/Value.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@
6969
import com.google.common.base.Functions;
7070
import com.google.common.base.Verify;
7171
import com.google.common.collect.ImmutableList;
72-
import com.google.common.collect.ImmutableMap;
72+
import com.google.common.collect.ImmutableMultimap;
7373
import com.google.common.collect.ImmutableSet;
7474
import com.google.common.collect.Iterables;
75+
import com.google.common.collect.Multimap;
7576
import com.google.common.collect.Streams;
7677
import com.google.common.primitives.ImmutableIntArray;
7778
import com.google.protobuf.Message;
@@ -81,7 +82,6 @@
8182
import java.util.Collection;
8283
import java.util.Iterator;
8384
import java.util.List;
84-
import java.util.Map;
8585
import java.util.Objects;
8686
import java.util.Optional;
8787
import java.util.Set;
@@ -508,30 +508,27 @@ default Value simplify(@Nonnull final EvaluationContext evaluationContext,
508508
* resulting values of the pull-up logic
509509
*/
510510
@Nonnull
511-
default Map<Value, Value> pullUp(@Nonnull final Iterable<? extends Value> toBePulledUpValues,
512-
@Nonnull final EvaluationContext evaluationContext,
513-
@Nonnull final AliasMap aliasMap,
514-
@Nonnull final Set<CorrelationIdentifier> constantAliases,
515-
@Nonnull final CorrelationIdentifier upperBaseAlias) {
511+
default Multimap<Value, Value> pullUp(@Nonnull final Iterable<? extends Value> toBePulledUpValues,
512+
@Nonnull final EvaluationContext evaluationContext,
513+
@Nonnull final AliasMap aliasMap,
514+
@Nonnull final Set<CorrelationIdentifier> constantAliases,
515+
@Nonnull final CorrelationIdentifier upperBaseAlias) {
516516
final var resultPair =
517517
Simplification.compute(this, evaluationContext, toBePulledUpValues, aliasMap, constantAliases,
518518
PullUpValueRuleSet.ofPullUpValueRules());
519519
if (resultPair == null) {
520-
return ImmutableMap.of();
520+
return ImmutableMultimap.of();
521521
}
522522

523523
final var matchedValuesMap = resultPair.getRight();
524-
final var resultsMapBuilder = ImmutableMap.<Value, Value>builder();
524+
final var resultsMapBuilder = ImmutableMultimap.<Value, Value>builder();
525525
for (final var toBePulledUpValue : toBePulledUpValues) {
526-
final var compensation = matchedValuesMap.get(toBePulledUpValue);
527-
if (compensation != null) {
528-
resultsMapBuilder.put(toBePulledUpValue,
529-
compensation.compensate(
530-
QuantifiedObjectValue.of(upperBaseAlias, this.getResultType())));
531-
}
526+
matchedValuesMap.getOrDefault(toBePulledUpValue, ImmutableList.of())
527+
.forEach(compensation -> resultsMapBuilder.put(toBePulledUpValue,
528+
compensation.compensate(QuantifiedObjectValue.of(upperBaseAlias, this.getResultType()))));
532529
}
533530

534-
return resultsMapBuilder.buildKeepingLast();
531+
return resultsMapBuilder.build();
535532
}
536533

537534
/**
@@ -547,7 +544,7 @@ default Map<Value, Value> pullUp(@Nonnull final Iterable<? extends Value> toBePu
547544
* @param aliasMap an alias map of equalities
548545
* @param constantAliases a set of aliases that are considered to be constant
549546
* @param upperBaseAlias an alias to be treated as <em>current</em> alias
550-
* @return a map from {@link Value} to {@link Value} that related the values that the called passed in with the
547+
* @return a list of {@link Value}s that related the values that the called passed in with the
551548
* resulting values of the pull-up logic
552549
*/
553550
@Nonnull

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/values/simplification/CompensateRecordConstructorRule.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
import com.apple.foundationdb.record.query.plan.cascades.values.FieldValue;
2727
import com.apple.foundationdb.record.query.plan.cascades.values.RecordConstructorValue;
2828
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
29+
import com.google.common.collect.ImmutableList;
2930

3031
import javax.annotation.Nonnull;
32+
import java.util.List;
3133
import java.util.Map;
3234

3335
import static com.apple.foundationdb.record.query.plan.cascades.matching.structure.MultiMatcher.all;
@@ -44,7 +46,7 @@
4446
*/
4547
@API(API.Status.EXPERIMENTAL)
4648
@SuppressWarnings("PMD.TooManyStaticImports")
47-
public class CompensateRecordConstructorRule extends ValueComputationRule<Iterable<? extends Value>, Map<Value, ValueCompensation>, RecordConstructorValue> {
49+
public class CompensateRecordConstructorRule extends ValueComputationRule<Iterable<? extends Value>, Map<Value, List<ValueCompensation>>, RecordConstructorValue> {
4850
@Nonnull
4951
private static final BindingMatcher<RecordConstructorValue> rootMatcher =
5052
recordConstructorValue(all(anyValue()));
@@ -54,17 +56,18 @@ public CompensateRecordConstructorRule() {
5456
}
5557

5658
@Override
57-
public void onMatch(@Nonnull final ValueComputationRuleCall<Iterable<? extends Value>, Map<Value, ValueCompensation>> call) {
59+
public void onMatch(@Nonnull final ValueComputationRuleCall<Iterable<? extends Value>, Map<Value, List<ValueCompensation>>> call) {
5860
final var bindings = call.getBindings();
5961
final var recordConstructorValue = bindings.get(rootMatcher);
60-
final var resultingMatchedValuesMap = new LinkedIdentityMap<Value, ValueCompensation>();
62+
final var resultingMatchedValuesMap = new LinkedIdentityMap<Value, List<ValueCompensation>>();
6163

6264
final var recordConstructorValueResult = call.getResult(recordConstructorValue);
63-
final var matchedCompensation = recordConstructorValueResult == null
65+
final var matchedCompensations = recordConstructorValueResult == null
6466
? null : recordConstructorValueResult.getValue().get(recordConstructorValue);
65-
if (matchedCompensation != null) {
66-
resultingMatchedValuesMap.put(recordConstructorValue, matchedCompensation);
67+
if (matchedCompensations != null) {
68+
resultingMatchedValuesMap.put(recordConstructorValue, matchedCompensations);
6769
} else {
70+
final var compensationsBuilderMap = new LinkedIdentityMap<Value, ImmutableList.Builder<ValueCompensation>>();
6871
for (int i = 0; i < recordConstructorValue.getColumns().size(); ++i) {
6972
final var column = recordConstructorValue.getColumns().get(i);
7073
final var childResultPair = call.getResult(column.getValue());
@@ -78,14 +81,19 @@ public void onMatch(@Nonnull final ValueComputationRuleCall<Iterable<? extends V
7881
//
7982
for (final var childValueEntry : childResultPair.getRight().entrySet()) {
8083
final var argumentValue = childValueEntry.getKey();
81-
final var argumentValueCompensation = childValueEntry.getValue();
84+
final var argumentValueCompensations = childValueEntry.getValue();
8285
final var field = column.getField();
83-
resultingMatchedValuesMap.putIfAbsent(argumentValue,
84-
new FieldValueCompensation(FieldValue.FieldPath.ofSingle(field, i), argumentValueCompensation));
86+
final var columnIdx = i;
87+
compensationsBuilderMap
88+
.computeIfAbsent(argumentValue, k -> new ImmutableList.Builder<>())
89+
.addAll(argumentValueCompensations
90+
.stream()
91+
.map(compensation -> new FieldValueCompensation(FieldValue.FieldPath.ofSingle(field, columnIdx), compensation))
92+
.iterator());
8593
}
8694
}
95+
compensationsBuilderMap.forEach((key, value) -> resultingMatchedValuesMap.put(key, value.build()));
8796
}
88-
8997
call.yieldValue(recordConstructorValue, resultingMatchedValuesMap);
9098
}
9199
}

0 commit comments

Comments
 (0)