Restrict empty-frame cache entries to their parent

Remove the parser's global $mTplExpandCache, and replace it with an
alternative that is separated by parent frame. This allows the integrity
of the empty-frame expansion cache to be maintained while also allowing
parent frame access.

A page with 3 copies of 
http://ja.wikipedia.org/wiki/%E4%B8%AD%E5%A4%AE%E7%B7%9A_(%E9%9F%93%E5%9B%BD) 
has the following statistics: Without this change, there are 4625 cache hits
on this page, and a sample of 3 parses took 16.6, 16.9, and 16.8 seconds.
With this change, there are 2588 cache hits, and a sample of 3 parses took
16.7, 16.7, and 17.0 seconds.

Change-Id: I621e9075e0f136ac188a4d2f53418b7cc957408d
This commit is contained in:
Jackmcbarn 2014-05-28 20:54:55 -04:00 committed by GWicke
parent c888520e99
commit 2094e578b4
4 changed files with 71 additions and 8 deletions

View file

@ -167,7 +167,6 @@ class Parser {
var $mLinkID;
var $mIncludeSizes, $mPPNodeCount, $mGeneratedPPNodeCount, $mHighestExpansionDepth;
var $mDefaultSort;
var $mTplExpandCache; # empty-frame expansion cache
var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
var $mExpensiveFunctionCount; # number of expensive parser function calls
var $mShowToc, $mForceTocPosition;
@ -321,7 +320,7 @@ class Parser {
$this->mStripState = new StripState( $this->mUniqPrefix );
# Clear these on every parse, bug 4549
$this->mTplExpandCache = $this->mTplRedirCache = $this->mTplDomCache = array();
$this->mTplRedirCache = $this->mTplDomCache = array();
$this->mShowToc = true;
$this->mForceTocPosition = false;
@ -3562,12 +3561,7 @@ class Parser {
$text = $newFrame->expand( $text, PPFrame::RECOVER_ORIG );
} elseif ( $titleText !== false && $newFrame->isEmpty() ) {
# Expansion is eligible for the empty-frame cache
if ( isset( $this->mTplExpandCache[$titleText] ) ) {
$text = $this->mTplExpandCache[$titleText];
} else {
$text = $newFrame->expand( $text );
$this->mTplExpandCache[$titleText] = $text;
}
$text = $newFrame->cachedExpand( $titleText, $text );
} else {
# Uncached expansion
$text = $newFrame->expand( $text );

View file

@ -94,6 +94,11 @@ interface PPFrame {
*/
function newChild( $args = false, $title = false, $indexOffset = 0 );
/**
* Expand a document tree node, caching the result on its parent with the given key
*/
function cachedExpand( $key, $root, $flags = 0 );
/**
* Expand a document tree node
*/

View file

@ -983,6 +983,11 @@ class PPFrame_DOM implements PPFrame {
*/
var $depth;
/**
* @var array
*/
protected $childExpansionCache;
/**
* Construct a new preprocessor frame.
* @param Preprocessor $preprocessor The parent preprocessor
@ -994,6 +999,7 @@ class PPFrame_DOM implements PPFrame {
$this->titleCache = array( $this->title ? $this->title->getPrefixedDBkey() : false );
$this->loopCheckHash = array();
$this->depth = 0;
$this->childExpansionCache = array();
}
/**
@ -1043,6 +1049,18 @@ class PPFrame_DOM implements PPFrame {
return new PPTemplateFrame_DOM( $this->preprocessor, $this, $numberedArgs, $namedArgs, $title );
}
/**
* @throws MWException
* @param string|int $key
* @param string|PPNode_DOM|DOMDocument $root
* @param int $flags
* @return string
*/
function cachedExpand( $key, $root, $flags = 0 ) {
// we don't have a parent, so we don't have a cache
return $this->expand( $root, $flags );
}
/**
* @throws MWException
* @param string|PPNode_DOM|DOMDocument $root
@ -1526,6 +1544,20 @@ class PPTemplateFrame_DOM extends PPFrame_DOM {
return $s;
}
/**
* @throws MWException
* @param string|int $key
* @param string|PPNode_DOM|DOMDocument $root
* @param int $flags
* @return string
*/
function cachedExpand( $key, $root, $flags = 0 ) {
if ( !isset( $this->parent->childExpansionCache[$key] ) ) {
$this->parent->childExpansionCache[$key] = $this->expand( $root, $flags );
}
return $this->parent->childExpansionCache[$key];
}
/**
* Returns true if there are no arguments in this frame
*

View file

@ -919,6 +919,11 @@ class PPFrame_Hash implements PPFrame {
*/
var $depth;
/**
* @var array
*/
protected $childExpansionCache;
/**
* Construct a new preprocessor frame.
* @param Preprocessor $preprocessor The parent preprocessor
@ -930,6 +935,7 @@ class PPFrame_Hash implements PPFrame {
$this->titleCache = array( $this->title ? $this->title->getPrefixedDBkey() : false );
$this->loopCheckHash = array();
$this->depth = 0;
$this->childExpansionCache = array();
}
/**
@ -972,6 +978,18 @@ class PPFrame_Hash implements PPFrame {
return new PPTemplateFrame_Hash( $this->preprocessor, $this, $numberedArgs, $namedArgs, $title );
}
/**
* @throws MWException
* @param string|int $key
* @param string|PPNode_Hash|DOMDocument $root
* @param int $flags
* @return string
*/
function cachedExpand( $key, $root, $flags = 0 ) {
// we don't have a parent, so we don't have a cache
return $this->expand( $root, $flags );
}
/**
* @throws MWException
* @param string|PPNode$root
@ -1426,6 +1444,20 @@ class PPTemplateFrame_Hash extends PPFrame_Hash {
return $s;
}
/**
* @throws MWException
* @param string|int $key
* @param string|PPNode_Hash|DOMDocument $root
* @param int $flags
* @return string
*/
function cachedExpand( $key, $root, $flags = 0 ) {
if ( !isset( $this->parent->childExpansionCache[$key] ) ) {
$this->parent->childExpansionCache[$key] = $this->expand( $root, $flags );
}
return $this->parent->childExpansionCache[$key];
}
/**
* Returns true if there are no arguments in this frame
*