Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2017-04-19 17:48:02 +0000
committerEd Willink2017-05-14 05:22:21 +0000
commitc7530de7d233bbab1a71de65a6351643c6fed5f0 (patch)
tree9decf1ad1819e93a56f27a2b0febc4c29c82fb06
parentef5f54b3f5360aa094aff62eae215dbbc1f06ee6 (diff)
downloadorg.eclipse.qvtd-c7530de7d233bbab1a71de65a6351643c6fed5f0.tar.gz
org.eclipse.qvtd-c7530de7d233bbab1a71de65a6351643c6fed5f0.tar.xz
org.eclipse.qvtd-c7530de7d233bbab1a71de65a6351643c6fed5f0.zip
[514590] speculate only the trace node
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/RegionHelper.java42
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java52
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculatedPartition.java22
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculationPartition.java4
4 files changed, 95 insertions, 25 deletions
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/RegionHelper.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/RegionHelper.java
index 7fea8f564..b305b3401 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/RegionHelper.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtm2qvts/RegionHelper.java
@@ -218,7 +218,7 @@ public class RegionHelper
return dependencyNodes;
} */
- protected @NonNull List<@NonNull Node> computeHeadNodes(@NonNull MappingRegion mappingRegion) {
+ protected @NonNull List<@NonNull Node> computeHeadNodes() {
//
// A head node is reachable from very few nodes, typically just itself, occasionally from a small group of mutually bidirectional nodes,
// so we search for the least reachable nodes taking care to avoid hazards from the source-to-target / target-source asymmetry.
@@ -265,6 +265,28 @@ public class RegionHelper
// targetClosure.add(computationEdge.getSource());
// }
}
+ List<@NonNull Node> headNodes = computeHeadNodes(targetFromSourceClosure);
+ //
+ // Check head node consistency
+ //
+ Set<@NonNull Node> debugHeadNodes = new HashSet<>();
+ for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
+ if (node.isTrue() || node.isDependency()) {
+ debugHeadNodes.add(node);
+ node.setHead();
+ assert !headNodes.contains(node);
+ headNodes.add(node);
+ }
+ else if (node.isHead()) {
+ debugHeadNodes.add(node);
+ }
+ }
+ assert debugHeadNodes.equals(new HashSet<>(headNodes));
+ return headNodes;
+ }
+
+ public @NonNull List<@NonNull Node> computeHeadNodes(@NonNull Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSourceClosure) {
+ Iterable <@NonNull Node> navigableNodes = targetFromSourceClosure.keySet();
//
// Ripple the local target-from-source closure to compute the overall target-from-source closure.
//
@@ -330,22 +352,6 @@ public class RegionHelper
headNodes.add(headNode);
}
//
- // Check head node consistency
- //
- Set<@NonNull Node> debugHeadNodes = new HashSet<>();
- for (@NonNull Node node : QVTscheduleUtil.getOwnedNodes(mappingRegion)) {
- if (node.isTrue() || node.isDependency()) {
- debugHeadNodes.add(node);
- node.setHead();
- assert !headNodes.contains(node);
- headNodes.add(node);
- }
- else if (node.isHead()) {
- debugHeadNodes.add(node);
- }
- }
- assert debugHeadNodes.equals(new HashSet<>(headNodes));
- //
return headNodes;
}
@@ -525,7 +531,7 @@ public class RegionHelper
}
public @NonNull List<@NonNull Node> initHeadNodes() {
- List<@NonNull Node> headNodes = computeHeadNodes(mappingRegion);
+ List<@NonNull Node> headNodes = computeHeadNodes();
((MappingRegionImpl)mappingRegion).getHeadNodes2().addAll(headNodes);
return headNodes;
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
index 93519712c..f43266f9f 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/Partitioner.java
@@ -23,6 +23,7 @@ import org.eclipse.ocl.pivot.Property;
import org.eclipse.qvtd.compiler.CompilerProblem;
import org.eclipse.qvtd.compiler.ProblemHandler;
import org.eclipse.qvtd.compiler.internal.qvtm2qvts.QVTm2QVTs;
+import org.eclipse.qvtd.compiler.internal.qvtm2qvts.RegionHelper;
import org.eclipse.qvtd.compiler.internal.qvtm2qvts.RegionUtil;
import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil;
import org.eclipse.qvtd.pivot.qvtschedule.Edge;
@@ -91,12 +92,16 @@ public class Partitioner
}
private static void gatherCorrolaries(@NonNull Set<@NonNull Property> corrolaryProperties, @NonNull MappingRegion region) {
+ List<@NonNull Node> middleNodes = new ArrayList<>();
for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
if (!node.isTrue() && node.isPattern() && node.isRealized() && RegionUtil.getClassDatumAnalysis(node).getDomainUsage().isMiddle()) {
- for (@NonNull NavigableEdge edge : node.getNavigationEdges()) {
- if (edge.isRealized() && edge.getEdgeTarget().isRealized()) {
- corrolaryProperties.add(RegionUtil.getProperty(edge));
- }
+ middleNodes.add(node);
+ }
+ }
+ for (@NonNull Node node : middleNodes) {
+ for (@NonNull NavigableEdge edge : node.getNavigationEdges()) {
+ if (edge.isRealized() && edge.getEdgeTarget().isRealized()) {
+ corrolaryProperties.add(RegionUtil.getProperty(edge));
}
}
}
@@ -117,6 +122,7 @@ public class Partitioner
private final @NonNull Set<@NonNull NavigableEdge> navigableEdges = new HashSet<>();
private final @NonNull Set<@NonNull Edge> realizedEdges = new HashSet<>();
private final @NonNull List<@NonNull Edge> realizedOutputEdges = new ArrayList<>();
+ private final @Nullable Node traceNode;
private final @NonNull List<@NonNull Node> trueNodes = new ArrayList<>();
private boolean hasLoadedNodes = false;
@@ -153,6 +159,7 @@ public class Partitioner
this.region = region;
this.corrolaryProperties = corrolaryProperties;
analyzeNodes();
+ this.traceNode = analyzeTraceNode();
analyzeEdges();
}
@@ -288,6 +295,39 @@ public class Partitioner
}
}
+ private @Nullable Node analyzeTraceNode() {
+ if (realizedMiddleNodes.size() == 0) {
+ return null;
+ }
+ if (realizedMiddleNodes.size() == 1) {
+ return realizedMiddleNodes.get(0);
+ }
+ //
+ // Compute the Set of all source nodes from which each target can be reached by transitive to-one navigation.
+ //
+ Map<@NonNull Node, @NonNull Set<@NonNull Node>> targetFromSourceClosure = new HashMap<>();
+ for (@NonNull Node targetNode : realizedMiddleNodes) {
+ targetFromSourceClosure.put(targetNode, Sets.newHashSet(targetNode));
+ }
+ for (@NonNull Node sourceNode : realizedMiddleNodes) {
+ for (@NonNull NavigableEdge navigationEdge : sourceNode.getRealizedNavigationEdges()) {
+ Node targetNode = navigationEdge.getEdgeTarget();
+ Set<@NonNull Node> sourceClosure = targetFromSourceClosure.get(targetNode);
+ if (sourceClosure != null) {
+ sourceClosure.add(sourceNode);
+ }
+ }
+ }
+ RegionHelper regionHelper = new RegionHelper(region);
+ List<@NonNull Node> headNodes = regionHelper.computeHeadNodes(targetFromSourceClosure);
+ if (headNodes.size() == 0) {
+ return null;
+ }
+ else {
+ return headNodes.get(0);
+ }
+ }
+
private void check() {
for (@NonNull Node node : RegionUtil.getOwnedNodes(region)) {
if ((node.isSpeculated() || node.isRealized()) && !hasRealizedNode(node)) {
@@ -445,6 +485,10 @@ public class Partitioner
return region;
}
+ public @Nullable Node getTraceNode() {
+ return traceNode;
+ }
+
public @NonNull Iterable<@NonNull Node> getTrueNodes() {
return trueNodes;
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculatedPartition.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculatedPartition.java
index b0a5b0e63..8bd7c0770 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculatedPartition.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculatedPartition.java
@@ -254,12 +254,30 @@ class SpeculatedPartition extends AbstractPartition
}
protected void resolveRealizedMiddleNodes() {
+ Node traceNode = partitioner.getTraceNode();
+ if (traceNode != null) {
+ if (traceNode.isMatched() && traceNode.isClass()) {
+ Role nodeRole = RegionUtil.getNodeRole(traceNode);
+ // assert nodeRole.isMatched();
+ assert traceNode.isPattern();//
+ nodeRole = QVTscheduleUtil.asSpeculated(nodeRole);
+ // }
+ if (!hasNode(traceNode)) {
+ addNode(traceNode, nodeRole);
+ }
+ for (@NonNull NavigableEdge edge : traceNode.getNavigationEdges()) {
+ if (partitioner.hasRealizedEdge(edge)) {
+ tracedInputNodes.add(edge.getEdgeTarget());
+ }
+ }
+ }
+ }
for (@NonNull Node node : partitioner.getRealizedMiddleNodes()) {
- if (node.isMatched() && node.isClass()) {
+ if ((node != traceNode) && node.isMatched() && node.isClass()) {
Role nodeRole = RegionUtil.getNodeRole(node);
// assert nodeRole.isMatched();
assert node.isPattern();//
- nodeRole = QVTscheduleUtil.asSpeculated(nodeRole);
+ // nodeRole = QVTscheduleUtil.asSpeculated(nodeRole);
// }
if (!hasNode(node)) {
addNode(node, nodeRole);
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculationPartition.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculationPartition.java
index 894d893aa..a182d2faa 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculationPartition.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvts2qvts/partitioner/SpeculationPartition.java
@@ -34,7 +34,9 @@ class SpeculationPartition extends AbstractPartition
// All traced loaded nodes are retained as is to be traced by the speculation.
// NB. Unreachable loaded nodes are effectively predicates nd so are deferred.
//
- for (@NonNull Node node : partitioner.getRealizedMiddleNodes()) {
+ // for (@NonNull Node node : partitioner.getRealizedMiddleNodes()) {
+ Node node = partitioner.getTraceNode();
+ if (node != null) {
if (node.isPattern() && node.isClass()) { // FIXME UML2RDBMS experiment
Role speculationNodeRole = RegionUtil.asSpeculation(RegionUtil.getNodeRole(node));
addNode(node, speculationNodeRole);

Back to the top