1 | package de.uka.ipd.sdq.pcmsolver.handler; |
2 | |
3 | import org.apache.log4j.Logger; |
4 | import org.eclipse.emf.common.util.EList; |
5 | |
6 | import de.uka.ipd.sdq.context.computed_usage.ComputedUsageFactory; |
7 | import de.uka.ipd.sdq.context.computed_usage.LoopIteration; |
8 | import de.uka.ipd.sdq.pcm.core.CoreFactory; |
9 | import de.uka.ipd.sdq.pcm.core.PCMRandomVariable; |
10 | import de.uka.ipd.sdq.pcm.seff.AbstractLoopAction; |
11 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour; |
12 | import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper; |
13 | import de.uka.ipd.sdq.pcmsolver.visitors.SeffVisitor; |
14 | import de.uka.ipd.sdq.probfunction.ProbabilityMassFunction; |
15 | import de.uka.ipd.sdq.probfunction.Sample; |
16 | import de.uka.ipd.sdq.stoex.Expression; |
17 | import de.uka.ipd.sdq.stoex.IntLiteral; |
18 | import de.uka.ipd.sdq.stoex.ProbabilityFunctionLiteral; |
19 | |
20 | public abstract class AbstractLoopActionHandler { |
21 | |
22 | private static Logger logger = Logger.getLogger(AbstractLoopActionHandler.class.getName()); |
23 | |
24 | protected ComputedUsageFactory usageFactory = ComputedUsageFactory.eINSTANCE; |
25 | |
26 | protected SeffVisitor visitor; |
27 | |
28 | /** |
29 | * @param context |
30 | * @param _visitor |
31 | * @param nextHandler |
32 | */ |
33 | public AbstractLoopActionHandler(SeffVisitor seffVisitor) { |
34 | visitor = seffVisitor; |
35 | } |
36 | |
37 | /** |
38 | * @param loop |
39 | * @param solvedIterationCountExpr |
40 | */ |
41 | protected void visitLoopBody(AbstractLoopAction loop, String iterationCountSpecification) { |
42 | Expression solvedIterationCountExpr = ExpressionHelper |
43 | .parseToExpression(iterationCountSpecification); |
44 | |
45 | // int lowerBound = 0; |
46 | // int upperBound = getUpperBound(solvedIterationCountExpr); |
47 | |
48 | ResourceDemandingBehaviour loopBody = loop.getBodyBehaviour_Loop(); |
49 | if (loopBody!=null){ |
50 | visitor.doSwitch(loopBody); |
51 | |
52 | // TODO: loops adequately modelled? |
53 | // visitor.getMyContext().getCurrentLoopIterationNumber().add(lowerBound); |
54 | // |
55 | // for (int i=lowerBound; i<upperBound; i++){ |
56 | // //logger.debug("Loop Execution Number "+i); |
57 | // ArrayList curLoop = visitor.getMyContext().getCurrentLoopIterationNumber(); |
58 | // curLoop.remove(curLoop.size()-1); // delete last element |
59 | // curLoop.add(i); // add current loop iteration number to scope |
60 | // |
61 | // visitor.doSwitch(loopBody); // is this really necessary? (TODO) |
62 | // // The loop body gets visited as many times as the loop count specifies. |
63 | // // This implies that a usage context will be created for each number |
64 | // // of loop iteration (if there's an external call within the loop), |
65 | // // which might lead to a huge number of contexts |
66 | // // for large iteration numbers and thus memory problems. |
67 | // } |
68 | // ArrayList curLoop = visitor.getMyContext().getCurrentLoopIterationNumber(); |
69 | // curLoop.remove(curLoop.size()-1); |
70 | } |
71 | } |
72 | |
73 | /** |
74 | * @param solvedLoopCountExpr |
75 | * @param upperBound |
76 | * @return |
77 | */ |
78 | public int getUpperBound(Expression solvedLoopCountExpr) { |
79 | int upperBound = 0; |
80 | if (solvedLoopCountExpr instanceof IntLiteral) { |
81 | IntLiteral loopInt = (IntLiteral) solvedLoopCountExpr; |
82 | upperBound = loopInt.getValue(); |
83 | } else if (solvedLoopCountExpr instanceof ProbabilityFunctionLiteral) { |
84 | ProbabilityFunctionLiteral loopProbLiteral = (ProbabilityFunctionLiteral) solvedLoopCountExpr; |
85 | if (loopProbLiteral.getFunction_ProbabilityFunctionLiteral() instanceof ProbabilityMassFunction){ |
86 | ProbabilityMassFunction loopPMF = (ProbabilityMassFunction) loopProbLiteral |
87 | .getFunction_ProbabilityFunctionLiteral(); |
88 | EList<Sample> sampleList = loopPMF.getSamples(); |
89 | Sample lastSample = sampleList.get(sampleList.size() - 1); |
90 | if (lastSample.getValue() instanceof Integer){ |
91 | upperBound = ((Integer) lastSample.getValue()).intValue(); |
92 | } else { |
93 | logger.error("Could not determine upper bound for executing loop " + |
94 | "(PMF for loop count does not contain integer values). " + |
95 | "Skipping execution of loop body."); |
96 | } |
97 | } else { |
98 | logger.error("Could not determine upper bound for executing loop " + |
99 | "(loop count is prob function, but not PMF)." + |
100 | "Skipping execution of loop body."); |
101 | } |
102 | } else { |
103 | logger.error("Could not determine upper bound for executing loop " + |
104 | "(loop count neither Integer nor PMF). " + |
105 | "Skipping execution of loop body."); |
106 | } |
107 | return upperBound; |
108 | } |
109 | |
110 | /** |
111 | * @param loop |
112 | * @param solvedSpecification |
113 | */ |
114 | protected void storeToUsageContext(AbstractLoopAction loop, String solvedSpecification) { |
115 | LoopIteration loopIteration = usageFactory.createLoopIteration(); |
116 | loopIteration.setLoopaction_LoopIteration(loop); |
117 | PCMRandomVariable rv = CoreFactory.eINSTANCE.createPCMRandomVariable(); |
118 | rv.setSpecification(solvedSpecification); |
119 | loopIteration.setSpecification_LoopIteration(rv); |
120 | |
121 | visitor.getContextWrapper().getCompUsgCtx().getLoopiterations_ComputedUsageContext().add(loopIteration); |
122 | } |
123 | |
124 | |
125 | } |