#625014 by dalin: Batch db operation for cache expiration.
authorMike Carper
Fri, 6 Nov 2009 08:52:58 +0000 (08:52 +0000)
committerMike Carper
Fri, 6 Nov 2009 08:52:58 +0000 (08:52 +0000)
boost.module

index 9a0cf4e..2a08f39 100644 (file)
@@ -1234,11 +1234,6 @@ function _boost_ob_handler() {
       }
       elseif ($status == 404 || $status == 403) {
         $filename = boost_file_path($GLOBALS['_boost_path'], TRUE, BOOST_JSON_EXTENSION);
-        if ($filename) {
-          $hash = md5($filename);
-          boost_cache_kill($filename, $hash, TRUE);
-          boost_remove_db($filename, $hash);
-        }
       }
     }
     elseif (stristr($types, 'application/rss') || stristr($types, 'text/xml') || stristr($types, 'application/rss+xml')) {
@@ -1250,11 +1245,6 @@ function _boost_ob_handler() {
       }
       elseif ($status == 404 || $status == 403) {
         $filename = boost_file_path($GLOBALS['_boost_path'], TRUE, BOOST_XML_EXTENSION);
-        if ($filename) {
-          $hash = md5($filename);
-          boost_cache_kill($filename, $hash, TRUE);
-          boost_remove_db($filename, $hash);
-        }
       }
     }
     elseif (stristr($types, 'text/html')) {
@@ -1268,13 +1258,13 @@ function _boost_ob_handler() {
       elseif ($status == 404 || $status == 403) {
         // Kill cache entry if it exists
         $filename = boost_file_path($GLOBALS['_boost_path'], TRUE, BOOST_FILE_EXTENSION);
-        if ($filename) {
-          $hash = md5($filename);
-          boost_cache_kill($filename, $hash, TRUE);
-          boost_remove_db($filename, $hash);
-        }
       }
     }
+    if ($filename) {
+      $files = array(array('filename' => $filename));
+      boost_cache_kill($files, TRUE);
+      boost_remove_db($files);
+    }
   }
 }
 
