Index: trunk/phase3/includes/parser/Preprocessor_Hash.php |
— | — | @@ -8,6 +8,8 @@ |
9 | 9 | */ |
10 | 10 | class Preprocessor_Hash implements Preprocessor { |
11 | 11 | var $parser; |
| 12 | + |
| 13 | + const CACHE_VERSION = 1; |
12 | 14 | |
13 | 15 | function __construct( $parser ) { |
14 | 16 | $this->parser = $parser; |
— | — | @@ -45,14 +47,30 @@ |
46 | 48 | */ |
47 | 49 | function preprocessToObj( $text, $flags = 0 ) { |
48 | 50 | wfProfileIn( __METHOD__ ); |
| 51 | + |
| 52 | + |
| 53 | + // Check cache. |
| 54 | + global $wgMemc, $wgPreprocessorCacheThreshold; |
49 | 55 | |
50 | | - global $wgMemc; |
51 | | - $cacheKey = wfMemckey( 'preprocessor-hash', md5( $text ), $flags ); |
52 | | - |
53 | | - if ( $obj = $wgMemc->get( $cacheKey ) ) { |
54 | | - wfDebugLog( "Preprocessor", "Got preprocessor_hash output from cache" ); |
55 | | - wfProfileOut( __METHOD__ ); |
56 | | - return $obj; |
| 56 | + $cacheable = strlen( $text ) > $wgPreprocessorCacheThreshold; |
| 57 | + if ( $cacheable ) { |
| 58 | + wfProfileIn( __METHOD__.'-cacheable' ); |
| 59 | + |
| 60 | + $cacheKey = wfMemcKey( 'preprocess-hash', md5($text), $flags ); |
| 61 | + $cacheValue = $wgMemc->get( $cacheKey ); |
| 62 | + if ( $cacheValue ) { |
| 63 | + $version = substr( $cacheValue, 0, 8 ); |
| 64 | + if ( intval( $version ) == self::CACHE_VERSION ) { |
| 65 | + $hash = unserialize( substr( $cacheValue, 8 ) ); |
| 66 | + // From the cache |
| 67 | + wfDebugLog( "Preprocessor", |
| 68 | + "Loaded preprocessor hash from memcached (key $cacheKey)" ); |
| 69 | + wfProfileOut( __METHOD__.'-cacheable' ); |
| 70 | + wfProfileOut( __METHOD__ ); |
| 71 | + return $hash; |
| 72 | + } |
| 73 | + } |
| 74 | + wfProfileIn( __METHOD__.'-cache-miss' ); |
57 | 75 | } |
58 | 76 | |
59 | 77 | $rules = array( |
— | — | @@ -626,10 +644,17 @@ |
627 | 645 | $rootNode = new PPNode_Hash_Tree( 'root' ); |
628 | 646 | $rootNode->firstChild = $stack->rootAccum->firstNode; |
629 | 647 | $rootNode->lastChild = $stack->rootAccum->lastNode; |
630 | | - wfProfileOut( __METHOD__ ); |
631 | 648 | |
632 | | - $wgMemc->set( $cacheKey, $rootNode, 86400 ); |
| 649 | + // Cache |
| 650 | + if ($cacheable) { |
| 651 | + $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . serialize( $rootNode );; |
| 652 | + $wgMemc->set( $cacheKey, $cacheValue, 86400 ); |
| 653 | + wfProfileOut( __METHOD__.'-cache-miss' ); |
| 654 | + wfProfileOut( __METHOD__.'-cacheable' ); |
| 655 | + wfDebugLog( "Preprocessor", "Saved preprocessor Hash to memcached (key $cacheKey)" ); |
| 656 | + } |
633 | 657 | |
| 658 | + wfProfileOut( __METHOD__ ); |
634 | 659 | return $rootNode; |
635 | 660 | } |
636 | 661 | } |
Index: trunk/phase3/includes/parser/Preprocessor_DOM.php |
— | — | @@ -6,6 +6,8 @@ |
7 | 7 | class Preprocessor_DOM implements Preprocessor { |
8 | 8 | var $parser, $memoryLimit; |
9 | 9 | |
| 10 | + const CACHE_VERSION = 1; |
| 11 | + |
10 | 12 | function __construct( $parser ) { |
11 | 13 | $this->parser = $parser; |
12 | 14 | $mem = ini_get( 'memory_limit' ); |
— | — | @@ -63,19 +65,37 @@ |
64 | 66 | */ |
65 | 67 | function preprocessToObj( $text, $flags = 0 ) { |
66 | 68 | wfProfileIn( __METHOD__ ); |
| 69 | + global $wgMemc, $wgPreprocessorCacheThreshold; |
67 | 70 | |
68 | | - global $wgMemc; |
69 | | - $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags ); |
70 | | - |
71 | | - if ( $xml = $wgMemc->get( $cacheKey ) ) { |
72 | | - // From the cache |
73 | | - wfDebugLog( "Preprocessor", "Loaded preprocessor XML from memcached (key $cacheKey)" ); |
74 | | - } else { |
75 | | - $xml = $this->preprocessToXml( $text, $flags ); |
76 | | - $wgMemc->set( $cacheKey, $xml, 86400 ); |
77 | | - wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" ); |
| 71 | + $xml = false; |
| 72 | + $cacheable = strlen( $text ) > $wgPreprocessorCacheThreshold; |
| 73 | + if ( $cacheable ) { |
| 74 | + wfProfileIn( __METHOD__.'-cacheable' ); |
| 75 | + |
| 76 | + $cacheKey = wfMemcKey( 'preprocess-xml', md5($text), $flags ); |
| 77 | + $cacheValue = $wgMemc->get( $cacheKey ); |
| 78 | + if ( $cacheValue ) { |
| 79 | + $version = substr( $cacheValue, 0, 8 ); |
| 80 | + if ( intval( $version ) == self::CACHE_VERSION ) { |
| 81 | + $xml = substr( $cacheValue, 8 ); |
| 82 | + // From the cache |
| 83 | + wfDebugLog( "Preprocessor", "Loaded preprocessor XML from memcached (key $cacheKey)" ); |
| 84 | + } |
| 85 | + } |
78 | 86 | } |
79 | | - |
| 87 | + if ( $xml === false ) { |
| 88 | + if ( $cacheable ) { |
| 89 | + wfProfileIn( __METHOD__.'-cache-miss' ); |
| 90 | + $xml = $this->preprocessToXml( $text, $flags ); |
| 91 | + $cacheValue = sprintf( "%08d", self::CACHE_VERSION ) . $xml; |
| 92 | + $wgMemc->set( $cacheKey, $cacheValue, 86400 ); |
| 93 | + wfProfileOut( __METHOD__.'-cache-miss' ); |
| 94 | + wfDebugLog( "Preprocessor", "Saved preprocessor XML to memcached (key $cacheKey)" ); |
| 95 | + } else { |
| 96 | + $xml = $this->preprocessToXml( $text, $flags ); |
| 97 | + } |
| 98 | + |
| 99 | + } |
80 | 100 | wfProfileIn( __METHOD__.'-loadXML' ); |
81 | 101 | $dom = new DOMDocument; |
82 | 102 | wfSuppressWarnings(); |
— | — | @@ -91,6 +111,9 @@ |
92 | 112 | } |
93 | 113 | $obj = new PPNode_DOM( $dom->documentElement ); |
94 | 114 | wfProfileOut( __METHOD__.'-loadXML' ); |
| 115 | + if ( $cacheable ) { |
| 116 | + wfProfileOut( __METHOD__.'-cacheable' ); |
| 117 | + } |
95 | 118 | wfProfileOut( __METHOD__ ); |
96 | 119 | return $obj; |
97 | 120 | } |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -3708,3 +3708,8 @@ |
3709 | 3709 | * false = use Go button & Advanced search link |
3710 | 3710 | */ |
3711 | 3711 | $wgUseTwoButtonsSearchForm = true; |
| 3712 | + |
| 3713 | +/** |
| 3714 | + * Preprocessor caching threshold |
| 3715 | + */ |
| 3716 | +$wgPreprocessorCacheThreshold = 1000; |
\ No newline at end of file |