25require_once __DIR__ .
'/../Maintenance.php';
40 private $templateTimestamp =
null;
42 private $clearLinkCache =
false;
50 private $idCache = [];
53 parent::__construct();
55 $this->
addArg(
'title',
'The name of the page to parse' );
56 $this->
addOption(
'warmup',
'Repeat the parse operation this number of times to warm the cache',
58 $this->
addOption(
'loops',
'Number of times to repeat parse operation post-warmup',
61 'Use the version of the page which was current at the given time',
64 'Use templates which were current at the given time (except that moves and ' .
65 'deletes are not handled properly)',
67 $this->
addOption(
'reset-linkcache',
'Reset the LinkCache after every parse.',
74 Hooks::register(
'BeforeParserFetchTemplateRevisionRecord', [ $this,
'onFetchTemplate' ] );
77 $this->clearLinkCache = $this->
hasOption(
'reset-linkcache' );
79 $this->linkCache = MediaWikiServices::getInstance()->getLinkCache();
86 $revLookup = MediaWikiServices::getInstance()->getRevisionLookup();
89 $id = $this->getRevIdForTime(
$title, $pageTimestamp );
91 $this->
fatalError(
"The page did not exist at that time" );
94 $revision = $revLookup->getRevisionById( (
int)$id );
96 $revision = $revLookup->getRevisionByTitle(
$title );
100 $this->
fatalError(
"Unable to load revision, incorrect title?" );
103 $warmup = $this->
getOption(
'warmup', 1 );
104 for ( $i = 0; $i < $warmup; $i++ ) {
105 $this->runParser( $revision );
110 $this->
fatalError(
'Invalid number of loops specified' );
112 $startUsage = getrusage();
113 $startTime = microtime(
true );
114 for ( $i = 0; $i < $loops; $i++ ) {
115 $this->runParser( $revision );
117 $endUsage = getrusage();
118 $endTime = microtime(
true );
120 printf(
"CPU time = %.3f s, wall clock time = %.3f s\n",
122 ( $endUsage[
'ru_utime.tv_sec'] + $endUsage[
'ru_utime.tv_usec'] * 1e-6
123 - $startUsage[
'ru_utime.tv_sec'] - $startUsage[
'ru_utime.tv_usec'] * 1e-6 ) / $loops,
125 ( $endTime - $startTime ) / $loops
136 private function getRevIdForTime(
Title $title, $timestamp ) {
139 $id =
$dbr->selectField(
140 [
'revision',
'page' ],
143 'page_namespace' =>
$title->getNamespace(),
144 'page_title' =>
$title->getDBkey(),
145 'rev_timestamp <= ' .
$dbr->addQuotes( $timestamp )
148 [
'ORDER BY' =>
'rev_timestamp DESC' ],
149 [
'revision' => [
'JOIN',
'rev_page=page_id' ] ]
162 $contentRenderer = MediaWikiServices::getInstance()->getContentRenderer();
165 if ( $this->clearLinkCache ) {
166 $this->linkCache->clear();
180 private function onFetchTemplate(
186 $title =
Title::castFromLinkTarget( $titleTarget );
189 if ( !isset( $this->idCache[$pdbk] ) ) {
190 $proposedId = $this->getRevIdForTime(
$title, $this->templateTimestamp );
191 $this->idCache[$pdbk] = $proposedId;
193 if ( $this->idCache[$pdbk] !==
false ) {
194 $revLookup = MediaWikiServices::getInstance()->getRevisionLookup();
195 $revRecord = $revLookup->getRevisionById( $this->idCache[$pdbk] );
203require_once RUN_MAINTENANCE_IF_MAIN;
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Maintenance script to benchmark how long it takes to parse a given title at an optionally specified t...
__construct()
Default constructor.
execute()
Do the actual work.
Cache for article titles (prefixed DB keys) and ids linked from one source.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
addArg( $arg, $description, $required=true)
Add some args that are needed.
hasOption( $name)
Checks to see if a particular option was set.
getArg( $argId=0, $default=null)
Get an argument.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
Represents a title within MediaWiki.
getPrefixedDBkey()
Get the prefixed database key form.