Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'wip-mdl-27120' of git://github.com/rajeshtaneja/moodle

  • Loading branch information...
commit c70b7fd81fa8d40e453ad7f5fa1759df48ae549f 2 parents e6f5528 + f2bfe26
@nebgor nebgor authored
View
20 backup/moodle2/backup_xml_transformer.class.php
@@ -27,6 +27,13 @@
defined('MOODLE_INTERNAL') || die();
+// Cache for storing link encoders, so that we don't need to call
+// register_link_encoders each time backup_xml_transformer is constructed
+// TODO MDL-25290 replace global with MUC code.
+global $LINKS_ENCODERS_CACHE;
+
+$LINKS_ENCODERS_CACHE = array();
+
/**
* Class implementing the @xml_contenttrasnformed logic to be applied in moodle2 backups
*
@@ -131,7 +138,19 @@ static private function process_filephp_uses($matches) {
return $result;
}
+ /**
+ * Register all available content link encoders
+ *
+ * @return array encoder
+ * @todo MDL-25290 replace LINKS_ENCODERS_CACHE global with MUC code
+ */
private function register_link_encoders() {
+ global $LINKS_ENCODERS_CACHE;
+ // If encoder is linked, then return cached encoder.
+ if (!empty($LINKS_ENCODERS_CACHE)) {
+ return $LINKS_ENCODERS_CACHE;
+ }
+
$encoders = array();
// Add the course encoder
@@ -160,6 +179,7 @@ private function register_link_encoders() {
// Add local encodes
// TODO: Any interest? 1.9 never had that.
+ $LINKS_ENCODERS_CACHE = $encoders;
return $encoders;
}
}
View
197 backup/util/dbops/restore_dbops.class.php
@@ -28,6 +28,38 @@
* TODO: Finish phpdocs
*/
abstract class restore_dbops {
+ /**
+ * Keep cache of backup records.
+ * @var array
+ * @todo MDL-25290 static should be replaced with MUC code.
+ */
+ private static $backupidscache = array();
+ /**
+ * Keep track of backup ids which are cached.
+ * @var array
+ * @todo MDL-25290 static should be replaced with MUC code.
+ */
+ private static $backupidsexist = array();
+ /**
+ * Count is expensive, so manually keeping track of
+ * backupidscache, to avoid memory issues.
+ * @var int
+ * @todo MDL-25290 static should be replaced with MUC code.
+ */
+ private static $backupidscachesize = 2048;
+ /**
+ * Count is expensive, so manually keeping track of
+ * backupidsexist, to avoid memory issues.
+ * @var int
+ * @todo MDL-25290 static should be replaced with MUC code.
+ */
+ private static $backupidsexistsize = 10240;
+ /**
+ * Slice backupids cache to add more data.
+ * @var int
+ * @todo MDL-25290 static should be replaced with MUC code.
+ */
+ private static $backupidsslice = 512;
/**
* Return one array containing all the tasks that have been included
@@ -152,6 +184,134 @@ public static function precheck_included_roles($restoreid, $courseid, $userid, $
}
/**
+ * Return cached backup id's
+ *
+ * @param int $restoreid id of backup
+ * @param string $itemname name of the item
+ * @param int $itemid id of item
+ * @return array backup id's
+ * @todo MDL-25290 replace static backupids* with MUC code
+ */
+ protected static function get_backup_ids_cached($restoreid, $itemname, $itemid) {
+ global $DB;
+
+ $key = "$itemid $itemname $restoreid";
+
+ // If record exists in cache then return.
+ if (isset(self::$backupidsexist[$key]) && isset(self::$backupidscache[$key])) {
+ return self::$backupidscache[$key];
+ }
+
+ // Clean cache, if it's full.
+ if (self::$backupidscachesize <= 0) {
+ // Remove some records, to keep memory in limit.
+ self::$backupidscache = array_slice(self::$backupidscache, self::$backupidsslice, null, true);
+ self::$backupidscachesize = self::$backupidscachesize + self::$backupidsslice;
+ }
+ if (self::$backupidsexistsize <= 0) {
+ self::$backupidsexist = array_slice(self::$backupidsexist, self::$backupidsslice, null, true);
+ self::$backupidsexistsize = self::$backupidsexistsize + self::$backupidsslice;
+ }
+
+ // Retrive record from database.
+ $record = array(
+ 'backupid' => $restoreid,
+ 'itemname' => $itemname,
+ 'itemid' => $itemid
+ );
+ if ($dbrec = $DB->get_record('backup_ids_temp', $record)) {
+ self::$backupidsexist[$key] = $dbrec->id;
+ self::$backupidscache[$key] = $dbrec;
+ self::$backupidscachesize--;
+ self::$backupidsexistsize--;
+ return self::$backupidscache[$key];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Cache backup ids'
+ *
+ * @param int $restoreid id of backup
+ * @param string $itemname name of the item
+ * @param int $itemid id of item
+ * @param array $extrarecord extra record which needs to be updated
+ * @return void
+ * @todo MDL-25290 replace static BACKUP_IDS_* with MUC code
+ */
+ protected static function set_backup_ids_cached($restoreid, $itemname, $itemid, $extrarecord) {
+ global $DB;
+
+ $key = "$itemid $itemname $restoreid";
+
+ $record = array(
+ 'backupid' => $restoreid,
+ 'itemname' => $itemname,
+ 'itemid' => $itemid,
+ );
+
+ // If record is not cached then add one.
+ if (!isset(self::$backupidsexist[$key])) {
+ // If we have this record in db, then just update this.
+ if ($existingrecord = $DB->get_record('backup_ids_temp', $record)) {
+ self::$backupidsexist[$key] = $existingrecord->id;
+ self::$backupidsexistsize--;
+ self::update_backup_cached_record($record, $extrarecord, $key, $existingrecord);
+ } else {
+ // Add new record to cache and db.
+ $recorddefault = array (
+ 'newitemid' => 0,
+ 'parentitemid' => null,
+ 'info' => null);
+ $record = array_merge($record, $recorddefault, $extrarecord);
+ $record['id'] = $DB->insert_record('backup_ids_temp', $record);
+ self::$backupidsexist[$key] = $record['id'];
+ self::$backupidsexistsize--;
+ if (self::$backupidscachesize > 0) {
+ // Cache new records if we haven't got many yet.
+ self::$backupidscache[$key] = (object) $record;
+ self::$backupidscachesize--;
+ }
+ }
+ } else {
+ self::update_backup_cached_record($record, $extrarecord, $key);
+ }
+ }
+
+ /**
+ * Updates existing backup record
+ *
+ * @param array $record record which needs to be updated
+ * @param array $extrarecord extra record which needs to be updated
+ * @param string $key unique key which is used to identify cached record
+ * @param stdClass $existingrecord (optional) existing record
+ */
+ protected static function update_backup_cached_record($record, $extrarecord, $key, $existingrecord = null) {
+ global $DB;
+ // Update only if extrarecord is not empty.
+ if (!empty($extrarecord)) {
+ $extrarecord['id'] = self::$backupidsexist[$key];
+ $DB->update_record('backup_ids_temp', $extrarecord);
+ // Update existing cache or add new record to cache.
+ if (isset(self::$backupidscache[$key])) {
+ $record = array_merge((array)self::$backupidscache[$key], $extrarecord);
+ self::$backupidscache[$key] = (object) $record;
+ } else if (self::$backupidscachesize > 0) {
+ if ($existingrecord) {
+ self::$backupidscache[$key] = $existingrecord;
+ } else {
+ // Retrive record from database and cache updated records.
+ self::$backupidscache[$key] = $DB->get_record('backup_ids_temp', $record);
+ }
+ $record = array_merge((array)self::$backupidscache[$key], $extrarecord);
+ self::$backupidscache[$key] = (object) $record;
+ self::$backupidscachesize--;
+ }
+ }
+ }
+
+ /**
* Given one role, as loaded from XML, perform the best possible matching against the assignable
* roles, using different fallback alternatives (shortname, archetype, editingteacher => teacher, defaultcourseroleid)
* returning the id of the best matching role or 0 if no match is found
@@ -1219,16 +1379,7 @@ public static function set_backup_files_record($restoreid, $filerec) {
$DB->insert_record('backup_files_temp', $filerec);
}
-
public static function set_backup_ids_record($restoreid, $itemname, $itemid, $newitemid = 0, $parentitemid = null, $info = null) {
- global $DB;
-
- // Build the basic (mandatory) record info
- $record = array(
- 'backupid' => $restoreid,
- 'itemname' => $itemname,
- 'itemid' => $itemid
- );
// Build conditionally the extra record info
$extrarecord = array();
if ($newitemid != 0) {
@@ -1241,34 +1392,16 @@ public static function set_backup_ids_record($restoreid, $itemname, $itemid, $ne
$extrarecord['info'] = base64_encode(serialize($info));
}
- // TODO: Analyze if some static (and limited) cache by the 3 params could save us a bunch of get_record() calls
- // Note: Sure it will! And also will improve getter
- if (!$dbrec = $DB->get_record('backup_ids_temp', $record)) { // Need to insert the complete record
- $DB->insert_record('backup_ids_temp', array_merge($record, $extrarecord));
-
- } else { // Need to update the extra record info if there is something to
- if (!empty($extrarecord)) {
- $extrarecord['id'] = $dbrec->id;
- $DB->update_record('backup_ids_temp', $extrarecord);
- }
- }
+ self::set_backup_ids_cached($restoreid, $itemname, $itemid, $extrarecord);
}
public static function get_backup_ids_record($restoreid, $itemname, $itemid) {
- global $DB;
+ $dbrec = self::get_backup_ids_cached($restoreid, $itemname, $itemid);
- // Build the basic (mandatory) record info to look for
- $record = array(
- 'backupid' => $restoreid,
- 'itemname' => $itemname,
- 'itemid' => $itemid
- );
- // TODO: Analyze if some static (and limited) cache by the 3 params could save us a bunch of get_record() calls
- if ($dbrec = $DB->get_record('backup_ids_temp', $record)) {
- if ($dbrec->info != null) {
- $dbrec->info = unserialize(base64_decode($dbrec->info));
- }
+ if ($dbrec && isset($dbrec->info) && is_string($dbrec->info)) {
+ $dbrec->info = unserialize(base64_decode($dbrec->info));
}
+
return $dbrec;
}
View
26 backup/util/plan/base_plan.class.php
@@ -61,7 +61,12 @@ public function add_task($task) {
// Append task settings to plan array, if not present, for comodity
foreach ($task->get_settings() as $key => $setting) {
if (!in_array($setting, $this->settings)) {
- $this->settings[] = $setting;
+ $name = $setting->get_name();
+ if (!isset($this->settings[$name])) {
+ $this->settings[$name] = $setting;
+ } else {
+ throw new base_plan_exception('multiple_settings_by_name_found', $name);
+ }
}
}
}
@@ -84,23 +89,16 @@ public function get_settings() {
/**
* return one setting by name, useful to request root/course settings
- * that are, by definition, unique by name. Throws exception if multiple
- * are found
+ * that are, by definition, unique by name.
*
- * TODO: Change this to string indexed array for quicker lookup. Not critical
+ * @param string $name name of the setting
+ * @throws base_plan_exception if setting name is not found.
*/
public function get_setting($name) {
$result = null;
- foreach ($this->settings as $key => $setting) {
- if ($setting->get_name() == $name) {
- if ($result != null) {
- throw new base_plan_exception('multiple_settings_by_name_found', $name);
- } else {
- $result = $setting;
- }
- }
- }
- if (!$result) {
+ if (isset($this->settings[$name])) {
+ $result = $this->settings[$name];
+ } else {
throw new base_plan_exception('setting_by_name_not_found', $name);
}
return $result;
View
22 backup/util/ui/backup_ui_stage.class.php
@@ -124,6 +124,8 @@ protected function initialise_stage_form() {
// Store as a variable so we can iterate by reference
$tasks = $this->ui->get_tasks();
// Iterate all tasks by reference
+ $add_settings = array();
+ $dependencies = array();
foreach ($tasks as &$task) {
// For the initial stage we are only interested in the root settings
if ($task instanceof backup_root_task) {
@@ -134,17 +136,23 @@ protected function initialise_stage_form() {
if ($setting->get_name() == 'filename') {
continue;
}
- $form->add_setting($setting, $task);
+ $add_settings[] = array($setting, $task);
}
// Then add all dependencies
foreach ($settings as &$setting) {
if ($setting->get_name() == 'filename') {
continue;
}
- $form->add_dependencies($setting);
+ $dependencies[] = $setting;
}
}
}
+ // Add all settings at once.
+ $form->add_settings($add_settings);
+ // Add dependencies.
+ foreach ($dependencies as $depsetting) {
+ $form->add_dependencies($depsetting);
+ }
$this->stageform = $form;
}
// Return the form
@@ -226,6 +234,8 @@ protected function initialise_stage_form() {
$tasks = $this->ui->get_tasks();
$content = '';
$courseheading = false;
+ $add_settings = array();
+ $dependencies = array();
foreach ($tasks as $task) {
if (!($task instanceof backup_root_task)) {
if (!$courseheading) {
@@ -235,11 +245,11 @@ protected function initialise_stage_form() {
}
// First add each setting
foreach ($task->get_settings() as $setting) {
- $form->add_setting($setting, $task);
+ $add_settings[] = array($setting, $task);
}
// The add all the dependencies
foreach ($task->get_settings() as $setting) {
- $form->add_dependencies($setting);
+ $dependencies[] = $setting;
}
} else if ($this->ui->enforce_changed_dependencies()) {
// Only show these settings if dependencies changed them.
@@ -254,6 +264,10 @@ protected function initialise_stage_form() {
}
}
}
+ $form->add_settings($add_settings);
+ foreach ($dependencies as $depsetting) {
+ $form->add_dependencies($depsetting);
+ }
$this->stageform = $form;
}
return $this->stageform;
View
42 backup/util/ui/base_moodleform.class.php
@@ -136,24 +136,38 @@ function close_task_divs() {
* @return bool
*/
function add_setting(backup_setting $setting, base_task $task=null) {
+ return $this->add_settings(array(array($setting, $task)));
+ }
+ /**
+ * Adds multiple backup_settings as elements to the form
+ * @param array $settingstasks Consists of array($setting, $task) elements
+ * @return bool
+ */
+ public function add_settings(array $settingstasks) {
global $OUTPUT;
- // If the setting cant be changed or isn't visible then add it as a fixed setting.
- if (!$setting->get_ui()->is_changeable() || $setting->get_visibility() != backup_setting::VISIBLE) {
- return $this->add_fixed_setting($setting, $task);
- }
+ $defaults = array();
+ foreach ($settingstasks as $st) {
+ list($setting, $task) = $st;
+ // If the setting cant be changed or isn't visible then add it as a fixed setting.
+ if (!$setting->get_ui()->is_changeable() || $setting->get_visibility() != backup_setting::VISIBLE) {
+ $this->add_fixed_setting($setting, $task);
+ continue;
+ }
- // First add the formatting for this setting
- $this->add_html_formatting($setting);
+ // First add the formatting for this setting
+ $this->add_html_formatting($setting);
- // The call the add method with the get_element_properties array
- call_user_func_array(array($this->_form, 'addElement'), $setting->get_ui()->get_element_properties($task, $OUTPUT));
- $this->_form->setDefault($setting->get_ui_name(), $setting->get_value());
- if ($setting->has_help()) {
- list($identifier, $component) = $setting->get_help();
- $this->_form->addHelpButton($setting->get_ui_name(), $identifier, $component);
+ // Then call the add method with the get_element_properties array
+ call_user_func_array(array($this->_form, 'addElement'), $setting->get_ui()->get_element_properties($task, $OUTPUT));
+ $defaults[$setting->get_ui_name()] = $setting->get_value();
+ if ($setting->has_help()) {
+ list($identifier, $component) = $setting->get_help();
+ $this->_form->addHelpButton($setting->get_ui_name(), $identifier, $component);
+ }
+ $this->_form->addElement('html', html_writer::end_tag('div'));
}
- $this->_form->addElement('html', html_writer::end_tag('div'));
+ $this->_form->setDefaults($defaults);
return true;
}
/**
@@ -317,4 +331,4 @@ public function require_definition_after_data() {
$this->definition_after_data();
}
}
-}
+}
Please sign in to comment.
Something went wrong with that request. Please try again.