@@ -1626,7 +1616,7 @@ function boost_cache_expire_by_db($paths) {
  *   If true get all chached files that start with this path.
  */
 function boost_cache_expire_by_filename($paths, $wildcard = TRUE) {
-  $filenames = array();
+  $filenames = $files = array();
   if (empty($paths)) {
     return FALSE;
   }
@@ -1651,13 +1641,13 @@ function boost_cache_expire_by_filename($paths, $wildcard = TRUE) {
     $filenames = array_filter(array_merge($filenames, $html, $xml, $json));
   }
 
-  $counter = 0;
   // Flush expired files
   if ($filenames) {
     $filenames = array_unique($filenames);
     foreach ($filenames as $filename) {
-      $counter += boost_cache_kill($filename);
+      $files[] = array('filename' => $filename);
     }
+    $counter = boost_cache_kill($files);
     if (BOOST_VERBOSE >= 9) {
       watchdog('boost', 'Debug: boost_cache_expire_by_filename() <br />Following files where flushed: <br />!list', array('!list' => implode('<br />', $filenames)));
     }
@@ -1669,7 +1659,7 @@ function boost_cache_expire_by_filename($paths, $wildcard = TRUE) {
 }
 
 /**
- * Expires the static file cache for the given paths
+ * Expires the static file cache for the given router items.
  *
  * @param $router_items
  *   Array of $router_item array "objects"
@@ -1688,7 +1678,7 @@ function boost_cache_expire_router($router_items, $force_flush = FALSE, $remove_
     return FALSE;
   }
   $count = 0;
-  $list = array();
+  $files = $list = array();
 
   foreach ($router_items as $dblookup) {
     if (isset($dblookup['base_dir'])) {
@@ -1735,16 +1725,18 @@ function boost_cache_expire_router($router_items, $force_flush = FALSE, $remove_
     }
 
     while ($info = db_fetch_array($result)) {
-      // Flush matching files
-      $counter = boost_cache_kill($info['filename'], $info['hash'], $force_flush, $info['base_dir']);
-      $count += $counter;
-      if ($remove_from_db) {
-        boost_remove_db($info['hash']);
-      }
-      if ($counter >= 1) {
+      $files[] = $info;
+      if (BOOST_VERBOSE >= 9) {
         $list[] = $info['filename'];
       }
     }
+
+  }
+  if (count($files)) {
+    $count = boost_cache_kill($files, $force_flush);
+    if ($remove_from_db) {
+      boost_remove_db($files);
+    }
   }
   if (BOOST_VERBOSE >= 9) {
     watchdog('boost', 'Debug: boost_cache_expire_router() <br />Following files where flushed: <br />!list', array('!list' => implode('<br />', $list)));
@@ -1753,41 +1745,65 @@ function boost_cache_expire_router($router_items, $force_flush = FALSE, $remove_
 }
 
 /**
- * Deletes cached page from file system
+ * Deletes cached page from file system.
  *
- * @param $filename
- *   Name of cached file.
- * @param $hash
- *   Primary key in database; filename hash
- * @param $force_flush
- *   Override BOOST_EXPIRE_NO_FLUSH setting
- * @param $base_dir
- *   Base directory of site
+ * @param array $files
+ *  An array of files. Each file is a secondary array must have a key for 'filename'
+ *  Optional keys for 'hash' and 'base_dir' that will be recalculated if necessary.
+ *  The hash is the primary key in the databse. If omitted it will be recalculated from the filename.
+ * @param boolean $force_flush = FALSE
+ *  Override BOOST_EXPIRE_NO_FLUSH setting.
+ * @param string $base_dir = ''
+ *  Base directory of the site.
  */
-function boost_cache_kill($filename, $hash = '', $force_flush = FALSE, $base_dir = '') {
+function boost_cache_kill($files, $force_flush = FALSE) {
+  $hashes = array();
+  $count = 0;
+
+  if (!$files) {
+    return FALSE;
+  }
+
+  // Pull out the first file to determine our course of action.
+  $first_file = current($files);
+
   // If not ignoring file removal
   // AND site is multisite and cache path matches filename
   //  OR full base url matches filename
-  $count = 0;
-  if (variable_get('boost_ignore_flush', 0) < 3 && ((BOOST_FLUSH_ALL_MULTISITE && strstr($filename, BOOST_ROOT_CACHE_DIR)) || strstr($filename, BOOST_FILE_PATH))) {
-    if ($hash == '') {
-      $hash = md5($filename);
-    }
-    if ($hash != '') {
-      if (!$force_flush && BOOST_EXPIRE_NO_FLUSH) {
-        db_query("UPDATE {boost_cache} SET expire = 434966400 WHERE hash = '%s'", $hash);
-        if (db_affected_rows()) {
-          $count++;
-        }
+  if (variable_get('boost_ignore_flush', 0) < 3 && (
+          (BOOST_FLUSH_ALL_MULTISITE && strstr($first_file['filename'], BOOST_ROOT_CACHE_DIR))
+          || strstr($first_file['filename'], BOOST_FILE_PATH)
+        )
+      ) {
+    // Calc md5 hash and set base dir
+    foreach ($files as $file) {
+      if (empty($file['hash'])) {
+        $file['hash'] = md5($file['filename']);
+      }
+      if (empty($file['base_dir'])) {
+        $file['base_dir'] = BOOST_FILE_PATH;
+      }
+      $hashes[] = "'" .$file['hash'] ."'";
+    }
+    // Expire entries from Database
+    if (count($hashes)) {
+      $hashes = implode(', ', $hashes);
+      if ($force_flush || !BOOST_EXPIRE_NO_FLUSH) {
+        db_query("UPDATE {boost_cache} SET expire = 0 WHERE hash IN ($hashes)");
       }
       else {
-        db_query("UPDATE {boost_cache} SET expire = 0 WHERE hash = '%s'", $hash);
-        if (file_exists($filename)) {
-          @unlink($filename);
+        db_query("UPDATE {boost_cache} SET expire = 434966400 WHERE hash IN ($hashes)");
+        $count = db_affected_rows();
+      }
+    }
+    // Kill Files from filesystem
+    foreach ($files as $file) {
+      if ($force_flush || !BOOST_EXPIRE_NO_FLUSH) {
+        if (file_exists($file['filename'])) {
+          @unlink($file['filename']);
           $count++;
         }
-        $base_dir = $base_dir == '' ? BOOST_FILE_PATH : $base_dir;
-        $gz_filename = str_replace($base_dir, BOOST_GZIP_FILE_PATH, $filename) . BOOST_GZIP_EXTENSION;
+        $gz_filename = str_replace($file['base_dir'], BOOST_GZIP_FILE_PATH, $file['filename']) . BOOST_GZIP_EXTENSION;
         if (file_exists($gz_filename)) {
           @unlink($gz_filename);
         }
@@ -1821,8 +1837,7 @@ function boost_cache_expire_all() {
  * TODO del empty dirs if enabled
  */
 function boost_cache_expire_all_db() {
-  $list = array();
-  $count = 0;
+  $list = $files = array();
   if (BOOST_FLUSH_ALL_MULTISITE) {
     $result = db_query("SELECT filename, hash, base_dir FROM {boost_cache} WHERE expire BETWEEN 1 AND %d", BOOST_TIME);
   }
@@ -1830,8 +1845,13 @@ function boost_cache_expire_all_db() {
     $result = db_query("SELECT filename, hash, base_dir FROM {boost_cache} WHERE base_dir = '%s' AND expire BETWEEN 1 AND %d", BOOST_FILE_PATH, BOOST_TIME);
   }
   while ($boost = db_fetch_array($result)) {
-    $count += boost_cache_kill($boost['filename'], $boost['hash'], TRUE, $boost['base_dir']);
-    $list[] = $boost['filename'];
+    $files[] = $boost;
+    if (BOOST_VERBOSE >= 9) {
+      $list[] = $boost['filename'];
+    }
+  }
+  if (count($files)) {
+    $count = boost_cache_kill($files, TRUE);
   }
   if (BOOST_FLUSH_DIR) {
     // TO-DO: del empty dirs.
@@ -1841,7 +1861,7 @@ function boost_cache_expire_all_db() {
     watchdog('boost', 'Debug: boost_cache_expire_all_db() <br />Following files where flushed: <br />!list', array('!list' => implode('<br />', $list)));
   }
   if (BOOST_VERBOSE >= 7) {
-    watchdog('boost', 'Debug: boost_cache_expire_all_db() <br />!num files where flushed', array('!num' => $list));
+    watchdog('boost', 'Debug: boost_cache_expire_all_db() <br />!num files where flushed', array('!num' => $count));
   }
   return TRUE;
 }
@@ -2164,11 +2184,19 @@ function boost_put_db($filename, $expire, $lifetime, $push, $router_item, $timer
 /**
  * Removes info from database. Use on 404 or 403.
  *
- * @param $hash
- *   md5 of filename
+ * @param array $files
+ *  An array of files. Each file is a secondary array with keys for 'filename' and 'hash'.
+ *  The hash is the primary key in the databse. If omitted it will be recalculated from the filename.
  */
-function boost_remove_db($hash) {
-  db_query("DELETE FROM {boost_cache} WHERE hash = '%s'", $hash);
+function boost_remove_db($files) {
+  $hashes = array();
+  foreach ($files as $file) {
+    if (empty($file['hash'])) {
+      $file['hash'] = md5($file['filename']);
+    }
+    $hashes[] = "'" .$file['hash'] ."'";
+  }
+  db_query("DELETE FROM {boost_cache} WHERE hash IN (%s)", implode(', ', $hashes));
 }
 
 /**