From fa1392fa4bb9c49f583dab04901d05ff00c4cc0b Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 10 Feb 2021 12:53:42 +0800 Subject: [PATCH] =?UTF-8?q?core:=20=E4=BC=98=E5=8C=96AC=E9=87=8F=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=20-=20=E6=AF=94=E8=B5=9B=E4=B8=AD=E4=B8=8D=E8=AE=A1?= =?UTF-8?q?=E5=85=A5nAccept=20-=20script.problemStat=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7AC=E9=87=8F=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/judge.ts | 14 +++---- packages/hydrooj/src/model/document.ts | 6 ++- packages/hydrooj/src/script/problemStat.ts | 47 +++++++++++++++++++++- 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index c62e036f8..d153ec459 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.17.12", + "version": "2.17.13", "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 5356cab7b..3fd261ca4 100644 --- a/packages/hydrooj/src/handler/judge.ts +++ b/packages/hydrooj/src/handler/judge.ts @@ -19,6 +19,10 @@ async function _postJudge(rdoc: Rdoc) { if (typeof rdoc.input === 'string') return; const accept = rdoc.status === builtin.STATUS.STATUS_ACCEPTED; const tasks = []; + tasks.push( + problem.inc(rdoc.domainId, rdoc.pid, 'nAccept', 1), + problem.updateStatus(rdoc.domainId, rdoc.pid, rdoc.uid, rdoc._id, rdoc.status), + ); if (rdoc.contest) { tasks.push( contest.updateStatus( @@ -26,14 +30,8 @@ async function _postJudge(rdoc: Rdoc) { rdoc._id, rdoc.pid, accept, rdoc.score, rdoc.contest.type, ), ); - } - if (await problem.updateStatus(rdoc.domainId, rdoc.pid, rdoc.uid, rdoc._id, rdoc.status)) { - if (accept && !rdoc.rejudged) { - tasks.push( - problem.inc(rdoc.domainId, rdoc.pid, 'nAccept', 1), - domain.incUserInDomain(rdoc.domainId, rdoc.uid, 'nAccept', 1), - ); - } + } else { + tasks.push(domain.incUserInDomain(rdoc.domainId, rdoc.uid, 'nAccept', 1)); } await Promise.all(tasks); } diff --git a/packages/hydrooj/src/model/document.ts b/packages/hydrooj/src/model/document.ts index dde86f35c..901d7a342 100644 --- a/packages/hydrooj/src/model/document.ts +++ b/packages/hydrooj/src/model/document.ts @@ -303,10 +303,12 @@ export async function setMultiStatus( export async function setIfNotStatus( domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, - key: K, value: number, ifNot: DocStatusType[T][K], args: Partial, + key: K, value: DocStatusType[T][K], ifNot: DocStatusType[T][K], args: Partial, ): Promise { + const current = await collStatus.findOne({ domainId, docType, docId, uid }) || {}; + if (current[key] === ifNot) return current; const res = await collStatus.findOneAndUpdate( - { domainId, docType, docId, uid, [key]: { $not: { $eq: ifNot } } }, + { domainId, docType, docId, uid }, { $set: { [key]: value, ...args } }, { upsert: true, returnOriginal: false }, ); diff --git a/packages/hydrooj/src/script/problemStat.ts b/packages/hydrooj/src/script/problemStat.ts index dd909a268..cc5bb40f0 100644 --- a/packages/hydrooj/src/script/problemStat.ts +++ b/packages/hydrooj/src/script/problemStat.ts @@ -4,11 +4,50 @@ import * as document from '../model/document'; export const description = 'Recalcuates nSubmit and nAccept in problem status.'; -export async function run() { +export async function udoc() { const pipeline = [ + { $match: { hidden: false, type: { $ne: 'run' } } }, { - $match: { hidden: false, type: { $ne: 'run' } }, + $group: { + _id: { domainId: '$domainId', pid: '$pid', uid: '$uid' }, + nSubmit: { $sum: 1 }, + nAccept: { + $sum: { + $cond: [{ $eq: ['$status', STATUS.STATUS_ACCEPTED] }, 1, 0], + }, + }, + }, }, + { + $group: { + _id: { domainId: '$_id.domainId', uid: '$_id.uid' }, + nSubmit: { $sum: '$nSubmit' }, + nAccept: { $sum: { $min: ['$nAccept', 1] } }, + }, + }, + ]; + const bulk = db.collection('domain.user').initializeUnorderedBulkOp(); + db.collection('record').aggregate(pipeline).each( + (err, adoc: any) => { + if (adoc) { + bulk.find({ + domainId: adoc._id.domainId, + uid: adoc._id.uid, + }).updateOne({ + $set: { + nSubmit: adoc.nSubmit, + nAccept: adoc.nAccept, + }, + }); + } + }, + ); + if (bulk.length) await bulk.execute(); +} + +export async function pdoc() { + const pipeline = [ + { $match: { hidden: false, type: { $ne: 'run' } } }, { $group: { _id: { domainId: '$domainId', pid: '$pid', uid: '$uid' }, @@ -48,6 +87,10 @@ export async function run() { if (bulk.length) await bulk.execute(); } +export async function run() { + return await Promise.all([udoc(), pdoc()]); +} + export const validate = {}; global.Hydro.script.problemStat = { run, description, validate };