1 | /** |
2 | * |
3 | */ |
4 | package de.uka.ipd.sdq.pcmsolver.handler; |
5 | |
6 | import java.util.Iterator; |
7 | |
8 | import org.apache.log4j.Logger; |
9 | import org.eclipse.emf.common.util.EList; |
10 | |
11 | import de.uka.ipd.sdq.context.computed_allocation.ComputedAllocationFactory; |
12 | import de.uka.ipd.sdq.context.computed_allocation.ResourceDemand; |
13 | import de.uka.ipd.sdq.pcm.allocation.AllocationContext; |
14 | import de.uka.ipd.sdq.pcm.core.CoreFactory; |
15 | import de.uka.ipd.sdq.pcm.core.PCMRandomVariable; |
16 | import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification; |
17 | import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer; |
18 | import de.uka.ipd.sdq.pcm.resourcetype.ProcessingResourceType; |
19 | import de.uka.ipd.sdq.pcm.seff.InternalAction; |
20 | import de.uka.ipd.sdq.pcm.seff.seff_performance.ParametricResourceDemand; |
21 | import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper; |
22 | import de.uka.ipd.sdq.pcmsolver.visitors.SeffVisitor; |
23 | import de.uka.ipd.sdq.stoex.Expression; |
24 | |
25 | /** |
26 | * @author Koziolek |
27 | * |
28 | */ |
29 | public class InternalActionHandler{ |
30 | |
31 | private static Logger logger = Logger.getLogger(InternalActionHandler.class.getName()); |
32 | |
33 | private ComputedAllocationFactory compAllocationFactory = ComputedAllocationFactory.eINSTANCE; |
34 | |
35 | private SeffVisitor visitor; |
36 | |
37 | public InternalActionHandler(SeffVisitor seffVisitor) { |
38 | visitor=seffVisitor; |
39 | } |
40 | |
41 | /** |
42 | * @param action |
43 | */ |
44 | public void handle(InternalAction action) { |
45 | //EList<ParametricResourceDemand> resourceDem = action.getResourceDemand_Action() |
46 | |
47 | Iterator resourceDemands = action.getResourceDemand_Action().iterator(); |
48 | while (resourceDemands.hasNext()) { |
49 | ParametricResourceDemand prd = (ParametricResourceDemand) resourceDemands.next(); |
50 | ProcessingResourceType requiredResourceType = prd.getRequiredResource_ParametricResourceDemand(); |
51 | |
52 | if (requiredResourceType.getEntityName().equals("SystemExternalResource")){ |
53 | EList<ResourceContainer> resConList = visitor.getContextWrapper().getPcmInstance().getResourceEnvironment().getResourceContainer_ResourceEnvironment(); |
54 | for (ResourceContainer resCon : resConList){ |
55 | if(resCon.getEntityName().equals("SystemExternalResourceContainer")){ |
56 | ProcessingResourceSpecification prs = resCon.getActiveResourceSpecifications_ResourceContainer().get(0); |
57 | createActualResourceDemand(action, prd, prs); |
58 | } |
59 | } |
60 | } else { |
61 | EList<ProcessingResourceSpecification> resourceList = getResourceList(); |
62 | for (ProcessingResourceSpecification prs : resourceList) { |
63 | ProcessingResourceType currentResourceType = prs |
64 | .getActiveResourceType_ActiveResourceSpecification(); |
65 | if (currentResourceType.getEntityName().equals( |
66 | requiredResourceType.getEntityName())) { |
67 | createActualResourceDemand(action, prd, prs); |
68 | } |
69 | } |
70 | } |
71 | } |
72 | } |
73 | |
74 | /** |
75 | * Create a ResourceDemand in the computed allocation context |
76 | * for the given ParametricResourceDemand and ProcessingResourceSpecification |
77 | * The resulting ResourceDemand already takes into account the processing rate. |
78 | * @param prd |
79 | * @param prs |
80 | */ |
81 | private void createActualResourceDemand(InternalAction action, ParametricResourceDemand prd, ProcessingResourceSpecification prs) { |
82 | // TODO: include current branch conditions and loop iterations |
83 | |
84 | String spec = prd.getSpecification_ParametericResourceDemand().getSpecification(); |
85 | |
86 | // quick fix: (convert pmfs to pdfs). This quick fix allows to use resource demands like "100 * file.BYTESIZE". |
87 | // Do not remove this until PMFs can be properly handled by the following, because the modelling of compression |
88 | // or other file handling would become difficult, one could not use the BYTESIZE characterization anymore in resource demands. |
89 | // spec = spec.replaceAll("IntPMF", "DoublePDF"); |
90 | // spec = spec.replaceAll("DoublePMF", "DoublePDF"); |
91 | |
92 | String actResDemSpecification = getSolvedSpecification(spec, prs); |
93 | |
94 | // actResDemSpecification = actResDemSpecification.replaceAll("IntPMF", "DoublePDF"); |
95 | // actResDemSpecification = actResDemSpecification.replaceAll("DoublePMF", "DoublePDF"); |
96 | |
97 | // TODO: Is there a better way to check the type of the specification? |
98 | // if(actResDemSpecification.contains("PMF") == true) { |
99 | // throw new RuntimeException("Resource demand specification \"" + spec |
100 | // + "\" of InternalAction \"" + action.getEntityName() + "\" (ID = \"" + action.getId() |
101 | // + "\") evaluates to a probability mass function (PMF), but only probability density functions (PDF) are allowed."); |
102 | // } |
103 | |
104 | ResourceDemand ard = compAllocationFactory.createResourceDemand(); |
105 | ard.setParametricResourceDemand_ResourceDemand(prd); |
106 | |
107 | PCMRandomVariable rv = CoreFactory.eINSTANCE.createPCMRandomVariable(); |
108 | rv.setSpecification(actResDemSpecification); |
109 | |
110 | //convertLiteralsToPDFs(rv); |
111 | |
112 | ard.setSpecification_ResourceDemand(rv); |
113 | |
114 | visitor.getContextWrapper().getCompAllCtx() |
115 | .getResourceDemands_ComputedAllocationContext().add(ard); |
116 | } |
117 | |
118 | /** |
119 | * Get a combined expression for the demanded time: specification / processing rate prs |
120 | * |
121 | * As the expressions can be more complex, we added parentheses, resulting in |
122 | * (specification)/((prs)*1.0). This expression is then solved in the ContextWrapper of this.visitor. |
123 | * and finally again printed to a String. |
124 | * |
125 | * @param specification |
126 | * @param prs |
127 | * @return A String with the solved expression. |
128 | */ |
129 | private String getSolvedSpecification(String specification, ProcessingResourceSpecification prs) { |
130 | |
131 | // quickly incorporate processing rate |
132 | /* As both divisor and divident may evaluate to an integer and the first may be smaller |
133 | * than the latter, I added the factor *1.0 so that it is not falsely rounded to 0 |
134 | * (without *1.0, e.g. (4) / 20 would result in a demand of 0 instead of 0.2) |
135 | */ |
136 | specification = "("+ specification+") / (("+prs.getProcessingRate_ProcessingResourceSpecification().getSpecification()+")*1.0)"; |
137 | logger.debug("Actual Resource Demand (Expression): "+specification); |
138 | |
139 | Expression solvedExpr = (Expression) ExpressionHelper |
140 | .getSolvedExpression(specification, visitor.getContextWrapper()); |
141 | |
142 | |
143 | |
144 | String solvedSpecification = ExpressionHelper |
145 | .getSolvedExpressionAsString(specification, |
146 | visitor.getContextWrapper()); |
147 | logger.debug("Computed Actual Resource Demand: "+solvedSpecification); |
148 | return solvedSpecification; |
149 | } |
150 | |
151 | /** |
152 | * @return |
153 | */ |
154 | private EList<ProcessingResourceSpecification> getResourceList() { |
155 | AllocationContext ac = visitor.getContextWrapper().getAllCtx(); |
156 | ResourceContainer currentResourceContainer = ac.getResourceContainer_AllocationContext(); |
157 | EList<ProcessingResourceSpecification> resourceList = currentResourceContainer |
158 | .getActiveResourceSpecifications_ResourceContainer(); |
159 | return resourceList; |
160 | } |
161 | |
162 | } |