View Javadoc

1   /*
2    * $Id: SimpleProrater.java 1540 2011-08-17 13:30:37Z hoheisel $
3    *
4    * Copyright (c) 2005, The K-Wf Grid Consortium
5    * Fraunhofer Institute for Computer Architecture and Software Technology
6    * See http://www.kwfgrid.eu and http://www.first.fraunhofer.de for more details.
7    */
8   
9   package net.kwfgrid.gwes.prorater;
10  
11  import net.kwfgrid.gworkflowdl.structure.Transition;
12  import net.kwfgrid.gworkflowdl.structure.OperationClass;
13  import net.kwfgrid.gworkflowdl.structure.OperationCandidate;
14  import net.kwfgrid.gwes.exception.DatabaseException;
15  import net.kwfgrid.gwes.Constants;
16  
17  import java.io.IOException;
18  import java.util.*;
19  
20  /**
21   * Simple implementation of a Prorater
22   *
23   * @author Helge Rose' and Andreas Hoheisel
24   * @version $Id: SimpleProrater.java 1540 2011-08-17 13:30:37Z hoheisel $
25   */
26  public class SimpleProrater extends AbstractProrater {
27  
28      /**
29       * key is hardware identifier, value is Node object.
30       */
31      HashMap<String, Node> nodes;
32  
33      /**
34       * key is hardware identifier, value is time of last assignment of this hardware
35       */
36      HashMap<String, Long> lastAssignments;
37  
38      void init(ArrayList<Transition> transitions) throws IOException {
39          logger.debug("Init:");
40          long now = System.currentTimeMillis();
41          if (nodes == null) nodes = new HashMap<String, Node>();
42          if (lastAssignments == null) lastAssignments = new HashMap<String, Long>();
43          nodes.clear();
44          int priority = 0;
45          for (Transition transition : transitions) {
46              Object oo = transition.getOperation().get();
47              if (oo instanceof OperationClass) {
48  
49                  OperationCandidate[] operationCandidates = ((OperationClass) oo).getOperationCandidates();
50                  for (OperationCandidate operationCandidate : operationCandidates) {
51                      String resourceName = operationCandidate.getResourceName();
52                      // skip hardware that has been recently assigned (wait for load update)
53                      Long last = lastAssignments.get(resourceName);
54                      if (last != null && now - last < WAIT_AFTER_LAST_ASSIGNMENT) continue;
55                      // <property name="priority">1</property>
56                      String propStr = transition.getProperties().get(Constants.PROP_TRANSITION_PRIORITY);
57                      if (propStr != null) {
58                          try {
59                              priority = Integer.parseInt(propStr);
60                          } catch (NumberFormatException e) {
61                              // do nothing.
62                          }
63                      }
64                      Alternative alternative = new Alternative(transition, operationCandidate, priority);
65                      Node node = nodes.get(resourceName);
66  
67                      if (node == null) {
68                          node = new Node(resourceName);
69                          node.updateQuality(operationCandidate.getQuality());
70                          nodes.put(resourceName, node);
71                      }
72  
73                      // Only nodes with a high quality get into the game
74                      if (node.quality > MIN_QUALITY) {
75                          node.add(alternative);
76                      }
77                      // for the others set the quality
78                      else {
79                          alternative.operationCandidate.setQuality(node.quality);
80                      }
81  
82                  }
83                  ++priority;
84              }
85          }
86  
87          if (logger.isDebugEnabled()) {
88              logger.debug("--------- last resource assignments ---------");
89              for (String hw : lastAssignments.keySet()) {
90                  logger.debug(hw + ": " + lastAssignments.get(hw));
91              }
92          }
93      }
94  
95      /**
96       * @return True if there has been a decision, false if not.
97       */
98      boolean decide() {
99          boolean ret = false;
100         if (nodes.size() == 0) return ret;
101         logger.debug("Decide:");
102         ArrayList<Transition> tdone = new ArrayList<Transition>();
103         ArrayList<Node> nc = new ArrayList<Node>();
104         nc.addAll(nodes.values());
105         Collections.shuffle(nc, new Random(System.currentTimeMillis()));
106         for (Node node : nc) {
107             int nr = node.alternatives.size();	// number of alternative operationCandidates involving this host
108             if (nr == 0) continue;
109             if (logger.isDebugEnabled()) {
110                 logger.debug("Node: " + node.hostname);
111             }
112             Collections.sort(node.alternatives);
113             Collections.reverse(node.alternatives);	// transitions with high priority first
114             for (int i = 0; i < nr; ++i) {
115                 Alternative a = node.alternatives.get(i);
116                 if (!tdone.contains(a.transition)) {
117                     // find equal priorities
118                     int tries, j = i;
119                     while (j + 1 < nr && a.priority == node.alternatives.get(j + 1).priority) ++j;
120                     // choose random transition in case of equal priorities
121                     if (j > i) {
122                         //System.out.println("node: "+node.hostname+" equal priorities: "+i+"-"+j);
123                         tries = j - i;
124                         while (tries-- > 0) {
125                             Alternative b = node.alternatives.get(i + (int) ((j - i) * Math.random() + 0.5));
126                             if (!tdone.contains(b.transition)) {
127                                 a = b;
128                                 break;
129                             }
130                         }
131                         i = j;
132                     }
133                     a.operationCandidate.setSelected(true);
134                     ret = true;
135                     tdone.add(a.transition);
136                     lastAssignments.put(node.hostname, System.currentTimeMillis());
137                     logger.info("  " + a.priority + ": " + a.operationCandidate.getResourceName() + ": " + a.transition.getID());
138                     break;
139                 }
140             }
141         }
142         return ret;
143     }
144 }