From faae0805c1a8f7c2d15e4688795af41b96eabd37 Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 21 Apr 2021 22:19:04 +0800 Subject: [PATCH] core: add judge priority system --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/judge.ts | 6 ++++-- packages/hydrooj/src/model/blacklist.ts | 2 +- packages/hydrooj/src/model/opcount.ts | 2 +- packages/hydrooj/src/model/record.ts | 16 +++++++++++++--- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 176540adc..09c5c7a3f 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.23.13", + "version": "2.23.14", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/handler/judge.ts b/packages/hydrooj/src/handler/judge.ts index d6479604c..7e94cf158 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -33,8 +33,10 @@ async function _postJudge(rdoc: Rdoc) { : await problem.get(rdoc.domainId, rdoc.pid); const difficulty = difficultyAlgorithm(pdoc.nSubmit, pdoc.nAccept); if (!updated) await record.updateMulti(rdoc.domainId, { uid: rdoc.uid, status: builtin.STATUS.STATUS_ACCEPTED }, { effective: false }); - await record.update(rdoc.domainId, rdoc._id, { effective: true }); - await problem.edit(pdoc.domainId, pdoc.docId, { difficulty }); + await Promise.all([ + record.update(rdoc.domainId, rdoc._id, { effective: true }), + problem.edit(pdoc.domainId, pdoc.docId, { difficulty }), + ]); await bus.serial('record/judge', rdoc, updated); } diff --git a/packages/hydrooj/src/model/blacklist.ts b/packages/hydrooj/src/model/blacklist.ts index 8ae2461c7..c0e902a87 100644 --- a/packages/hydrooj/src/model/blacklist.ts +++ b/packages/hydrooj/src/model/blacklist.ts @@ -9,7 +9,7 @@ class BlackListModel { @ArgMethod static async add(id: string, expire?: Date | number) { let expireAt; - if (expire === 0) expireAt = moment().add(1000, 'years').toDate(); + if (expire === 0) expireAt = moment().add(1000, 'months').toDate(); if (typeof expire === 'number') expireAt = moment().add(expire, 'months').toDate(); else if (expire instanceof Date) expireAt = expire; else expireAt = new Date(new Date().getTime() + 365 * 24 * 60 * 60 * 1000); diff --git a/packages/hydrooj/src/model/opcount.ts b/packages/hydrooj/src/model/opcount.ts index 09e72666b..f7745f75d 100644 --- a/packages/hydrooj/src/model/opcount.ts +++ b/packages/hydrooj/src/model/opcount.ts @@ -13,7 +13,7 @@ export async function inc(op: string, ident: string, periodSecs: number, maxOper ident, beginAt, expireAt, - op: { $not: { $gte: maxOperations } }, + op: { $lt: maxOperations }, }, { $inc: { op: 1 } }, { upsert: true }); } catch (e) { throw new OpcountExceededError(op, periodSecs, maxOperations); diff --git a/packages/hydrooj/src/model/record.ts b/packages/hydrooj/src/model/record.ts index 6f47be7ba..cc6aeaa1e 100644 --- a/packages/hydrooj/src/model/record.ts +++ b/packages/hydrooj/src/model/record.ts @@ -3,7 +3,7 @@ import { PushOperator, MatchKeysAndValues, OnlyFieldsOfType, FilterQuery, } from 'mongodb'; -import { Dictionary } from 'lodash'; +import { sum } from 'lodash'; import moment from 'moment'; import { STATUS } from './builtin'; import task from './task'; @@ -16,6 +16,13 @@ import db from '../service/db'; class RecordModel { static coll: Collection = db.collection('record'); + static async submissionPriority(uid: number) { + const pending = await task.count({ uid }); + const timeRecent = await RecordModel.coll + .find({ _id: { $gte: Time.getObjectID(moment().add(-1, 'hour')) }, uid }).project({ time: 1 }).toArray(); + return -(pending * (sum(timeRecent) / 1000)); + } + static async get(domainId: string, _id: ObjectID): Promise { const res = await RecordModel.coll.findOne({ _id }); if (res && res.domainId === domainId) return res; @@ -86,7 +93,10 @@ class RecordModel { data.hidden = true; } else data.contest = contestOrConfig; const res = await RecordModel.coll.insertOne(data); - if (addTask) await RecordModel.judge(domainId, res.insertedId); + if (addTask) { + const priority = await RecordModel.submissionPriority(uid); + await RecordModel.judge(domainId, res.insertedId, 1 - priority); + } return res.insertedId; } @@ -151,7 +161,7 @@ class RecordModel { static async getList( domainId: string, rids: ObjectID[], showHidden: boolean, - ): Promise> { + ): Promise> { const r = {}; rids = Array.from(new Set(rids)); const rdocs = await RecordModel.coll.find({ domainId, _id: { $in: rids } }).toArray();