use of com.github.zhanhb.judge.common.JudgeException in project judge by zjnu-acm.
the class JudgeService method runProcess.
private void runProcess(RunRecord runRecord) throws IOException {
Path dataPath = judgeConfiguration.getDataDirectory(runRecord.getProblemId());
Objects.requireNonNull(dataPath, "dataPath");
Path specialFile = dataPath.resolve(JudgeConfiguration.VALIDATE_FILE_NAME);
boolean isSpecial = Files.exists(specialFile);
if (!Files.isDirectory(dataPath)) {
log.error("{} not exists", dataPath);
return;
}
List<Path[]> files = new ArrayList<>(20);
try (DirectoryStream<Path> listFiles = Files.newDirectoryStream(dataPath)) {
log.debug("dataPath = {}", dataPath);
for (Path inFile : listFiles) {
String inFileName = inFile.getFileName().toString();
if (!inFileName.toLowerCase().endsWith(".in")) {
continue;
}
Path outFile = dataPath.resolve(inFileName.substring(0, inFileName.length() - 3) + ".out");
if (!Files.exists(outFile)) {
continue;
}
// 统计输入,输出文件
files.add(new Path[] { inFile, outFile });
}
}
int caseNum = files.size();
log.debug("caseNum = {}", caseNum);
if (caseNum == 0) {
log.error("No test cases found for problem({})", runRecord.getProblemId());
return;
}
// 最后通过的个数
int accept = 0;
ArrayList<String> details = new ArrayList<>(caseNum << 2);
String command = runRecord.getLanguage().getExecuteCommand();
// 建立临时文件
Path work = judgeConfiguration.getWorkDirectory(runRecord.getSubmissionId());
command = StringUtils.hasText(command) ? command : work.resolve("Main." + runRecord.getLanguage().getExecutableExtension()).toString();
long extTime = runRecord.getLanguage().getExtTime();
long castTimeLimit = runRecord.getTimeLimit() * runRecord.getLanguage().getTimeFactor() + extTime;
// 内存附加
long extraMemory = runRecord.getLanguage().getExtMemory();
long caseMemoryLimit = (runRecord.getMemoryLimit() + extraMemory) * 1024;
Options[] optionses = new Options[caseNum];
for (int cas = 0; cas < caseNum; cas++) {
Path[] entry = files.get(cas);
Path in = entry[0];
Path standard = entry[1];
Path progOutput = work.resolve(standard.getFileName());
optionses[cas] = Options.builder().timeLimit(// time limit
castTimeLimit).memoryLimit(// memory in bytes
caseMemoryLimit).outputLimit(// 16M
16 * 1024 * 1024).command(command).workDirectory(work).inputFile(in).outputFile(progOutput).standardOutput(standard).errFile(NULL_FILE.toPath()).build();
}
String detailMessageStr = null;
String scorePerCase = new DecimalFormat("0.#").format(100.0 / caseNum);
final Validator validator = isSpecial ? new SpecialValidator(specialFile.toString(), work) : SimpleValidator.PE_AS_ACCEPTED;
// 时间
long time = 0;
// 内存
long memory = 0;
try {
ExecuteResult[] ers = JudgeBridge.INSTANCE.judge(optionses, false, validator);
for (ExecuteResult er : ers) {
long tim1 = Math.max(0, er.getTime() - extTime);
long mem1 = Math.max(0, er.getMemory() / 1024 - extraMemory);
String message = er.getMessage();
boolean success = er.isSuccess();
time = Math.max(time, tim1);
memory = Math.max(memory, mem1);
log.debug("message = {}, time = {}, memory = {}", message, time, memory);
details.add(String.valueOf(er.getCode().getResult()));
details.add(success ? scorePerCase : "0");
details.add(String.valueOf(tim1));
details.add(String.valueOf(mem1));
if (success) {
++accept;
}
}
} catch (JudgeException | RuntimeException | Error ex) {
log.error("", ex);
accept = ResultType.SYSTEM_ERROR;
detailMessageStr = ex.getMessage();
}
log.debug("{}", details);
int score = accept >= 0 ? (int) Math.round(accept * 100.0 / caseNum) : accept;
if (score == 0 && accept != 0) {
++score;
} else if (score == ResultType.SCORE_ACCEPT && accept != caseNum) {
--score;
}
submissionMapper.updateResult(runRecord.getSubmissionId(), score, time, memory);
submissionMapper.saveDetail(runRecord.getSubmissionId(), detailMessageStr != null ? detailMessageStr : details.stream().map(String::valueOf).collect(Collectors.joining(",")));
updateSubmissionStatus(runRecord);
}
Aggregations