Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.255.2.9
diff -u -p -r1.255.2.9 menu.inc
--- includes/menu.inc	27 Feb 2008 12:12:01 -0000	1.255.2.9
+++ includes/menu.inc	10 Mar 2008 11:21:21 -0000
@@ -773,13 +773,17 @@ function menu_tree_all_data($menu_name =
   // Use $mlid as a flag for whether the data being loaded is for the whole tree.
   $mlid = isset($item['mlid']) ? $item['mlid'] : 0;
   // Generate the cache ID.
-  $cid = 'links:'. $menu_name .':all:'. $mlid;
+  $cid = 'links-cid:'. $menu_name .':all:'. $mlid;
 
   if (!isset($tree[$cid])) {
     // If the static variable doesn't have the data, check {cache_menu}.
     $cache = cache_get($cid, 'cache_menu');
     if ($cache && isset($cache->data)) {
-      $data = $cache->data;
+      // The first entry is just the cid for the real data, to avoid duplication.
+      $cache = cache_get($cache->data, 'cache_menu');
+      if ($cache && isset($cache->data)) {
+        $data = $cache->data;
+      }
     }
     else {
       // Build and run the query, and build the tree.
@@ -813,8 +817,12 @@ function menu_tree_all_data($menu_name =
         ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", $args), $parents);
       $data['node_links'] = array();
       menu_tree_collect_node_links($data['tree'], $data['node_links']);
-      // Cache the data.
-      cache_set($cid, $data, 'cache_menu');
+      // Cache the data, or just a reference to the already cached data.
+      $tree_cid = _menu_tree_cid($data);
+      if (!_menu_tree_is_cached($tree_cid)) {
+        cache_set($tree_cid, $data, 'cache_menu');
+      }
+      cache_set($cid, $tree_cid, 'cache_menu');
     }
     // Check access for the current user to each item in the tree.
     menu_tree_check_access($data['tree'], $data['node_links']);
@@ -845,13 +853,17 @@ function menu_tree_page_data($menu_name 
   // Load the menu item corresponding to the current page.
   if ($item = menu_get_item()) {
     // Generate the cache ID.
-    $cid = 'links:'. $menu_name .':page:'. $item['href'] .':'. (int)$item['access'];
+    $cid = 'links-cid:'. $menu_name .':page:'. $item['href'] .':'. (int)$item['access'];
 
     if (!isset($tree[$cid])) {
       // If the static variable doesn't have the data, check {cache_menu}.
       $cache = cache_get($cid, 'cache_menu');
       if ($cache && isset($cache->data)) {
-        $data = $cache->data;
+        // The first entry is just the cid for the real data, to avoid duplication.
+        $cache = cache_get($cache->data, 'cache_menu');
+        if ($cache && isset($cache->data)) {
+          $data = $cache->data;
+        }
       }
       else {
         // Build and run the query, and build the tree.
@@ -909,8 +921,12 @@ function menu_tree_page_data($menu_name 
           ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", $args), $parents);
         $data['node_links'] = array();
         menu_tree_collect_node_links($data['tree'], $data['node_links']);
-        // Cache the data.
-        cache_set($cid, $data, 'cache_menu');
+        // Cache the data, or just a reference to the already cached data.
+        $tree_cid = _menu_tree_cid($data);
+        if (!cache_get($tree_cid, 'cache_menu')) {
+          cache_set($tree_cid, $data, 'cache_menu');
+        }
+        cache_set($cid, $tree_cid, 'cache_menu');
       }
       // Check access for the current user to each item in the tree.
       menu_tree_check_access($data['tree'], $data['node_links']);
@@ -923,6 +939,13 @@ function menu_tree_page_data($menu_name 
 }
 
 /**
+ * Helper function - compute the real cache ID for menu tree data.
+ */
+function _menu_tree_cid($data) {
+  return 'tree:'. md5(serialize($data));
+}
+
+/**
  * Recursive helper function - collect node links.
  */
 function menu_tree_collect_node_links(&$tree, &$node_links) {
cvs diff: Diffing misc
cvs diff: Diffing misc/farbtastic
cvs diff: Diffing modules
cvs diff: Diffing modules/aggregator
cvs diff: Diffing modules/block
cvs diff: Diffing modules/blog
cvs diff: Diffing modules/blogapi
cvs diff: Diffing modules/book
Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.454.2.2
diff -u -p -r1.454.2.2 book.module
--- modules/book/book.module	13 Feb 2008 11:20:47 -0000	1.454.2.2
+++ modules/book/book.module	10 Mar 2008 11:21:22 -0000
@@ -1044,12 +1044,16 @@ function book_link_load($mlid) {
 function book_menu_subtree_data($item) {
   static $tree = array();
 
-  $cid = 'links:'. $item['menu_name'] .':subtree:'. $item['mlid'];
+  $cid = 'links-cid:'. $item['menu_name'] .':subtree:'. $item['mlid'];
 
   if (!isset($tree[$cid])) {
     $cache = cache_get($cid, 'cache_menu');
     if ($cache && isset($cache->data)) {
-      $data = $cache->data;
+      // The first entry is just the cid for the real data, to avoid duplication.
+      $cache = cache_get($cache->data, 'cache_menu');
+      if ($cache && isset($cache->data)) {
+        $data = $cache->data;
+      }
     }
     else {
       $match = array("menu_name = '%s'");
@@ -1070,8 +1074,12 @@ function book_menu_subtree_data($item) {
       $data['tree'] = menu_tree_data(db_query($sql, $args), array(), $item['depth']);
       $data['node_links'] = array();
       menu_tree_collect_node_links($data['tree'], $data['node_links']);
-      // Cache the data.
-      cache_set($cid, $data, 'cache_menu');
+      // Cache the data, or just a reference to the already cached data.
+      $tree_cid = _book_subtree_cid($data);
+      if (!cache_get($tree_cid, 'cache_menu')) {
+        cache_set($tree_cid, $data, 'cache_menu');
+      }
+      cache_set($cid, $tree_cid, 'cache_menu');
     }
     // Check access for the current user to each item in the tree.
     menu_tree_check_access($data['tree'], $data['node_links']);
@@ -1081,3 +1089,10 @@ function book_menu_subtree_data($item) {
   return $tree[$cid];
 }
 
+
+/**
+ * Helper function - compute the real cache ID for book subtree data.
+ */
+function _book_subtree_cid($data) {
+  return 'subtree:'. md5(serialize($data));
+}
