Permalink
Browse files

MDL-33857 Increase performance of queries for Server files repository…

… (small improvements)
  • Loading branch information...
1 parent c84b704 commit ed7e6a735663de70df69d4d759550cbf11383a3d @marinaglancy marinaglancy committed Sep 20, 2012
@@ -143,7 +143,7 @@ public function get_non_empty_children($extensions = '*') {
$nonemptylist[] = $fileinfo;
} else {
$filename = $fileinfo->get_visible_name();
- $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+ $extension = textlib::strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!empty($extension) && in_array('.'.$extension, $extensions)) {
$nonemptylist[] = $fileinfo;
}
@@ -156,7 +156,7 @@ public function get_non_empty_children($extensions = '*') {
* Returns the number of children which are either files matching the specified extensions
* or folders containing at least one such file.
*
- * NOTE: We don't need the exact number of non empty children if it is >=2
+ * We usually don't need the exact number of non empty children if it is >=2 (see param $limit)
* This function is used by repository_local to evaluate if the folder is empty. But
* it also can be used to check if folder has only one subfolder because in some cases
* this subfolder can be skipped.
@@ -166,27 +166,32 @@ public function get_non_empty_children($extensions = '*') {
* and memory usage on big sites).
*
* @param string|array $extensions, for example '*' or array('.gif','.jpg')
+ * @param int $limit stop counting after at least $limit non-empty children are found
* @return int
*/
- public function count_non_empty_children($extensions = '*') {
+ public function count_non_empty_children($extensions = '*', $limit = 1) {
$list = $this->get_children();
$cnt = 0;
+ // first loop through files
foreach ($list as $fileinfo) {
- if ($cnt > 1) {
- // it only matters if it is 0, 1 or 2+
- return $cnt;
- }
- if ($fileinfo->is_directory()) {
- if ($fileinfo->count_non_empty_children($extensions)) {
- $cnt++;
+ if (!$fileinfo->is_directory()) {
+ if ($extensions !== '*') {
+ $filename = $fileinfo->get_visible_name();
+ $extension = textlib::strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+ if (empty($extension) || !in_array('.'.$extension, $extensions)) {
+ continue;
+ }
}
- } else if ($extensions === '*') {
- $cnt++;
- } else {
- $filename = $fileinfo->get_visible_name();
- $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
- if (!empty($extension) && in_array('.'.$extension, $extensions)) {
- $cnt++;
+ if ((++$cnt) >= $limit) {
+ return $cnt;
+ }
+ }
+ }
+ // now loop through directories
+ foreach ($list as $fileinfo) {
+ if ($fileinfo->is_directory() && $fileinfo->count_non_empty_children($extensions)) {
+ if ((++$cnt) >= $limit) {
+ return $cnt;
}
}
}
@@ -357,7 +357,8 @@ public function get_children() {
* Help function to return files matching extensions or their count
*
* @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
- * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1)
+ * @param bool|int $countonly if false returns the children, if an int returns just the
+ * count of children but stops counting when $countonly number of children is reached
* @param bool $returnemptyfolders if true returns items that don't have matching files inside
* @return array|int array of file_info instances or the count
*/
@@ -375,8 +376,8 @@ private function get_filtered_children($extensions = '*', $countonly = false, $r
if ($child = $this->get_file_info($area[0], $area[1], 0, '/', '.')) {
if ($returnemptyfolders || $child->count_non_empty_children($extensions)) {
$children[] = $child;
- if ($countonly && count($children)>1) {
- return 2;
+ if (($countonly !== false) && count($children)>=$countonly) {
+ return $countonly;
}
}
}
@@ -396,15 +397,15 @@ private function get_filtered_children($extensions = '*', $countonly = false, $r
if ($child = $this->browser->get_file_info($modcontext)) {
if ($returnemptyfolders || $child->count_non_empty_children($extensions)) {
$children[] = $child;
- if ($countonly && count($children)>1) {
- return 2;
+ if (($countonly !== false) && count($children)>=$countonly) {
+ return $countonly;
}
}
}
}
}
- if ($countonly) {
+ if ($countonly !== false) {
return count($children);
}
return $children;
@@ -425,14 +426,12 @@ public function get_non_empty_children($extensions = '*') {
* Returns the number of children which are either files matching the specified extensions
* or folders containing at least one such file.
*
- * NOTE: We don't need the exact number of non empty children if it is >=2
- * In this function 1 is never returned to avoid skipping the single subfolder
- *
* @param string|array $extensions, for example '*' or array('.gif','.jpg')
+ * @param int $limit stop counting after at least $limit non-empty children are found
* @return int
*/
- public function count_non_empty_children($extensions = '*') {
- return $this->get_filtered_children($extensions, true);
+ public function count_non_empty_children($extensions = '*', $limit = 1) {
+ return $this->get_filtered_children($extensions, $limit);
}
/**
@@ -535,7 +534,7 @@ public function get_non_empty_children($extensions = '*') {
$storedfiles = $fs->get_directory_files($this->context->id, 'course', 'legacy', 0,
$this->lf->get_filepath(), false, true, "filepath, filename");
foreach ($storedfiles as $file) {
- $extension = strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION));
+ $extension = textlib::strtolower(pathinfo($file->get_filename(), PATHINFO_EXTENSION));
if ($file->is_directory() || $extensions === '*' || (!empty($extension) && in_array('.'.$extension, $extensions))) {
$fileinfo = new file_info_area_course_legacy($this->browser, $this->context, $file, $this->urlbase, $this->topvisiblename,
$this->itemidused, $this->readaccess, $this->writeaccess, false);
@@ -656,29 +655,35 @@ public function get_children() {
* Returns the number of children which are either files matching the specified extensions
* or folders containing at least one such file.
*
- * NOTE: We don't need the exact number of non empty children if it is >=2
- * In this function 1 is never returned to avoid skipping the single subfolder
- *
* @param string|array $extensions, for example '*' or array('.gif','.jpg')
+ * @param int $limit stop counting after at least $limit non-empty children are found
* @return int
*/
- public function count_non_empty_children($extensions = '*') {
+ public function count_non_empty_children($extensions = '*', $limit = 1) {
global $DB;
$params1 = array(
'courseid' => $this->course->id,
'contextid' => $this->context->id,
'component' => 'course',
'filearea' => 'section',
'emptyfilename' => '.');
- $sql1 = "SELECT 1 from {files} f, {course_sections} cs
+ $sql1 = "SELECT DISTINCT cs.id FROM {files} f, {course_sections} cs
WHERE cs.course = :courseid
AND f.contextid = :contextid
AND f.component = :component
AND f.filearea = :filearea
AND f.itemid = cs.id
AND f.filename <> :emptyfilename";
list($sql2, $params2) = $this->build_search_files_sql($extensions);
- return $DB->record_exists_sql($sql1.' '.$sql2, array_merge($params1, $params2)) ? 2 : 0;
+ $rs = $DB->get_recordset_sql($sql1. ' '. $sql2, array_merge($params1, $params2));
+ $cnt = 0;
+ foreach ($rs as $record) {
+ if ((++$cnt) >= $limit) {
+ break;
+ }
+ }
+ $rs->close();
+ return $cnt;
}
/**
@@ -796,29 +801,35 @@ public function get_children() {
* Returns the number of children which are either files matching the specified extensions
* or folders containing at least one such file.
*
- * NOTE: We don't need the exact number of non empty children if it is >=2
- * In this function 1 is never returned to avoid skipping the single subfolder
- *
* @param string|array $extensions, for example '*' or array('.gif','.jpg')
+ * @param int $limit stop counting after at least $limit non-empty children are found
* @return int
*/
- public function count_non_empty_children($extensions = '*') {
+ public function count_non_empty_children($extensions = '*', $limit = 1) {
global $DB;
$params1 = array(
'courseid' => $this->course->id,
'contextid' => $this->context->id,
'component' => 'backup',
'filearea' => 'section',
'emptyfilename' => '.');
- $sql1 = "SELECT 1 from {files} f, {course_sections} cs
+ $sql1 = "SELECT DISTINCT cs.id sectionid FROM {files} f, {course_sections} cs
WHERE cs.course = :courseid
AND f.contextid = :contextid
AND f.component = :component
AND f.filearea = :filearea
AND f.itemid = cs.id
AND f.filename <> :emptyfilename";
list($sql2, $params2) = $this->build_search_files_sql($extensions);
- return $DB->record_exists_sql($sql1.' '.$sql2, array_merge($params1, $params2)) ? 2 : 0;
+ $rs = $DB->get_recordset_sql($sql1. ' '. $sql2, array_merge($params1, $params2));
+ $cnt = 0;
+ foreach ($rs as $record) {
+ if ((++$cnt) >= $limit) {
+ break;
+ }
+ }
+ $rs->close();
+ return $cnt;
}
/**
@@ -192,44 +192,60 @@ public function get_children() {
* Returns the number of children which are either files matching the specified extensions
* or folders containing at least one such file.
*
- * NOTE: We don't need the exact number of non empty children if it is >=2
- * In this function 1 is never returned to avoid skipping the single subfolder
- *
* @param string|array $extensions, for example '*' or array('.gif','.jpg')
+ * @param int $limit stop counting after at least $limit non-empty children are found
* @return int
*/
- public function count_non_empty_children($extensions = '*') {
+ public function count_non_empty_children($extensions = '*', $limit = 1) {
global $DB;
+ $cnt = 0;
if (($child = $this->get_area_coursecat_description(0, '/', '.'))
- && $child->count_non_empty_children($extensions)) {
- return 2;
+ && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) {
+ return $cnt;
}
- $course_cats = $DB->get_records('course_categories', array('parent'=>$this->category->id), 'sortorder', 'id,visible');
- foreach ($course_cats as $category) {
- $context = context_coursecat::instance($category->id);
- if (!$category->visible and !has_capability('moodle/category:viewhiddencategories', $context)) {
+ $rs = $DB->get_recordset_sql('SELECT ctx.id contextid, c.visible
+ FROM {context} ctx, {course} c
+ WHERE ctx.instanceid = c.id
+ AND ctx.contextlevel = :courselevel
+ AND c.category = :categoryid
+ ORDER BY c.visible DESC', // retrieve visible courses first
+ array('categoryid' => $this->category->id, 'courselevel' => CONTEXT_COURSE));
+ foreach ($rs as $record) {
+ $context = context::instance_by_id($record->contextid);
+ if (!$record->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
continue;
}
if (($child = $this->browser->get_file_info($context))
- && $child->count_non_empty_children($extensions)) {
- return 2;
+ && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) {
+ break;
}
}
+ $rs->close();
+ if ($cnt >= $limit) {
+ return $cnt;
+ }
- $courses = $DB->get_records('course', array('category'=>$this->category->id), 'sortorder', 'id,visible');
- foreach ($courses as $course) {
- $context = context_course::instance($course->id);
- if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
+ $rs = $DB->get_recordset_sql('SELECT ctx.id contextid, cat.visible
+ FROM {context} ctx, {course_categories} cat
+ WHERE ctx.instanceid = cat.id
+ AND ctx.contextlevel = :catlevel
+ AND cat.parent = :categoryid
+ ORDER BY cat.visible DESC', // retrieve visible categories first
+ array('categoryid' => $this->category->id, 'catlevel' => CONTEXT_COURSECAT));
+ foreach ($rs as $record) {
+ $context = context::instance_by_id($record->contextid);
+ if (!$record->visible and !has_capability('moodle/category:viewhiddencategories', $context)) {
continue;
}
if (($child = $this->browser->get_file_info($context))
- && $child->count_non_empty_children($extensions)) {
- return 2;
+ && $child->count_non_empty_children($extensions) && (++$cnt) >= $limit) {
+ break;
}
}
+ $rs->close();
- return 0;
+ return $cnt;
}
/**
@@ -268,7 +268,8 @@ public function get_children() {
* Help function to return files matching extensions or their count
*
* @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
- * @param bool $countonly if true returns the count of children (0, 1 or 2 if more than 1)
+ * @param bool|int $countonly if false returns the children, if an int returns just the
+ * count of children but stops counting when $countonly number of children is reached
* @param bool $returnemptyfolders if true returns items that don't have matching files inside
* @return array|int array of file_info instances or the count
*/
@@ -303,13 +304,13 @@ private function get_filtered_children($extensions = '*', $countonly = false, $r
if ($child = $this->get_file_info($area[0], $area[1], null, null, null)) {
if ($returnemptyfolders || $child->count_non_empty_children($extensions)) {
$children[] = $child;
- if ($countonly && count($children)>1) {
+ if ($countonly !== false && count($children) >= $countonly) {
break;
}
}
}
}
- if ($countonly) {
+ if ($countonly !== false) {
return count($children);
}
return $children;
@@ -319,11 +320,10 @@ private function get_filtered_children($extensions = '*', $countonly = false, $r
* Returns list of children which are either files matching the specified extensions
* or folders that contain at least one such file.
*
- * @param string|array $extensions, either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
+ * @param string|array $extensions either '*' or array of lowercase extensions, i.e. array('.gif','.jpg')
* @return array of file_info instances
*/
public function get_non_empty_children($extensions = '*') {
- global $DB;
if ($this->nonemptychildren !== null) {
return $this->nonemptychildren;
}
@@ -335,17 +335,15 @@ public function get_non_empty_children($extensions = '*') {
* Returns the number of children which are either files matching the specified extensions
* or folders containing at least one such file.
*
- * NOTE: We don't need the exact number of non empty children if it is >=2
- *
- * @param string|array $extensions, for example '*' or array('.gif','.jpg')
+ * @param string|array $extensions for example '*' or array('.gif','.jpg')
+ * @param int $limit stop counting after at least $limit non-empty children are found
* @return int
*/
- public function count_non_empty_children($extensions = '*') {
- global $DB;
+ public function count_non_empty_children($extensions = '*', $limit = 1) {
if ($this->nonemptychildren !== null) {
return count($this->nonemptychildren);
}
- return $this->get_filtered_children($extensions, true);
+ return $this->get_filtered_children($extensions, $limit);
}
/**
Oops, something went wrong.

0 comments on commit ed7e6a7

Please sign in to comment.