Minor fixes in LifxLightBulb driver (not fully tested yet)
[iot2.git] / iotjava / iotruntime / master / LoadBalancer.java
1 package iotruntime.master;
2
3 import java.util.Collection;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import java.util.Arrays;
8
9 import iotinstaller.MySQLInterface;
10 import iotinstaller.TableProperty;
11 import iotinstaller.Table;
12
13 /** Class LoadBalancer is a class that derives information
14  *  about hosts (compute nodes) from the database and select
15  *  a certain host to do a computation at a certain situation
16  *  based on the metrics given to calculate the most load-balanced
17  *  job assignment
18  *
19  * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
20  * @version     1.0
21  * @since       2016-01-18
22  */
23 public class LoadBalancer {
24
25         /**
26          * LoadBalancer class properties
27          * <p>
28          * Class properties to contain host information from table
29          * HOSTADDRESS is in the form of MAC address that gets translated
30          * through DHCP
31          * hmNumProcesses tracks the usage of a certain host/compute node
32          * hmLoadScore tracks the score of the load for each host;
33          * host selection for the next process is based on these scores
34          * +----------------------+-----------+--------+------------+
35          * | HOSTADDRESS          | PROCESSOR | MEMORY | #PROCESSES |
36          * +----------------------+-----------+--------+------------+
37          * | XX:XX:XX:XX:XX:XX    |      3500 |     32 |          1 |
38          * | XX:XX:XX:XX:XX:XX    |      3500 |     32 |          4 |
39          * | ...                  |      ...  |    ... |        ... |
40          * | ...                  |      ...  |    ... |        ... |
41          * +----------------------+-----------+--------+------------+
42          */
43         private HashMap<String, Integer> hmHostAddress;
44         private int[] arrProcessor;
45         private int[] arrMemory;
46         private int[] arrNumProcesses;
47         private int[] arrLoadScore;
48         private Table tbl;
49         private boolean bVerbose;
50
51         /**
52          * LoadBalancer class constants
53          */
54 //      private static final String STR_TABLE_COMPUTE_NODE = "IoTComputeNodePC";
55     private static final String STR_TABLE_COMPUTE_NODE = "IoTComputeNode";
56
57         /**
58          * Class constructor
59          */
60         public LoadBalancer(boolean _bVerbose) {
61
62                 hmHostAddress = new HashMap<String, Integer>();
63                 arrProcessor = null;
64                 arrMemory = null;
65                 arrNumProcesses = null;
66                 arrLoadScore = null;
67                 tbl = new Table(STR_TABLE_COMPUTE_NODE, _bVerbose);
68                 bVerbose = _bVerbose;
69                 RuntimeOutput.print("LoadBalancer: Creating a load-balancer!", bVerbose);
70         }
71
72         /**
73          * setupLoadBalancer() method loads host information from DB
74          *
75          * @return  void
76          */
77         public void setupLoadBalancer() {
78
79                 String[][] arrTbl = tbl.getGeneralDBTable();
80                 arrProcessor = new int[arrTbl.length];
81                 arrMemory = new int[arrTbl.length];
82                 arrNumProcesses = new int[arrTbl.length];
83                 arrLoadScore = new int[arrTbl.length];
84
85                 for(int i=0; i<arrTbl.length; i++) {
86
87                         // Iterate per row from the DB table
88                         hmHostAddress.put((String) arrTbl[i][0], i);
89                         arrProcessor[i] = Integer.parseInt((String) arrTbl[i][1]);
90                         arrMemory[i] = Integer.parseInt((String) arrTbl[i][2]);
91
92                         // Initialize #process to 0 for all entries in the beginning
93                         // Initialize load score to maximum integer value
94                         arrNumProcesses[i] = 0;
95                         arrLoadScore[i] = Integer.MAX_VALUE;
96                 }
97                 RuntimeOutput.print("LoadBalancer: Initializing load balancer...", bVerbose);
98         }
99
100         /**
101          * selectHost() method selects a host based on the metrics
102          *
103          * @return  void
104          */
105         public String selectHost() {
106
107                 // Variable for highest score that we are going to select
108                 int iHighestScore = 0;
109
110                 //String strHostMACAddress = null;
111                 String strHostIPAddress = null;
112
113                 RuntimeOutput.print("LoadBalancer: Host address number: " + hmHostAddress.size(), bVerbose);
114
115                 // Get the first host address from the hashmap
116                 strHostIPAddress = (String) hmHostAddress.keySet().toArray()[0];
117                 for(Map.Entry<String, Integer> mapHost : hmHostAddress.entrySet()) {
118
119                         // Get the current entry load score
120                         int iEntryScore = arrLoadScore[mapHost.getValue()];
121
122                         // Compare highest score and entry score; select the highest
123                         if (iHighestScore < iEntryScore) {
124                                 iHighestScore = iEntryScore;
125                                 strHostIPAddress = mapHost.getKey();
126                         }
127                 }
128
129                 // Calculate the new score for this host and return the host address
130                 calculateHostScore(strHostIPAddress);
131                 RuntimeOutput.print("LoadBalancer: Selected host: " + strHostIPAddress, bVerbose);
132
133                 return strHostIPAddress;
134         }
135
136         /**
137          * calculateHostScore() calculates score for a host based on the metrics
138          * <p>
139          * It also stores the results back to the corresponding hashmaps
140          *
141          * @param   strHostAddress   String host address
142          * @return                   void
143          */
144         private void calculateHostScore(String strHostAddress) {
145
146                 // Get the previous values
147                 int iIndex = hmHostAddress.get(strHostAddress);
148                 int iPrevNumProcesses = arrNumProcesses[iIndex];
149
150                 // Calculate the current values
151                 // Every time we call this method, we increment #process by 1
152                 // (we add one new process)
153                 int iCurrNumProcesses = iPrevNumProcesses + 1;
154                 int iProcessor = arrProcessor[iIndex];
155                 int iMemory = arrMemory[iIndex];
156
157                 // We calculate the score simply with this formula
158                 // Score = (Processor/current #process) x (Memory/current #process)
159                 // The more processes a certain node has, the lower its score is.
160                 // Therefore, we always choose a node that has the highest score.
161                 // P.S. In this formula we also take the processor and memory specs
162                 // into account
163                 int iCurrScore = (iProcessor * iMemory) / iCurrNumProcesses;
164                 arrLoadScore[iIndex] = iCurrScore;
165                 arrNumProcesses[iIndex] = iCurrNumProcesses;
166                 RuntimeOutput.print("LoadBalancer: Calculate host load score for " + strHostAddress, bVerbose);
167         }
168
169         /**
170          * printHostInfo() method prints the host information at runtime
171          *
172          * @return  void
173          */
174         public void printHostInfo() {
175
176                 for(Map.Entry<String, Integer> mapHost : hmHostAddress.entrySet()) {
177
178                         RuntimeOutput.print("Host address        : " + mapHost.getKey(), bVerbose);
179                         RuntimeOutput.print("Processor           : " + arrProcessor[mapHost.getValue()], bVerbose);
180                         RuntimeOutput.print("Memory              : " + arrMemory[mapHost.getValue()], bVerbose);
181                         RuntimeOutput.print("Number of processes : " + arrNumProcesses[mapHost.getValue()], bVerbose);
182                         RuntimeOutput.print("Host score          : " + arrLoadScore[mapHost.getValue()], bVerbose);
183                 }
184         }
185
186         public static void main(String[] args) {
187
188                 LoadBalancer lb = new LoadBalancer(true);
189                 lb.setupLoadBalancer();
190                 System.out.println("Chosen host: " + lb.selectHost());
191                 System.out.println("Chosen host: " + lb.selectHost());
192                 System.out.println("Chosen host: " + lb.selectHost());
193                 System.out.println("Chosen host: " + lb.selectHost());
194                 System.out.println("Chosen host: " + lb.selectHost());
195                 System.out.println("Chosen host: " + lb.selectHost());
196                 System.out.println("Chosen host: " + lb.selectHost());
197                 System.out.println("Chosen host: " + lb.selectHost());
198                 lb.printHostInfo();
199         }
200 }