Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.735 diff -u -p -r1.735 system.module --- modules/system/system.module 3 Aug 2009 06:06:23 -0000 1.735 +++ modules/system/system.module 4 Aug 2009 02:13:57 -0000 @@ -1552,14 +1552,24 @@ function system_block_view($delta = '') */ function system_admin_menu_block($item) { $cache = &drupal_static(__FUNCTION__, array()); - if (!isset($item['mlid'])) { - $item += db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = :path AND module = 'system'", array(':path' => $item['path']))->fetchAssoc(); - } - if (isset($cache[$item['mlid']])) { - return $cache[$item['mlid']]; + // This function is called on every page request if administrative links are + // displayed, so we cache by path to improve the performance of + // system_admin_menu_block_access(). While path is not guaranteed to be + // unique if users configure their administrative menu using the menu + // interface, we don't support two top level items with the same path + // here since this would require an additional query, or duplicate cache to + // be implemented. + if (isset($cache[$item['path']])) { + return $cache[$item['path']]; } - + global $user; + $cid = 'system_block:' . implode('|', array_keys($user->roles)) . $item['path']; + if ($cached = cache_get($cid, 'cache_menu')) { + $cache[$item['path']] = $cached->data; + return $cached->data; + } + $item += db_query("SELECT mlid, menu_name FROM {menu_links} ml WHERE ml.router_path = :path AND module = 'system'", array(':path' => $item['path']))->fetchAssoc(); $content = array(); $result = db_query(" SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, m.description, ml.* @@ -1581,7 +1591,8 @@ function system_admin_menu_block($item) $content[(50000 + $link['weight']) . ' ' . $link['title'] . ' ' . $link['mlid']] = $link; } ksort($content); - $cache[$item['mlid']] = $content; + cache_set($cid, $content, 'cache_menu'); + $cache[$item['path']] = $content; return $content; } Index: modules/toolbar/toolbar.module =================================================================== RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.module,v retrieving revision 1.4 diff -u -p -r1.4 toolbar.module --- modules/toolbar/toolbar.module 28 Jul 2009 10:35:56 -0000 1.4 +++ modules/toolbar/toolbar.module 4 Aug 2009 02:14:00 -0000 @@ -111,6 +111,15 @@ function toolbar_build() { * Get only the top level items below the 'admin' path. */ function toolbar_get_menu_tree() { + global $user; + // Since generating the key can take 25% of page execution time, cache this + // for each combination of user roles. This guarantees a unique set of + // permissions for the minimum number of cache entries. Use the {cache_menu} + // bin to ensure this cache is cleared when the menu is updated. + $cid = 'toolbar:' . implode('|', array_keys($user->roles)); + if ($cached = cache_get($cid), 'cache_menu') { + return $cached->data; + } $tree = menu_tree_all_data('management'); foreach ($tree as $item) { if ($item['link']['link_path'] == 'admin' && !empty($item['below'])) { @@ -124,6 +133,7 @@ function toolbar_get_menu_tree() { // Get rid of subitems to have a leaner data structure. unset($tree[$key]['below']); } + cache_set($cid, $tree, 'cache_menu'); return $tree; }