WCF icon indicating copy to clipboard operation
WCF copied to clipboard

Rework DiskCacheSource

Open TimWolla opened this issue 3 years ago • 1 comments
trafficstars

  • [ ] Remove use of DirectoryUtil.
  • [ ] Make the cache files return; the serialized data, instead of needing to manually parse them (in preliminary tests this brings a small, but measurable performance improvement).

PoC diff:

diff --git i/wcfsetup/install/files/lib/system/cache/source/DiskCacheSource.class.php w/wcfsetup/install/files/lib/system/cache/source/DiskCacheSource.class.php
index 7a3e9b02dc..56dd01c0bd 100644
--- i/wcfsetup/install/files/lib/system/cache/source/DiskCacheSource.class.php
+++ w/wcfsetup/install/files/lib/system/cache/source/DiskCacheSource.class.php
@@ -9,6 +9,8 @@
 use wcf\util\DirectoryUtil;
 use wcf\util\FileUtil;
 
+define('CACHE_VERSION', 'v1');
+
 /**
  * DiskCacheSource is an implementation of CacheSource that stores the cache as simple files in the file system.
  *
@@ -70,11 +72,20 @@ public function get($cacheName, $maxLifetime)
      */
     public function set($cacheName, $value, $maxLifetime)
     {
+        if (CACHE_VERSION === 'v1') {
         $writer = new AtomicWriter($this->getFilename($cacheName));
         $writer->write("<?php exit; /* cache: " . $cacheName . " (generated at " . \gmdate('r') . ") DO NOT EDIT THIS FILE */ ?>\n");
         $writer->write(\serialize($value));
         $writer->flush();
         $writer->close();
+        } else {
+        $writer = new AtomicWriter($this->getFilename($cacheName));
+        $writer->write("<?php /* cache: " . $cacheName . " (generated at " . \gmdate('r') . ") DO NOT EDIT THIS FILE */ return <<<'EOT'\n");
+        $writer->write(\serialize($value));
+        $writer->write("\nEOT;\n");
+        $writer->flush();
+        $writer->close();
+        }
 
         // unset current DirectoryUtil object to make sure new cache file
         // can be deleted in the same request
@@ -91,7 +102,7 @@ public function set($cacheName, $value, $maxLifetime)
      */
     protected function getFilename($cacheName)
     {
-        return WCF_DIR . 'cache/cache.' . $cacheName . '.php';
+        return WCF_DIR . 'cache/cache.' . CACHE_VERSION . $cacheName . '.php';
     }
 
     /**
@@ -156,9 +167,8 @@ protected function needRebuild($filename, $maxLifetime)
      */
     protected function readCache($cacheName, $filename)
     {
-        // get file contents
+        if (\CACHE_VERSION === 'v1') {
         $contents = \file_get_contents($filename);
-
         // find first newline
         $position = \strpos($contents, "\n");
         if ($position === false) {
@@ -167,6 +177,16 @@ protected function readCache($cacheName, $filename)
 
         // cut contents
         $contents = \substr($contents, $position + 1);
+        // unserialize
+        $value = @\unserialize($contents);
+        if ($value === false) {
+            throw new SystemException("Unable to load cache resource '" . $cacheName . "'");
+        }
+
+        return $value;
+        } else {
+        // get file contents
+        $contents = include($filename);
 
         // unserialize
         $value = @\unserialize($contents);
@@ -175,6 +195,7 @@ protected function readCache($cacheName, $filename)
         }
 
         return $value;
+        }
     }
 
     /**

TimWolla avatar Mar 01 '22 13:03 TimWolla

The same optimization can likely be applied to the TemplateEngine's metadata files.

TimWolla avatar Mar 02 '22 10:03 TimWolla