]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-18768: Limited size of context and modinfo caches to avoid memory problems with...
authorsam_marshall <sam_marshall>
Mon, 6 Apr 2009 09:48:39 +0000 (09:48 +0000)
committersam_marshall <sam_marshall>
Mon, 6 Apr 2009 09:48:39 +0000 (09:48 +0000)
course/lib.php
lib/accesslib.php
mod/forum/lib.php

index 2d906cf1504e596f59c3eb1fd3b51812602d0a92..1810a5a18dd3433aff6d17ceb6d535080079d01f 100644 (file)
@@ -22,6 +22,9 @@ define('FIRSTUSEDEXCELROW', 3);
 define('MOD_CLASS_ACTIVITY', 0);
 define('MOD_CLASS_RESOURCE', 1);
 
+if (!defined('MAX_MODINFO_CACHE_SIZE')) { 
+    define('MAX_MODINFO_CACHE_SIZE', 10);
+}
 
 function make_log_url($module, $url) {
     switch ($module) {
@@ -1254,6 +1257,11 @@ function &get_fast_modinfo(&$course, $userid=0) {
     unset($cache[$course->id]); // prevent potential reference problems when switching users
     $cache[$course->id] = $modinfo;
 
+    // Ensure cache does not use too much RAM
+    if (count($cache) > MAX_MODINFO_CACHE_SIZE) {
+        array_shift($cache);
+    }
+
     return $cache[$course->id];
 }
 
index 53019e47ee7b34c36e20b95d53810a1479386233..17b37cb4e4f9f264b00b2d3e957fae6e3f8559a3 100755 (executable)
@@ -161,6 +161,11 @@ define('ROLENAME_BOTH', 2);    // Both, like this:  Role alias (Original)
 define('ROLENAME_ORIGINALANDSHORT', 3); // the name as defined in the role definition and the shortname in brackets
 define('ROLENAME_ALIAS_RAW', 4);   // the name as defined by a role alias, in raw form suitable for editing
 
+// size limit for context cache
+if (!defined('MAX_CONTEXT_CACHE_SIZE')) { 
+    define('MAX_CONTEXT_CACHE_SIZE', 5000);
+}
+
 // Although this looks like a global variable, it isn't really. It is just a private
 // implementation detail to accesslib that MUST NOT be used elsewhere. It is used to
 // cache various bits of data between function calls for performance reasons. Sadly,
@@ -205,6 +210,14 @@ function accesslib_clear_all_caches_for_unit_testing() {
  */
 function cache_context($context) {
     global $ACCESSLIB_PRIVATE;
+
+    // If there are too many items in the cache already, remove items until
+    // there is space
+    while (count($ACCESSLIB_PRIVATE->contextsbyid) >= MAX_CONTEXT_CACHE_SIZE) {
+        $first = array_shift($ACCESSLIB_PRIVATE->contextsbyid);
+        unset($ACCESSLIB_PRIVATE->contexts[$first->contextlevel][$first->instanceid]);
+    }
+
     $ACCESSLIB_PRIVATE->contexts[$context->contextlevel][$context->instanceid] = $context;
     $ACCESSLIB_PRIVATE->contextsbyid[$context->id] = $context;
 }
index ebf30f37994aecafe2245303dd96d04e6458b3b1..255f0b90f13036f26fa14a00afb4113a99c9e75c 100644 (file)
@@ -5782,21 +5782,21 @@ function forum_add_user_default_subscriptions($userid, $context) {
     switch ($context->contextlevel) {
 
         case CONTEXT_SYSTEM:   // For the whole site
-             if ($courses = $DB->get_records('course')) {
-                 foreach ($courses as $course) {
-                     $subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                     forum_add_user_default_subscriptions($userid, $subcontext);
-                 }
+             $rs = $DB->get_recordset('course',null,'','id');
+             foreach ($rs as $course) {
+                 $subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
+                 forum_add_user_default_subscriptions($userid, $subcontext);
              }
+             $rs->close();
              break;
 
         case CONTEXT_COURSECAT:   // For a whole category
-             if ($courses = $DB->get_records('course', array('category' => $context->instanceid))) {
-                 foreach ($courses as $course) {
-                     $subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                     forum_add_user_default_subscriptions($userid, $subcontext);
-                 }
+             $rs = $DB->get_recordset('course', array('category' => $context->instanceid),'','id');
+             foreach ($rs as $course) {
+                 $subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
+                 forum_add_user_default_subscriptions($userid, $subcontext);
              }
+             $rs->close();
              if ($categories = $DB->get_records('course_categories', array('parent' => $context->instanceid))) {
                  foreach ($categories as $category) {
                      $subcontext = get_context_instance(CONTEXT_COURSECAT, $category->id);