use of com.github.zhanhb.judge.win32.SpecialValidator 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);
}
use of com.github.zhanhb.judge.win32.SpecialValidator in project judge by zjnu-acm.
the class JudgeServiceImpl method execute.
@Override
public void execute(long submissionId) {
Submission submission = submissionMapper.findOne(submissionId);
if (submission == null) {
throw new BusinessException(BusinessCode.SUBMISSION_NOT_FOUND, submissionId);
}
long problemId = submission.getProblem();
Problem problem = problemService.findOneNoI18n(problemId);
try {
RunRecord runRecord = RunRecord.builder().language(languageService.getAvailableLanguage(submission.getLanguage())).source(submissionDetailMapper.findSourceById(submissionId)).memoryLimit(problem.getMemoryLimit()).timeLimit(problem.getTimeLimit()).build();
Path dataDirectory = systemService.getDataDirectory(problemId);
JudgeData judgeData = JudgeData.parse(dataDirectory);
Path specialFile = systemService.getSpecialJudgeExecutable(problemId);
boolean isSpecial = systemService.isSpecialJudge(problemId);
// 建立临时文件
Path work = systemService.getWorkDirectory(submissionId);
final Validator validator = isSpecial ? new SpecialValidator(specialFile.toString(), work) : SimpleValidator.PE_AS_AC;
boolean deleteTempFile = systemService.isDeleteTempFile();
RunResult runResult = judgeRunner.run(runRecord, work, judgeData, validator, deleteTempFile);
SubmissionDetail detail = SubmissionDetail.builder().id(submissionId).compileInfo(runResult.getCompileInfo()).detail(runResult.getDetail()).systemInfo(runResult.getSystemInfo()).build();
if (runResult.getType() == Status.COMPILATION_ERROR) {
submissionMapper.updateResult(submissionId, ResultType.COMPILE_ERROR, 0, 0);
} else {
int score = runResult.getScore();
long time = runResult.getTime();
long memory = runResult.getMemory();
submissionMapper.updateResult(submissionId, score, time, memory);
}
// TODO return value not handled, we can do nothing for the record not exists in the table now.
submissionDetailMapper.update(detail);
updateSubmissionStatus(submission.getUser(), problemId);
} catch (ThreadDeath | VirtualMachineError error) {
throw error;
} catch (JudgeException | IOException | Error ex) {
log.error("got an exception when judging submission {}", submissionId, ex);
submissionMapper.updateResult(submissionId, ResultType.SYSTEM_ERROR, 0, 0);
StringWriter sw = new StringWriter();
try (PrintWriter pw = new PrintWriter(sw)) {
ex.printStackTrace(pw);
}
submissionDetailMapper.update(SubmissionDetail.builder().id(submissionId).systemInfo(sw.toString()).build());
}
}
Aggregations