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:
parent
c888520e99
commit
2094e578b4
4 changed files with 71 additions and 8 deletions
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue