-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
… than best cost of subset. (Second attempt) (cherry picked from commit 1c795d7)
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,12 +28,14 @@ | |
import org.apache.calcite.util.trace.CalciteTrace; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.collect.Maps; | ||
|
||
import org.slf4j.Logger; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
|
@@ -311,21 +313,24 @@ void mergeWith( | |
assert otherSet.equivalentSet == null; | ||
LOGGER.trace("Merge set#{} into set#{}", otherSet.id, id); | ||
otherSet.equivalentSet = this; | ||
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery(); | ||
|
||
// remove from table | ||
boolean existed = planner.allSets.remove(otherSet); | ||
assert existed : "merging with a dead otherSet"; | ||
|
||
final Map<RelSubset, RelNode> changedSubsets = Maps.newIdentityHashMap(); | ||
|
||
// merge subsets | ||
for (RelSubset otherSubset : otherSet.subsets) { | ||
planner.ruleQueue.subsetImportances.remove(otherSubset); | ||
RelSubset subset = | ||
getOrCreateSubset( | ||
otherSubset.getCluster(), | ||
otherSubset.getTraitSet()); | ||
// collect RelSubset instances, whose best should be changed | ||
if (otherSubset.bestCost.isLt(subset.bestCost)) { | ||
subset.bestCost = otherSubset.bestCost; | ||
subset.best = otherSubset.best; | ||
changedSubsets.put(subset, otherSubset.best); | ||
} | ||
for (RelNode otherRel : otherSubset.getRels()) { | ||
planner.reregister(this, otherRel); | ||
|
@@ -335,6 +340,18 @@ void mergeWith( | |
// Has another set merged with this? | ||
assert equivalentSet == null; | ||
|
||
// calls propagateCostImprovements() for RelSubset instances, | ||
// whose best should be changed to checks whether that | ||
// subset's parents have gotten cheaper. | ||
final Set<RelSubset> activeSet = new HashSet<>(); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
vvysotskyi
Author
Collaborator
|
||
for (Map.Entry<RelSubset, RelNode> subsetBestPair : changedSubsets.entrySet()) { | ||
RelSubset relSubset = subsetBestPair.getKey(); | ||
relSubset.propagateCostImprovements( | ||
planner, mq, subsetBestPair.getValue(), | ||
activeSet); | ||
} | ||
assert activeSet.isEmpty(); | ||
|
||
// Update all rels which have a child in the other set, to reflect the | ||
// fact that the child has been renamed. | ||
// | ||
|
@@ -353,8 +370,6 @@ void mergeWith( | |
} | ||
|
||
// Make sure the cost changes as a result of merging are propagated. | ||
final Set<RelSubset> activeSet = new HashSet<>(); | ||
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery(); | ||
for (RelNode parentRel : getParentRels()) { | ||
final RelSubset parentSubset = planner.getSubset(parentRel); | ||
parentSubset.propagateCostImprovements( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,7 +195,8 @@ Set<RelNode> getParents() { | |
final Set<RelNode> list = new LinkedHashSet<>(); | ||
for (RelNode parent : set.getParentRels()) { | ||
for (RelSubset rel : inputSubsets(parent)) { | ||
if (rel.set == set && traitSet.satisfies(rel.getTraitSet())) { | ||
// see usage of this method in propagateCostImprovements0() | ||
if (rel == this) { | ||
This comment has been minimized.
Sorry, something went wrong.
chunhui-shi
|
||
list.add(parent); | ||
} | ||
} | ||
|
@@ -337,12 +338,17 @@ void propagateCostImprovements0(VolcanoPlanner planner, RelMetadataQuery mq, | |
|
||
bestCost = cost; | ||
best = rel; | ||
// since best was changed, cached metadata for this subset should be removed | ||
mq.clearCache(this); | ||
|
||
// Lower cost means lower importance. Other nodes will change | ||
// too, but we'll get to them later. | ||
planner.ruleQueue.recompute(this); | ||
for (RelNode parent : getParents()) { | ||
// removes parent cached metadata since its input was changed | ||
mq.clearCache(parent); | ||
final RelSubset parentSubset = planner.getSubset(parent); | ||
// parent subset will clear its cache in propagateCostImprovements0 method itself | ||
parentSubset.propagateCostImprovements(planner, mq, parent, | ||
activeSet); | ||
} | ||
|
My understanding is this change allow the lower cost from otherSubset to update the parents of merged 'this', if so, could we skip the next propagateCostImprovements at line 375?