package zeta.tool.check;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import zeta.util.DatabaseUtils;
import zeta.util.Properties;
import zeta.util.StreamUtils;
import zeta.util.ThrowableHandler;
public class CheckConsistencyZetaZeros implements CheckConsistency {
public boolean checkHeader(long workUnitId, int range, String filename) {
if (filename.endsWith(".log")) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filename));
String line = reader.readLine();
if (!line.startsWith("This run (LASTN=" + workUnitId + ", NRANGE=" + range)) {
if (line.startsWith("This run (LASTN=")) {
int i = 16;
int l = line.length();
while (i < l && Character.isDigit(line.charAt(i))) {
++i;
}
long n = Long.parseLong(line.substring(16, i));
if (n > workUnitId+range || n < workUnitId-range || !line.startsWith(", NRANGE=" + range, i)) {
return false;
}
} else {
return false;
}
}
} catch (IOException ioe) {
ThrowableHandler.handle(ioe);
} finally {
StreamUtils.close(reader);
}
}
return true;
}
public boolean check(long workUnitId, int range, String filename, Connection con) {
if (filename.endsWith(".log")) {
BufferedReader reader = null;
Statement stmt = null;
try {
boolean wrongHeader = !checkHeader(workUnitId, range, filename);
if (wrongHeader) {
System.out.println("Wrong header!");
}
stmt = con.createStatement();
reader = new BufferedReader(new FileReader(filename));
String largeLine = null;
String line = reader.readLine();
boolean footer = false;
boolean wrongFooter = false;
while (line != null) {
line = reader.readLine();
if (line == null) {
break;
}
wrongFooter = footer;
if (line.startsWith("... Close pair of zeros between ")) {
String s = reader.readLine();
if (s != null) {
line += s;
}
int taskId = 1;
Properties properties = new Properties();
DatabaseUtils.executeAndLogUpdate(properties.get("server_id", 1), stmt,
"INSERT INTO zeta.found (task_id,work_unit_id,type,timestamp,found) VALUES ("
+ taskId + ',' + workUnitId + ",'close zeros',CURRENT TIMESTAMP,'" + DatabaseUtils.encodeName(line) + "')");
} else if (line.startsWith(".... Large value at ")) {
if (largeLine != null) {
int idx1 = line.indexOf(':');
int idx2 = largeLine.indexOf(':');
if (idx1 > 0 && idx2 > 0 && ++idx1 < line.length() && ++idx2 < line.length()) {
try {
BigDecimal t1 = new BigDecimal(line.substring(idx1));
BigDecimal t2 = new BigDecimal(largeLine.substring(idx2));
if (t1.compareTo(t2) > 0) {
largeLine = line;
}
} catch (NumberFormatException nfe) {
ThrowableHandler.handle(nfe);
}
}
} else {
largeLine = line;
}
} else if (line.startsWith("LASTN (input for next run) ")) {
int idx = line.indexOf('=');
if (idx > 0 && idx+2 < line.length()) {
try {
long l = 0;
for (idx += 2; idx < line.length(); ++idx) {
char c = line.charAt(idx);
if (Character.isDigit(c)) {
l = l*10 + Character.digit(c, 10);
} else if (c == ' ') {
break;
}
}
if (l+10 < workUnitId+range) {
System.out.println("ERROR: " + line);
}
} catch (NumberFormatException nfe) {
ThrowableHandler.handle(nfe);
}
} else {
System.out.println("ERROR: " + line);
}
} else if (line.equals("@")) {
footer = true;
}
}
if (largeLine != null) {
int taskId = 1;
Properties properties = new Properties();
DatabaseUtils.executeAndLogUpdate(properties.get("server_id", 1), stmt,
"INSERT INTO zeta.found (task_id,work_unit_id,type,timestamp,found) VALUES ("
+ taskId + ',' + workUnitId + ",'large value',CURRENT TIMESTAMP,'" + DatabaseUtils.encodeName(largeLine) + "')");
}
if (!footer || wrongFooter) {
System.out.println("Wrong footer!");
if (wrongHeader) {
throw new RuntimeException("Wrong header and footer!");
}
}
} catch (SQLException se) {
ThrowableHandler.handle(se);
System.exit(1);
} catch (IOException ioe) {
ThrowableHandler.handle(ioe);
} finally {
DatabaseUtils.close(stmt);
StreamUtils.close(reader);
}
}
return true;
}
}