Skip to content

Commit

Permalink
MDL-47911 gradebook: Improve the performance of set_usedinaggregation
Browse files Browse the repository at this point in the history
This function is called many many times during grade calculation, so it
should be as efficient as possible.
  • Loading branch information
ericmerrill authored and Damyon Wiese committed Feb 27, 2015
1 parent cf2927b commit 4ea7da7
Showing 1 changed file with 22 additions and 31 deletions.
53 changes: 22 additions & 31 deletions lib/grade/grade_category.php
Expand Up @@ -767,6 +767,8 @@ private function aggregate_grades($userid,
* Set the flags on the grade_grade items to indicate how individual grades are used
* in the aggregation.
*
* WARNING: This function is called a lot during gradebook recalculation, be very performance considerate.
*
* @param int $userid The user we have aggregated the grades for.
* @param array $usedweights An array with keys for each of the grade_item columns included in the aggregation. The value are the relative weight.
* @param array $novalue An array with keys for each of the grade_item columns skipped because
Expand All @@ -779,44 +781,32 @@ private function aggregate_grades($userid,
private function set_usedinaggregation($userid, $usedweights, $novalue, $dropped, $extracredit) {
global $DB;

// First set them all to weight null and status = 'unknown'.
if ($allitems = grade_item::fetch_all(array('categoryid'=>$this->id))) {
list($itemsql, $itemlist) = $DB->get_in_or_equal(array_keys($allitems), SQL_PARAMS_NAMED, 'g');
// Reset aggregation to unknown and 0 for all grade items for this user and category.
$params = array('categoryid' => $this->id, 'userid' => $userid);
$itemssql = "SELECT id
FROM {grade_items}
WHERE categoryid = :categoryid";

$itemlist['userid'] = $userid;
$sql = "UPDATE {grade_grades}
SET aggregationstatus = 'unknown',
aggregationweight = 0
WHERE userid = :userid
AND itemid IN ($itemssql)";

$DB->set_field_select('grade_grades',
'aggregationstatus',
'unknown',
"itemid $itemsql AND userid = :userid",
$itemlist);
$DB->set_field_select('grade_grades',
'aggregationweight',
0,
"itemid $itemsql AND userid = :userid",
$itemlist);
}
$DB->execute($sql, $params);

// Included.
// Included with weights.
if (!empty($usedweights)) {
// The usedweights items are updated individually to record the weights.
foreach ($usedweights as $gradeitemid => $contribution) {
$DB->set_field_select('grade_grades',
'aggregationweight',
$contribution,
"itemid = :itemid AND userid = :userid",
array('itemid'=>$gradeitemid, 'userid'=>$userid));
}
$sql = "UPDATE {grade_grades}
SET aggregationstatus = 'used',
aggregationweight = :contribution
WHERE itemid = :itemid AND userid = :userid";

// Now set the status flag for all these weights.
list($itemsql, $itemlist) = $DB->get_in_or_equal(array_keys($usedweights), SQL_PARAMS_NAMED, 'g');
$itemlist['userid'] = $userid;

$DB->set_field_select('grade_grades',
'aggregationstatus',
'used',
"itemid $itemsql AND userid = :userid",
$itemlist);
$params = array('contribution' => $contribution, 'itemid' => $gradeitemid, 'userid' => $userid);
$DB->execute($sql, $params);
}
}

// No value.
Expand Down Expand Up @@ -844,6 +834,7 @@ private function set_usedinaggregation($userid, $usedweights, $novalue, $dropped
"itemid $itemsql AND userid = :userid",
$itemlist);
}

// Extra credit.
if (!empty($extracredit)) {
list($itemsql, $itemlist) = $DB->get_in_or_equal(array_keys($extracredit), SQL_PARAMS_NAMED, 'g');
Expand Down

0 comments on commit 4ea7da7

Please sign in to comment.