Skip to content

Commit

Permalink
studentquiz#72 Performance optimization: Don't load all attempts on s…
Browse files Browse the repository at this point in the history
…tart
  • Loading branch information
muqiuq committed Dec 11, 2018
1 parent 7a165c9 commit 7bb60c3
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 18 deletions.
15 changes: 14 additions & 1 deletion attempt.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,27 @@

$questionusage = question_engine::load_questions_usage_by_activity($attempt->questionusageid);

$slots = $questionusage->get_slots();

$questionids = explode(",",$attempt->ids);
$originalnumofquestionids = count($questionids);

if(!in_array($slot, $slots)) {
mod_studentquiz_add_question_to_attempt($questionusage, $studentquiz, $questionids, $slot-1);
if(count($questionids) != $originalnumofquestionids) {
$attempt->ids = implode(",", $questionids);
$DB->update_record('studentquiz_attempt', $attempt);
}
}

$actionurl = new moodle_url('/mod/studentquiz/attempt.php', array('cmid' => $cmid, 'id' => $attemptid, 'slot' => $slot));
// Reroute this to attempt summary page if desired.
$stopurl = new moodle_url('/mod/studentquiz/view.php', array('id' => $cmid));

// Get Current Question.
$question = $questionusage->get_question($slot);
// Navigatable?
$questionscount = $questionusage->question_count();
$questionscount = count($questionids);
$hasnext = $slot < $questionscount;
$hasprevious = $slot > $questionusage->get_first_question_number();
$canfinish = $questionusage->can_question_finish_during_attempt($slot);
Expand Down
3 changes: 2 additions & 1 deletion db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
</TABLE>
<TABLE NAME="studentquiz_progress" COMMENT="Store progress information of student with this question">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Id of question"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Id of user"/>
<FIELD NAME="studentquizid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Id of studentquiz"/>
Expand All @@ -59,7 +60,6 @@
<FIELD NAME="correctattempts" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Number of correct answers" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="questionid,userid,studentquizid"/>
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="questionid" TYPE="foreign" FIELDS="questionid" REFTABLE="question" REFFIELDS="id"/>
<KEY NAME="studentquizid" TYPE="foreign" FIELDS="studentquizid" REFTABLE="studentquiz" REFFIELDS="id"/>
Expand Down Expand Up @@ -121,6 +121,7 @@
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="questionusageid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="categoryid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="ids" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT=""/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
38 changes: 38 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -393,5 +393,43 @@ function xmldb_studentquiz_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2018051300, 'studentquiz');
}

if($oldversion < 2018121101) {
// Repair table studentquiz_progress
$table = new xmldb_table('studentquiz_progress');

// Adding fields to table studentquiz_progress.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('studentquizid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('lastanswercorrect', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, 0);
$table->add_field('attempts', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
$table->add_field('correctattempts', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);

// Add key.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('questionid', XMLDB_KEY_FOREIGN, array('questionid'), 'question', array('id'));
$table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
$table->add_key('studentquizid', XMLDB_KEY_FOREIGN, array('studentquizid'), 'studentquiz', array('id'));

if($dbman->table_exists($table)) {
$dbman->drop_table($table);
}

// Conditionally launch create table for studentquiz_progress.
$dbman->create_table($table);

$table = new xmldb_table('studentquiz_attempt');
$field = new xmldb_field('ids', XMLDB_TYPE_TEXT, 'medium', null, null, null, null);

// Add field intro.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}


upgrade_mod_savepoint(true, 2018121101, 'studentquiz');
}

return true;
}
45 changes: 30 additions & 15 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -372,31 +372,46 @@ function mod_studentquiz_generate_attempt($ids, $studentquiz, $userid) {
// TODO: Check if this is instance id from studentquiz table.
$attempt->studentquizid = $studentquiz->id;

// Add questions to usage.
// Don't shuffle($ids) as per requirement for now.
$usageorder = array();
$allowedcategories = question_categorylist($studentquiz->categoryid);
foreach ($ids as $i => $questionid) {
$questiondata = question_bank::load_question($questionid);
// We have to check if the question is really from this module, limit questions to categories used in this module.
if (in_array($questiondata->category, $allowedcategories)) {
$usageorder[$i] = $questionusage->add_question($questiondata);
}
}

// Persistence.
// TODO: Is it necessary to start all questions here, or just the current one?
$questionusage->start_all_questions();
// Add first question to usage
mod_studentquiz_add_question_to_attempt($questionusage, $studentquiz, $ids);

question_engine::save_questions_usage_by_activity($questionusage);

$attempt->questionusageid = $questionusage->get_id();
$attempt->ids = implode(",",$ids);

$attempt->id = $DB->insert_record('studentquiz_attempt', $attempt);

return $attempt;
}

/**
* @param $questionusage question_usage_by_activity
* @param $studentquiz stdClass $studentquiz generating this attempt
* @param $questionids array $ids of question ids to be used in this attempt
* @throws coding_exception
*/
function mod_studentquiz_add_question_to_attempt(&$questionusage, $studentquiz, &$questionids, $lastslost = 0) {
$allowedcategories = question_categorylist($studentquiz->categoryid);
$i = $lastslost;
$addedquestions = 0;
while($addedquestions <= 0 && $i < count($questionids)) {
$questiondata = question_bank::load_question($questionids[$i]);
if (in_array($questiondata->category, $allowedcategories)) {
$questionusage->add_question($questiondata);
$addedquestions++;
}else{
unset($questionids[$i]);
$questionids = array_values($questionids);
}
$i++;
}

if($addedquestions == 0) throw new moodle_exception("Could not load any valid question for attempt", "studentquiz");

$questionusage->start_question($i);
}


/**
* Trigger Report viewed Event
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
defined('MOODLE_INTERNAL') || die();

$plugin->component = 'mod_studentquiz';
$plugin->version = 2018112900;
$plugin->version = 2018121101;
$plugin->release = 'v3.2.0';
$plugin->requires = 2017111306; // Version MOODLE_31, 3.1.0.
$plugin->maturity = MATURITY_STABLE;
Expand Down

0 comments on commit 7bb60c3

Please sign in to comment.