Apply changes made live on Wikimedia cluster related to preprocessor caching to subve...
authorAndrew Garrett <werdna@users.mediawiki.org>
Mon, 9 Feb 2009 23:18:37 +0000 (23:18 +0000)
committerAndrew Garrett <werdna@users.mediawiki.org>
Mon, 9 Feb 2009 23:18:37 +0000 (23:18 +0000)
Changes from the original patch (r46936):
* Add versioning to the cache, so the cache can be purged.
* Only cache preprocessor output for input of over a certain amount (default of 1000 bytes).

includes/DefaultSettings.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php

index 949fd81..8171586 100644 (file)
@@ -3708,3 +3708,8 @@ $wgEnforceHtmlIds = true;
  * false = use Go button & Advanced search link
  */
 $wgUseTwoButtonsSearchForm = true;
+
+/**
+ * Preprocessor caching threshold
+ */
+$wgPreprocessorCacheThreshold = 1000;
\ No newline at end of file
index 66b5e1d..bd33c10 100644 (file)
@@ -6,6 +6,8 @@
 class Preprocessor_DOM implements Preprocessor {
        var $parser, $memoryLimit;
 
+       const CACHE_VERSION = 1;
+
        function __construct( $parser ) {
                $this->parser = $parser;
                $mem = ini_get( 'memory_limit' );
@@ -63,19 +65,37 @@ class Preprocessor_DOM implements Preprocessor {
         */
        function preprocessToObj( $text, $flags = 0 ) {
                wfProfileIn( __METHOD__ );
+               global $wgMemc, $wgPreprocessorCacheThreshold;
                
-               global $wgMemc;
-               $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags );
-               
-               if ( $xml = $wgMemc->get( $cacheKey ) ) {
-                       // From the cache
-                       wfDebugLog( "Preprocessor", "Loaded preprocessor XML from memcached (key $cacheKey)" );
-               } else {
-                       $xml = $this->preprocessToXml( $text, $flags );
-                       $wgMemc->set( $cacheKey, $xml, 86400 );
-                       wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" );
+               $xml = false;
+               $cacheable = strlen( $text ) > $wgPreprocessorCacheThreshold;
+               if ( $cacheable ) {
+                       wfProfileIn( __METHOD__.'-cacheable' );
+
+                       $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags );
+                       $cacheValue = $wgMemc->get( $cacheKey );
+                       if ( $cacheValue ) {
+                               $version = substr( $cacheValue, 0, 8 );
+                               if ( intval( $version ) == self::CACHE_VERSION ) {
+                                       $xml = substr( $cacheValue, 8 );
+                                       // From the cache
+                                       wfDebugLog( "Preprocessor", "Loaded preprocessor XML from memcached (key $cacheKey)" );
+                               }
+                       }
+               }
+               if ( $xml === false ) {
+                       if ( $cacheable ) {
+                               wfProfileIn( __METHOD__.'-cache-miss' );
+                               $xml = $this->preprocessToXml( $text, $flags );
+                               $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . $xml;
+                               $wgMemc->set( $cacheKey, $cacheValue, 86400 );
+                               wfProfileOut( __METHOD__.'-cache-miss' );
+                               wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" );
+                       } else {
+                               $xml = $this->preprocessToXml( $text, $flags );
+                       }
+
                }
-               
                wfProfileIn( __METHOD__.'-loadXML' );
                $dom = new DOMDocument;
                wfSuppressWarnings();
@@ -91,6 +111,9 @@ class Preprocessor_DOM implements Preprocessor {
                }
                $obj = new PPNode_DOM( $dom->documentElement );
                wfProfileOut( __METHOD__.'-loadXML' );
+               if ( $cacheable ) {
+                       wfProfileOut( __METHOD__.'-cacheable' );
+               }
                wfProfileOut( __METHOD__ );
                return $obj;
        }
index 0bebdb7..f46ee40 100644 (file)
@@ -8,6 +8,8 @@
  */
 class Preprocessor_Hash implements Preprocessor {
        var $parser;
+       
+       const CACHE_VERSION = 1;
 
        function __construct( $parser ) {
                $this->parser = $parser;
@@ -45,14 +47,30 @@ class Preprocessor_Hash implements Preprocessor {
         */
        function preprocessToObj( $text, $flags = 0 ) {
                wfProfileIn( __METHOD__ );
+       
+       
+               // Check cache.
+               global $wgMemc, $wgPreprocessorCacheThreshold;
                
-               global $wgMemc;
-               $cacheKey = wfMemckey( 'preprocessor-hash', md5( $text ), $flags );
-               
-               if ( $obj = $wgMemc->get( $cacheKey ) ) {
-                       wfDebugLog( "Preprocessor", "Got preprocessor_hash output from cache" );
-                       wfProfileOut( __METHOD__ );
-                       return $obj;
+               $cacheable = strlen( $text ) > $wgPreprocessorCacheThreshold;
+               if ( $cacheable ) {
+                       wfProfileIn( __METHOD__.'-cacheable' );
+
+                       $cacheKey = wfMemcKey( 'preprocess-hash', md5($text), $flags );
+                       $cacheValue = $wgMemc->get( $cacheKey );
+                       if ( $cacheValue ) {
+                               $version = substr( $cacheValue, 0, 8 );
+                               if ( intval( $version ) == self::CACHE_VERSION ) {
+                                       $hash = unserialize( substr( $cacheValue, 8 ) );
+                                       // From the cache
+                                       wfDebugLog( "Preprocessor",
+                                               "Loaded preprocessor hash from memcached (key $cacheKey)" );
+                                       wfProfileOut( __METHOD__.'-cacheable' );
+                                       wfProfileOut( __METHOD__ );
+                                       return $hash;
+                               }
+                       }
+                       wfProfileIn( __METHOD__.'-cache-miss' );
                }
 
                $rules = array(
@@ -626,10 +644,17 @@ class Preprocessor_Hash implements Preprocessor {
                $rootNode = new PPNode_Hash_Tree( 'root' );
                $rootNode->firstChild = $stack->rootAccum->firstNode;
                $rootNode->lastChild = $stack->rootAccum->lastNode;
-               wfProfileOut( __METHOD__ );
                
-               $wgMemc->set( $cacheKey, $rootNode, 86400 );
+               // Cache
+               if ($cacheable) {
+                       $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . serialize( $rootNode );;
+                       $wgMemc->set( $cacheKey, $cacheValue, 86400 );
+                       wfProfileOut( __METHOD__.'-cache-miss' );
+                       wfProfileOut( __METHOD__.'-cacheable' );
+                       wfDebugLog( "Preprocessor", "Saved preprocessor Hash to memcached (key $cacheKey)" );
+               }
                
+               wfProfileOut( __METHOD__ );
                return $rootNode;
        }
 }