Esempio n. 1
0
/**
 * Scoreboard calculation
 *
 * Given a contestid, teamid and a problemid,
 * (re)calculate the values for one row in the scoreboard.
 *
 * Due to current transactions usage, this function MUST NOT contain
 * any START TRANSACTION or COMMIT statements.
 */
function calcScoreRow($cid, $team, $prob)
{
    global $DB;
    logmsg(LOG_DEBUG, "calcScoreRow '{$cid}' '{$team}' '{$prob}'");
    // First acquire an advisory lock to prevent other calls to
    // calcScoreRow() from interfering with our update.
    $lockstr = "domjudge.{$cid}.{$team}.{$prob}";
    if ($DB->q("VALUE SELECT GET_LOCK('{$lockstr}',3)") != 1) {
        error("calcScoreRow failed to obtain lock '{$lockstr}'");
    }
    // Note the clause 'submittime < c.endtime': this is used to
    // filter out TOO-LATE submissions from pending, but it also means
    // that these will not count as solved. Correct submissions with
    // submittime after contest end should never happen, unless one
    // resets the contest time after successful judging.
    $result = $DB->q('SELECT result, verified, submittime,
	                  (c.freezetime IS NOT NULL && submittime >= c.freezetime) AS afterfreeze
	                  FROM submission s
	                  LEFT JOIN judging j ON(s.submitid=j.submitid AND j.valid=1)
	                  LEFT OUTER JOIN contest c ON(c.cid=s.cid)
	                  WHERE teamid = %i AND probid = %i AND s.cid = %i AND s.valid = 1 ' . (dbconfig_get('compile_penalty', 1) ? "" : "AND j.result != 'compiler-error' ") . 'AND submittime < c.endtime
	                  ORDER BY submittime', $team, $prob, $cid);
    // reset vars
    $submitted_j = $pending_j = $time_j = $correct_j = 0;
    $submitted_p = $pending_p = $time_p = $correct_p = 0;
    // for each submission
    while ($row = $result->next()) {
        // Contest submit time in minutes for scoring.
        $submittime = (int) floor(calcContestTime($row['submittime'], $cid) / 60);
        // Check if this submission has a publicly visible judging result:
        if (dbconfig_get('verification_required', 0) && !$row['verified'] || empty($row['result'])) {
            $pending_j++;
            $pending_p++;
            // Don't do any more counting for this submission.
            continue;
        }
        $submitted_j++;
        if ($row['afterfreeze']) {
            // Show submissions after freeze as pending to the public
            // (if SHOW_PENDING is enabled):
            $pending_p++;
        } else {
            $submitted_p++;
        }
        // if correct, don't look at any more submissions after this one
        if ($row['result'] == 'correct') {
            $correct_j = 1;
            $time_j = $submittime;
            if (!$row['afterfreeze']) {
                $correct_p = 1;
                $time_p = $submittime;
            }
            // stop counting after a first correct submission
            break;
        }
    }
    // insert or update the values in the public/team scores table
    $DB->q('REPLACE INTO scorecache_public
	        (cid, teamid, probid, submissions, pending, totaltime, is_correct)
	        VALUES (%i,%i,%i,%i,%i,%i,%i)', $cid, $team, $prob, $submitted_p, $pending_p, $time_p, $correct_p);
    // insert or update the values in the jury scores table
    $DB->q('REPLACE INTO scorecache_jury
	        (cid, teamid, probid, submissions, pending, totaltime, is_correct)
	        VALUES (%i,%i,%i,%i,%i,%i,%i)', $cid, $team, $prob, $submitted_j, $pending_j, $time_j, $correct_j);
    if ($DB->q("VALUE SELECT RELEASE_LOCK('{$lockstr}')") != 1) {
        error("calcScoreRow failed to release lock '{$lockstr}'");
    }
    // If we found a new correct result, update the rank cache too
    if ($correct_j > 0) {
        updateRankCache($cid, $team, true);
    }
    if ($correct_p > 0) {
        updateRankCache($cid, $team, false);
    }
    return;
}
} elseif (isset($_POST['export'])) {
    // Fetch data from database and store in an associative array
    $cid = @$_POST['contest'];
    $contest_row = $DB->q("MAYBETUPLE SELECT * FROM contest WHERE cid = %i", $cid);
    if (!$contest_row) {
        echo "<p>Contest not found.</p>\n";
        require LIBWWWDIR . '/footer.php';
        exit;
    }
    $contest_data = array();
    $contest_data['name'] = $contest_row['name'];
    $contest_data['short-name'] = $contest_row['name'];
    $contest_data['start-time'] = date('c', $contest_row['starttime']);
    $contest_data['duration'] = printtimerel(calcContestTime($contest_row['endtime'], $contest_row['cid']));
    if (!is_null($contest_row['freezetime'])) {
        $contest_data['scoreboard-freeze'] = printtimerel(calcContestTime($contest_row['freezetime'], $contest_row['cid']));
    }
    // TODO: event-feed-port
    $contest_data['penaltytime'] = dbconfig_get('penalty_time');
    /*
    $contest_data['default-clars'] = dbconfig_get('clar_answers');
    $contest_data['clar-categories'] = array_values(dbconfig_get('clar_categories'));
    */
    $contest_data['languages'] = array();
    $q = $DB->q("SELECT * FROM language");
    while ($lang = $q->next()) {
        $language = array();
        $language['name'] = $lang['name'];
        // TODO: compiler, -flags, runner, -flags?
        $contest_data['languages'][] = $language;
    }
Esempio n. 3
0
    if ($row['description'] != 'problem submitted' && $row['description'] != 'problem judged') {
        continue;
    }
    $data = $DB->q('MAYBETUPLE SELECT submittime, teamid, probid, name AS langname, valid
	                FROM submission
	                LEFT JOIN language USING (langid)
	                WHERE valid = 1 AND submitid = %i', $row['submitid']);
    if (empty($data) || difftime($data['submittime'], $cdata['endtime']) >= 0 || !isset($prob_to_id[$data['probid']]) || !isset($team_to_id[$data['teamid']])) {
        continue;
    }
    $run = XMLaddnode($root, 'run');
    XMLaddnode($run, 'id', $row['submitid']);
    XMLaddnode($run, 'problem', $prob_to_id[$data['probid']]);
    XMLaddnode($run, 'team', $team_to_id[$data['teamid']]);
    XMLaddnode($run, 'timestamp', $row['eventtime']);
    XMLaddnode($run, 'time', calcContestTime($data['submittime'], $cid));
    XMLaddnode($run, 'language', $data['langname']);
    if ($row['description'] == 'problem submitted') {
        XMLaddnode($run, 'judged', 'False');
        XMLaddnode($run, 'status', 'fresh');
    } else {
        $jdata = $DB->q('MAYBETUPLE SELECT result, starttime FROM judging j
		                 LEFT JOIN submission USING(submitid)
		                 WHERE j.valid = 1 AND judgingid = %i', $row['judgingid']);
        if (!isset($jdata['result'])) {
            continue;
        }
        $ntestcases = $DB->q('VALUE SELECT count(*) FROM testcase
		                      WHERE probid = %i', $data['probid']);
        $jruns = $DB->q('SELECT rank, runresult, runtime
		                 FROM judging_run