package zeta.tool;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import zeta.util.DatabaseUtils;
import zeta.util.Parameter;
import zeta.util.Properties;
import zeta.util.ThrowableHandler;
public class GenerateWorkUnits {
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("USAGE: <task ID> <start work unit ID>");
} else {
generate(Integer.parseInt(args[0]), Long.parseLong(args[1]));
}
}
public static void generate(int taskId, long startWorkUnitId) {
Connection connection = null;
Statement stmt = null;
Statement stmt2 = null;
try {
connection = GetData.getConnection();
stmt = connection.createStatement();
stmt2 = connection.createStatement();
Properties properties = new Properties();
int serverId = properties.get("server_id", 1);
long workUnitIdComplete = Parameter.getValue(stmt, "work_unit_id_complete", taskId, 0, 3600000);
long workUnitIdOverlap = Parameter.getValue(stmt, "work_unit_id_overlap", taskId, 0, 3600000);
ResultSet rs = stmt.executeQuery("SELECT MIN(work_unit_id) FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id>=" + startWorkUnitId);
if (rs.next()) {
long maxWorkUnitId = rs.getLong(1);
rs.close();
rs = stmt.executeQuery("SELECT MAX(work_unit_id) FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id<=" + startWorkUnitId);
long minWorkUnitId = (rs.next())? rs.getLong(1) : 0;
rs.close();
rs = stmt.executeQuery("SELECT range FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id=" + minWorkUnitId);
minWorkUnitId += (rs.next())? rs.getInt(1) : 0;
rs.close();
rs = stmt.executeQuery("SELECT work_unit_id,range FROM zeta.server_range WHERE server_id=" + serverId + " AND task_id=" + taskId
+ " AND work_unit_id<=" + startWorkUnitId + " AND work_unit_id+range>" + startWorkUnitId);
if (!rs.next()) {
throw new SQLException("Work unit " + startWorkUnitId + " is not inside a defined range for the server " + serverId);
}
long maxWorkUnitId2 = rs.getLong(1)+rs.getLong(2);
rs.close();
if (minWorkUnitId-workUnitIdOverlap > startWorkUnitId) {
rs = stmt.executeQuery("SELECT MAX(work_unit_id) FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id>=" + minWorkUnitId + " AND work_unit_id<" + (maxWorkUnitId2-workUnitIdOverlap));
minWorkUnitId = (rs.next())? rs.getLong(1) : 0;
rs.close();
rs = stmt.executeQuery("SELECT range FROM zeta.computation WHERE task_id=" + taskId + " AND work_unit_id=" + minWorkUnitId);
minWorkUnitId += (rs.next())? rs.getInt(1) : 0;
rs.close();
minWorkUnitId -= workUnitIdOverlap;
throw new SQLException("Work unit " + startWorkUnitId + " is still defined; a possible work unit may be " + minWorkUnitId);
}
maxWorkUnitId = Math.min(maxWorkUnitId, maxWorkUnitId2);
System.out.println("start: " + startWorkUnitId + ", end: " + maxWorkUnitId);
int numberOfNewWorkUnits = 0;
long rangeAssigned = 0;
rs = stmt.executeQuery("SELECT user_id,workstation_id,range,version,"
+ "COUNT(DISTINCT DAYS(start)) AS start_days,"
+ "COUNT(DISTINCT DAYS(stop)),"
+ "MAX(TIMESTAMPDIFF(8,CAST((stop-start) AS CHAR(22)))) AS a"
+ " FROM zeta.computation c, zeta.result r"
+ " WHERE c.work_unit_id=r.work_unit_id"
+ " AND c.task_id=r.task_id"
+ " AND c.work_unit_id>" + workUnitIdComplete
+ " AND c.task_id=" + taskId
+ " AND c.server_id=" + serverId
+ " AND DAYS(r.stop)>=DAYS(CURRENT DATE)-5"
+ " GROUP BY workstation_id,user_id,range,version"
+ " ORDER BY start_days DESC,a FETCH FIRST 1000 ROWS ONLY");
while (rs.next() && startWorkUnitId < maxWorkUnitId) {
if (rs.getInt(5) >= 5 && rs.getInt(6) >= 5 && rs.getInt(7) <= 24) {
int userId = rs.getInt(1);
int workstationId = rs.getInt(2);
int range = rs.getInt(3);
String version = rs.getString(4);
if (startWorkUnitId+range+workUnitIdOverlap >= maxWorkUnitId) {
range = (int)(maxWorkUnitId-startWorkUnitId+workUnitIdOverlap);
}
DatabaseUtils.executeAndLogUpdate(serverId, stmt2,
"INSERT INTO zeta.computation (task_id,work_unit_id,range,server_id,workstation_id,user_id,version,start) VALUES ("
+ taskId + ',' + startWorkUnitId + ',' + range + ',' + serverId + ',' + workstationId + ',' + userId
+ ",'" + version + "',CURRENT TIMESTAMP)");
System.out.println(String.valueOf(startWorkUnitId) + " (" + range + ") -> " + workstationId + " (" + version + ')');
++numberOfNewWorkUnits;
rangeAssigned += range;
startWorkUnitId += range-workUnitIdOverlap;
}
}
System.out.println("Number of new work units: " + numberOfNewWorkUnits);
System.out.println("Range assigned: " + rangeAssigned);
System.out.println("Next work unit: " + startWorkUnitId);
}
rs.close();
} catch (Exception e) {
ThrowableHandler.handle(e);
} finally {
DatabaseUtils.close(stmt);
DatabaseUtils.close(stmt2);
DatabaseUtils.close(connection);
}
}
}