From 3774956fe7e48f61e504912361d46e2a1e853000 Mon Sep 17 00:00:00 2001
From: Brandon Bergren <bdragon@rtk0.net>
Date: Wed, 2 May 2012 16:02:18 -0500
Subject: [PATCH] Fix #1421844.

---
 includes/cache.inc |  117 +++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 84 insertions(+), 33 deletions(-)

diff --git a/includes/cache.inc b/includes/cache.inc
index 11c77f7..c641d09 100644
--- a/includes/cache.inc
+++ b/includes/cache.inc
@@ -15,46 +15,97 @@
 function _views_fetch_data($table = NULL, $move = TRUE, $reset = FALSE) {
   $cache = &drupal_static(__FUNCTION__ . '_cache');
   $recursion_protection = &drupal_static(__FUNCTION__ . '_recursion_protected');
-  if (!isset($cache) || $reset) {
-    $start = microtime(TRUE);
-    // NOTE: This happens whether we retrieve them from cache or otherwise.
-
-    $data = views_cache_get('views_data', TRUE);
-    if (!empty($data->data)) {
-      $cache = $data->data;
+  if ($table) {
+    if (!isset($cache[$table]) || $reset) {
+      $cid = 'views_data:' . $table;
+      $data = views_cache_get($cid, TRUE);
+      if (!empty($data->data)) {
+        $cache[$table] = $data->data;
+      }
+      else {
+        // No cache entry, rebuild.
+        views_include_handlers();
+        $cache = module_invoke_all('views_data');
+        foreach (module_implements('views_data_alter') as $module) {
+          $function = $module . '_views_data_alter';
+          $function($cache);
+        }
+        _views_data_process_entity_types($cache);
+
+        // Save data in seperate cache entries.
+        foreach ($cache as $key => $data) {
+          $cid = 'views_data:' . $key;
+          views_cache_set($cid, $data, TRUE);
+        }
+        // Also keep a record with all data.
+        views_cache_set('views_data', $cache, TRUE);
+      }
     }
-
-    if (empty($cache)) {
-      views_include_handlers();
-      $cache = module_invoke_all('views_data');
-      foreach (module_implements('views_data_alter') as $module) {
-        $function = $module . '_views_data_alter';
-        $function($cache);
+    if (isset($cache[$table])) {
+      if (isset($cache[$table]['moved to']) && $move) {
+        $moved_table = $cache[$table]['moved to'];
+        if (!empty($recursion_protection[$table])) {
+          // recursion detected!
+          return NULL;
+        }
+        $recursion_protection[$table] = TRUE;
+        $data = _views_fetch_data($moved_table);
+        $recursion_protection = array();
+        return $data;
+      }
+      else {
+        return $cache[$table];
       }
-      _views_data_process_entity_types($cache);
-
-      views_cache_set('views_data', $cache, TRUE);
     }
-  }
 
-  if (!$table) {
-    return $cache;
   }
-  if (isset($cache[$table])) {
-    // Support old views_data entries conversion.
-    if (isset($cache[$table]['moved to']) && $move) {
-      $moved_table = $cache[$table]['moved to'];
-      if (!empty($recursion_protection[$table])) {
-        // recursion detected!
-        return NULL;
+  else {
+    if (!isset($cache) || $reset) {
+      // NOTE: This happens whether we retrieve them from cache or otherwise.
+
+      $data = views_cache_get('views_data', TRUE);
+      if (!empty($data->data)) {
+        $cache = $data->data;
+      }
+
+      if (empty($cache)) {
+        views_include_handlers();
+        $cache = module_invoke_all('views_data');
+        foreach (module_implements('views_data_alter') as $module) {
+          $function = $module . '_views_data_alter';
+          $function($cache);
+        }
+        _views_data_process_entity_types($cache);
+
+        // Save data in seperate cache entries.
+        foreach ($cache as $key => $data) {
+          $cid = 'views_data:' . $key;
+          views_cache_set($cid, $data, TRUE);
+        }
+        // Also keep a record with all data.
+        views_cache_set('views_data', $cache, TRUE);
       }
-      $recursion_protection[$table] = TRUE;
-      $data = _views_fetch_data($moved_table);
-      $recursion_protection = array();
-      return $data;
     }
-    else {
-      return $cache[$table];
+
+    if (!$table) {
+      return $cache;
+    }
+    if (isset($cache[$table])) {
+      // Support old views_data entries conversion.
+      if (isset($cache[$table]['moved to']) && $move) {
+        $moved_table = $cache[$table]['moved to'];
+        if (!empty($recursion_protection[$table])) {
+          // recursion detected!
+          return NULL;
+        }
+        $recursion_protection[$table] = TRUE;
+        $data = _views_fetch_data($moved_table);
+        $recursion_protection = array();
+        return $data;
+      }
+      else {
+        return $cache[$table];
+      }
     }
   }
 
-- 
1.7.10

