From 8058f07dc39224df8bd27d4aa267120d5d15deab Mon Sep 17 00:00:00 2001 From: Menci Date: Fri, 26 Apr 2019 02:09:24 +0800 Subject: [PATCH] Optimize judge_state table query with enum type and indexes --- models/judge_state.ts | 31 ++++++++++++++++++++++++++----- modules/admin.js | 2 +- modules/contest.js | 2 +- modules/submission.js | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/models/judge_state.ts b/models/judge_state.ts index 1cf0404..7564443 100644 --- a/models/judge_state.ts +++ b/models/judge_state.ts @@ -9,9 +9,30 @@ import Contest from "./contest"; const Judger = syzoj.lib('judger'); +enum Status { + ACCEPTED = "Accepted", + COMPILE_ERROR = "Compile Error", + FILE_ERROR = "File Error", + INVALID_INTERACTION = "Invalid Interaction", + JUDGEMENT_FAILED = "Judgement Failed", + MEMORY_LIMIT_EXCEEDED = "Memory Limit Exceeded", + NO_TESTDATA = "No Testdata", + OUTPUT_LIMIT_EXCEEDED = "Output Limit Exceeded", + PARTIALLY_CORRECT = "Partially Correct", + RUNTIME_ERROR = "Runtime Error", + SYSTEM_ERROR = "System Error", + TIME_LIMIT_EXCEEDED = "Time Limit Exceeded", + UNKNOWN = "Unknown", + WRONG_ANSWER = "Wrong Answer", + WAITING = "Waiting" +} + @TypeORM.Entity() @TypeORM.Index(['type', 'type_info']) -@TypeORM.Index(['type', 'is_public']) +@TypeORM.Index(['type', 'is_public', 'language', 'status', 'problem_id']) +@TypeORM.Index(['type', 'is_public', 'status', 'problem_id']) +@TypeORM.Index(['type', 'is_public', 'problem_id']) +@TypeORM.Index(['type', 'is_public', 'language', 'problem_id']) @TypeORM.Index(['problem_id', 'type', 'pending', 'score']) export default class JudgeState extends Model { @TypeORM.PrimaryGeneratedColumn() @@ -25,8 +46,8 @@ export default class JudgeState extends Model { language: string; @TypeORM.Index() - @TypeORM.Column({ nullable: true, type: "varchar", length: 50 }) - status: string; + @TypeORM.Column({ nullable: true, type: "enum", enum: Status }) + status: Status; @TypeORM.Index() @TypeORM.Column({ nullable: true, type: "varchar", length: 50 }) @@ -131,7 +152,7 @@ export default class JudgeState extends Model { let oldStatus = this.status; - this.status = 'Unknown'; + this.status = Status.UNKNOWN; this.pending = false; this.score = null; if (this.language) { @@ -148,7 +169,7 @@ export default class JudgeState extends Model { try { await Judger.judge(this, this.problem, 1); this.pending = true; - this.status = 'Waiting'; + this.status = Status.WAITING; await this.save(); } catch (err) { console.log("Error while connecting to judge frontend: " + err.toString()); diff --git a/modules/admin.js b/modules/admin.js index 44f4dfc..b9725ab 100644 --- a/modules/admin.js +++ b/modules/admin.js @@ -363,7 +363,7 @@ app.post('/admin/rejudge', async (req, res) => { } if (req.body.status) { - query.andWhere('status LIKE :status', { status: req.body.status + '%' }); + query.andWhere('status = :status', { status: req.body.status }); } if (req.body.problem_id) { diff --git a/modules/contest.js b/modules/contest.js index 5d8786b..a2a40ad 100644 --- a/modules/contest.js +++ b/modules/contest.js @@ -355,7 +355,7 @@ app.get('/contest/:id/submissions', async (req, res) => { if (displayConfig.showResult) { if (req.query.status) { - query.andWhere('status LIKE :status', { status: req.query.status + '%' }); + query.andWhere('status = :status', { status: req.query.status }); isFiltered = true; } } diff --git a/modules/submission.js b/modules/submission.js index af58da2..954cb58 100644 --- a/modules/submission.js +++ b/modules/submission.js @@ -79,7 +79,7 @@ app.get('/submissions', async (req, res) => { } if (req.query.status) { - query.andWhere('status LIKE :status', { status: req.query.status + '%' }); + query.andWhere('status = :status', { status: req.query.status }); isFiltered = true; }