source: DCWoRMS/trunk/build/classes/simulator/workload/generator/RandomNumbersWrapper.java @ 477

Revision 477, 14.8 KB checked in by wojtekp, 13 years ago (diff)
  • Property svn:mime-type set to text/plain
Line 
1package simulator.workload.generator;
2
3import java.io.IOException;
4import java.util.ArrayList;
5import java.util.HashMap;
6
7import javax.xml.parsers.DocumentBuilder;
8import javax.xml.parsers.DocumentBuilderFactory;
9import javax.xml.parsers.ParserConfigurationException;
10import javax.xml.xpath.XPath;
11import javax.xml.xpath.XPathConstants;
12import javax.xml.xpath.XPathExpression;
13import javax.xml.xpath.XPathExpressionException;
14import javax.xml.xpath.XPathFactory;
15
16import org.apache.commons.logging.Log;
17import org.apache.commons.logging.LogFactory;
18import org.w3c.dom.Document;
19import org.w3c.dom.Node;
20import org.xml.sax.SAXException;
21
22import simulator.RandomNumbers;
23import simulator.workload.reader.archive.AbstractWAParser;
24import simulator.workload.reader.archive.WAParser;
25import simulator.workload.reader.archive.swf.SWFFields;
26
27import bsh.EvalError;
28import bsh.Interpreter;
29
30import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList;
31
32public class RandomNumbersWrapper {
33       
34        protected Log log = LogFactory.getLog(RandomNumbersWrapper.class);
35       
36        protected WAParser swfParser;
37        protected String jobId;
38        protected String taskId;
39       
40        protected RandomNumbers randomNumbers[];
41       
42        /**
43         * List of all dependency paths detected in workload.
44         */
45        protected ArrayList<ArrayList<String>> idDep;
46       
47        /**
48         * Map, where key is workload node id and value is arithmetic expression.
49         */
50        protected HashMap <String, String> idExpMap;
51        protected Interpreter interpreter;
52       
53        public RandomNumbersWrapper(){
54                swfParser = null;
55                idExpMap = new HashMap<String, String>();
56                interpreter = new Interpreter();
57                randomNumbers = new RandomNumbers[5];
58                /*
59                 * 0 - parameterRandomNumbers;
60                 * 1 - hardConstraintsRandomNumbers;
61                 * 2 - softConstraintsRandomNumbers;
62                 * 3 - timeConstraintsRandomNumbers;
63                 * 4 - precedingConstraintsRandomNumbers;
64                 */
65        }
66       
67        public void setExternalFileDpendencies(String fileName){
68                try {
69                       
70                        this.swfParser = AbstractWAParser.getInstance(fileName);
71                       
72                } catch (NullPointerException e) {
73                        e.printStackTrace();
74                }
75        }
76       
77        public void setCurrentJobId(String id){
78                this.jobId = id;
79        }
80       
81        public void setCurrentTaskId(String id){
82                this.taskId = id;
83        }
84       
85        public void setParameterRandomNumbers(RandomNumbers parameterRandomNumbers) {
86                randomNumbers[0] = parameterRandomNumbers;
87        }
88        public void setHardConstraintsRandomNumbers(
89                        RandomNumbers hardConstraintsRandomNumbers) {
90                randomNumbers[1] = hardConstraintsRandomNumbers;
91        }
92        public void setSoftConstraintsRandomNumbers(
93                        RandomNumbers softConstraintsRandomNumbers) {
94                randomNumbers[2] = softConstraintsRandomNumbers;
95        }
96        public void setTimeConstraintsRandomNumbers(
97                        RandomNumbers timeConstraintsRandomNumbers) {
98                randomNumbers[3] = timeConstraintsRandomNumbers;
99        }
100        public void setPrecedingConstraintsRandomNumbers(
101                        RandomNumbers precedingConstraintsRandomNumbers) {
102                randomNumbers[4] = precedingConstraintsRandomNumbers;
103        }
104       
105       
106        public double evalValueFor(String id, String refElementId){
107                ArrayList<String> path = null;
108                String idName;
109                boolean found = false;
110                int idx = 0;
111               
112                // find path which contains node.id .
113                for(int i = 0; i < idDep.size(); i++){
114                        path = idDep.get(i);
115                        // find position of id in path
116                        for(idx = 0; idx < path.size(); idx++){
117                                idName = path.get(idx);
118                                if(idName.equals(id)) {
119                                        found = true;
120                                        break;
121                                }
122                        }
123                        if(found) break;
124                }
125               
126                if(!found)
127                        throw new RuntimeException("No value for "+id);
128
129                RandomNumbers randomNumber;
130                String genName;
131                String expr;
132                double value = 0;
133                Number nValue;
134               
135               
136                try {
137                        // this is the id of the first node in the path. All others nodes depends on this node.
138                        idName = path.get(0);
139                               
140                        if(isExternalFileDependent(refElementId)){      // evaluate external file dependency
141                                value = evalExternalFileDependency(refElementId);
142                                if(idExpMap.containsKey(idName)){
143                                        expr = idExpMap.get(idName);
144                                        interpreter.set("x", value);
145                                        nValue = (Number) interpreter.eval(expr);
146                                        value = nValue.doubleValue();
147                                }
148                        } else {                                                                // if there is no external file dependency, try to use random generator
149                                for(int i = 0; i < randomNumbers.length; i++){
150                                        randomNumber = randomNumbers[i];
151                                        if(randomNumber.containsElement(idName)){
152                                                genName = randomNumber.getGeneratorName(idName);
153                                //              value = randomNumber.getRandomValue(genName);
154                                                value = randomNumber.getLastGeneratedRandomValue(genName);
155                                                break;
156                                        }
157                                }
158                        }
159                       
160                        // execute all arithmetic dependency expressions between first node and current one.
161                        for(int i = 1; i <= idx; i++){
162                                idName = path.get(i);
163                                expr = idExpMap.get(idName);
164                                interpreter.set("x", value);
165                                nValue = (Number)interpreter.eval(expr);
166                                value = nValue.doubleValue();
167                                if(i < idx) {
168                                        // random factor which was generated last time should be added to current value.
169                                        for(int j = 0; j < randomNumbers.length; j++){
170                                                randomNumber = randomNumbers[j];
171                                                if(randomNumber.containsElement(idName)){
172                                                        genName = randomNumber.getGeneratorName(idName);
173                                                        value = value + randomNumber.getLastGeneratedRandomValue(genName);
174                                                        break;
175                                                }
176                                        }
177                                }
178                        }
179                       
180                        // if for current node is defined any random generator, it means that to the value
181                        // accounted by arithmetic expressions some random factor must be added.
182                        for(int i = 0; i < randomNumbers.length; i++){
183                                randomNumber = randomNumbers[i];
184                                if(randomNumber.containsElement(idName)){
185                                        genName = randomNumber.getGeneratorName(idName);
186                                        value = value + randomNumber.getRandomValue(genName);
187                                        break;
188                                }
189                        }
190                       
191                } catch (IllegalAccessException e){
192                        e.printStackTrace();
193                } catch (EvalError e) {
194                        e.printStackTrace();
195                }
196
197                return value;
198        }
199       
200       
201        /**
202         *
203         * @param fileLocation - workload configuration file location
204         * @return list of lists of xml elements id's, organized in dependency order (top-down hierarchy)
205         * or null if no dependencies in workload configuration file were detected.
206         * @throws Exception if cycle in dependency graph was detected
207         */
208        public ArrayList<ArrayList<String>> findDependencies(String fileLocation) throws Exception{
209                ArrayList <ArrayList<String>> genOrderList = new ArrayList<ArrayList<String>>();
210               
211                try {
212                        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
213                        DocumentBuilder builder = docFactory.newDocumentBuilder();
214                        Document doc = builder.parse(fileLocation);
215                       
216                       
217                        XPathFactory factory = XPathFactory.newInstance();
218                        XPath xpath = factory.newXPath();
219                        XPathExpression expr = xpath.compile("//*[@id]");
220                       
221                        Object wynik = expr.evaluate(doc, XPathConstants.NODESET);
222                        DTMNodeList list = (DTMNodeList) wynik;
223                        Node node = null;
224                        Node refAttr = null;
225                        Node idAttr = null;
226                       
227                        HashMap<String, Integer> nodeMap = new HashMap<String, Integer>();
228                        HashMap<Integer, String> nodeMapInv = new HashMap<Integer, String>();
229                        String key;
230                        for(int i = 0; i < list.getLength(); i++){
231                                node = list.item(i);
232                                key = node.getAttributes().getNamedItem("id").getNodeValue();
233                                nodeMap.put(key, i);
234                                nodeMapInv.put(i, key);
235                                node = node.getAttributes().getNamedItem("expr");
236                                if(node != null && node.getNodeValue() != null)
237                                        idExpMap.put(key, node.getNodeValue());
238                                else
239                                        idExpMap.put(key, "x");
240                        }
241                       
242                        int size = nodeMap.size();
243                        if(size == 0)
244                                return null;
245                       
246                        int refGraph[] = new int[size];
247                        for(int i = 0; i < refGraph.length; i++)
248                                refGraph[i] = -1;
249                       
250                        expr = xpath.compile("//*[@refElementId]");
251                        wynik = expr.evaluate(doc, XPathConstants.NODESET);
252                        int x = 0;
253                        int y = 0;
254                        String idValue = null;
255                        for(int i = 0; i < list.getLength(); i++){
256                                node = list.item(i);
257                                refAttr = node.getAttributes().getNamedItem("refElementId");
258                                idAttr = node.getAttributes().getNamedItem("id");
259                                if(refAttr != null){
260                                        try {
261                                                idValue = idAttr.getNodeValue();
262                                                y = nodeMap.get(idValue);
263                                                x = nodeMap.get(refAttr.getNodeValue());
264                                                refGraph[y] = nodeMap.get(nodeMapInv.get(x));
265                                               
266                                        } catch (NullPointerException e){
267                                                log.warn("Element referenced by " + idValue + " doeas not exist in configuration file.");
268                                        }
269                                }
270                        }
271
272                        // find start points
273                        /*
274                         * ostatni w grafie jest ten, ktory nie poprzedza innego wierzcholka (nie ma nastepnikow).
275                         * W celu lokalizacji:
276                         * jezeli wierzcholek 'i' posiada poprzednika 'p', to poprzednik 'p' oznaczany jest jako uzyty
277                         * (posiadajacy nastepnika) - pod indeksem reprezentujacym 'p' w helpTab wpisywne jest -1
278                         */
279                       
280                        int helpTab[] = new int[refGraph.length];
281                        for(int i = 0; i < refGraph.length; i++){
282                                if(refGraph[i] != -1)                   // bo -1 nie moze byc indeksem tablicy
283                                        helpTab[refGraph[i]] = -1;
284                        }
285                       
286                        // path end detection
287                        /*
288                         * jezeli wierzcholek 'i' posiada w tabeli helpTab wartosc 0, to oznacza, ze nie posiada
289                         * nastepnikow - jest ostatnim wierzcholkiem na sciezce
290                         */
291                        ArrayList <Integer> pathEnd = new ArrayList<Integer>();
292                        for(int i = 0; i < helpTab.length; i++){
293                                if(helpTab[i] == 0) {
294                                        pathEnd.add(i);
295                                }
296                        }
297                       
298                        int loopDetector[] = new int[refGraph.length];
299                        /*
300                         * jezeli jakis wierzcholek nigdy nie zostal uzyty w trakcie przejscia wszystkimi sciezkami
301                         * to albo jest wolnym strzelcem albo nalezy do cyklu, z ktorego zaden wierzcholek nie nalezy
302                         * do listy pathEnd
303                         */
304                        int usedNodes[] = new int[refGraph.length]; // 1 - used, 0 - not used
305                        boolean process = true;
306                        boolean loopNotFound = true;
307                        int idx = 0;
308                        int pathId = 0;
309                        int val = 0;
310                        String path = new String();
311                        ArrayList <String> genOrder = new ArrayList<String>();
312                       
313                        if(pathEnd.size() == 0)
314                                throw new Exception("ERROR: Loop detected in attributes dependency.");
315                       
316                        // for each path (path end)
317                        for(int i = 0; i < pathEnd.size(); i++){
318                                System.arraycopy(refGraph, 0, loopDetector, 0, refGraph.length);
319                                idx = pathEnd.get(i);
320                                usedNodes[idx] = 1;
321                                pathId = refGraph.length + idx;
322                                path = nodeMapInv.get(idx);
323                                genOrder.clear();
324                                genOrder.add(0, path);
325                                process = true;
326                                loopNotFound = true;
327                               
328                                // found ancestor of current nod
329                                // path is build from the end to the beginning
330                                while(process && loopNotFound){
331                                        val = loopDetector[idx];
332                                       
333                                        if(val == -1)
334                                                process = false;
335                                        else if(val == -pathId)
336                                                loopNotFound = false;
337                                        else {
338                                                loopDetector[idx] = -pathId;
339                                                path = nodeMapInv.get(val) + " -> " + path;
340                                                usedNodes[val] = 1;
341                                                genOrder.add(0, nodeMapInv.get(val));
342                                        }
343                                        idx = val;
344                                }
345                                if(!loopNotFound) {
346                                        throw new Exception("ERROR: Loop detected in atributes dependency, path: "+path);
347                                }
348                               
349                                if(genOrder.size() > 0){
350                                        genOrderList.add((ArrayList<String>)genOrder.clone());
351                                }
352                               
353                        }
354                       
355                        // the same as above loop, but for all unused nodes.
356                        for(int i = 0; i < usedNodes.length; i++){
357                                if(usedNodes[i] == 0){
358                                        System.arraycopy(refGraph, 0, loopDetector, 0, refGraph.length);
359                                        idx = i;
360                                        pathId = refGraph.length + idx;
361                                        path = nodeMapInv.get(idx);
362                                        genOrder.clear();
363                                        genOrder.add(0, path);
364                                        process = true;
365                                        loopNotFound = true;
366                                       
367                                        while(process && loopNotFound){
368                                                val = loopDetector[idx];
369                                               
370                                                if(val == -1)
371                                                        process = false;
372                                                else if(val == -pathId)
373                                                        loopNotFound = false;
374                                                else {
375                                                        loopDetector[idx] = -pathId;
376                                                        path = nodeMapInv.get(val) + " -> " + path;
377                                                        genOrder.add(0, nodeMapInv.get(val));
378                                                }
379                                                idx = val;
380                                        }
381                                        if(!loopNotFound){
382                                                throw new Exception("ERROR: Loop detected in atributes dependency, path: "+path);
383                                        }
384                                       
385                                        if(genOrder.size() > 0){
386                                                genOrderList.add((ArrayList<String>)genOrder.clone());
387                                        }
388                                }
389                        }
390                       
391                } catch (XPathExpressionException e) {
392                        e.printStackTrace();
393                } catch (ParserConfigurationException e) {
394                        e.printStackTrace();
395                } catch (SAXException e) {
396                        e.printStackTrace();
397                } catch (IOException e) {
398                        e.printStackTrace();
399                }
400               
401                idDep = genOrderList;
402                return genOrderList;
403        }
404       
405        protected boolean isExternalFileDependent(String idName){
406                if(idName.startsWith("swf."))
407                        return true;
408               
409                return false;
410        }
411       
412        protected double evalExternalFileDependency(String refElementId){
413                String filedName = refElementId.substring(4).toUpperCase();
414               
415                try {
416                        String value = null;
417                       
418                        if("JOB_NUMBER".equals(filedName)){
419                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_JOB_NUMBER];
420                        } else if("SUBMIT_TIME".equals(filedName)){
421                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_SUBMIT_TIME];
422                        } else if("WAIT_TIME".equals(filedName)){
423                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_WAIT_TIME];
424                        } else if("RUN_TIME".equals(filedName)){
425                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_RUN_TIME];
426                        } else if("NUMBER_OF_ALLOCATED_PROCESSORS".equals(filedName)){
427                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_NUMBER_OF_ALLOCATED_PROCESSORS];
428                        } else if("AVERAGE_CPU_TIME_USED".equals(filedName)){
429                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_AVERAGE_CPU_TIME_USED];
430                        } else if("USED_MEMORY".equals(filedName)){
431                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_USED_MEMORY];
432                        } else if("REQUESTED_NUMBER_OF_PROCESSORS".equals(filedName)){
433                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_REQUESTED_NUMBER_OF_PROCESSORS];
434                        } else if("REQUESTED_TIME".equals(filedName)){
435                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_REQUESTED_TIME];
436                        } else if("REQUESTED_MEMORY".equals(filedName)){
437                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_REQUESTED_MEMORY];
438                        } else if("STATUS".equals(filedName)){
439                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_STATUS];
440                        } else if("USER_ID".equals(filedName)){
441                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_USER_ID];
442                        } else if("GROUP_ID".equals(filedName)){
443                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_GROUP_ID];
444                        } else if("EXECUTABLE_NUMBER".equals(filedName)){
445                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_EXECUTABLE_NUMBER];
446                        } else if("QUEUE_NUMBER".equals(filedName)){
447                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_QUEUE_NUMBER];
448                        } else if("PARTITION_NUMBER".equals(filedName)){
449                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_PARTITION_NUMBER];
450                        } else if("PRECEDING_JOB_NUMBER".equals(filedName)){
451                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_PRECEDING_JOB_NUMBER];
452                        } else if("THINK_TIME_FROM_PRECEDING_JOB".equals(filedName)){
453                                value = swfParser.readTask(jobId, taskId)[SWFFields.DATA_THINK_TIME_FROM_PRECEDING_JOB];
454                        } else {
455                                log.error("No external value for element reference "+refElementId + ". Assign default value 0.");
456                                return 0;
457                        }
458                       
459                        return Double.valueOf(value);
460                       
461                } catch (IOException e) {
462                        // TODO Auto-generated catch block
463                        e.printStackTrace();
464                }
465               
466                return 0;
467        }
468       
469        public void close(){
470                try {
471                        swfParser.close();
472                } catch (IOException e) {
473                        e.printStackTrace();
474                }
475        }
476}
Note: See TracBrowser for help on using the repository browser.