Code, style, and doc fixes for benchmarkParse.php
authorTyler Anthony Romeo <tylerromeo@gmail.com>
Wed, 5 Feb 2014 02:35:48 +0000 (21:35 -0500)
committerTyler Anthony Romeo <tylerromeo@gmail.com>
Wed, 5 Feb 2014 03:00:37 +0000 (22:00 -0500)
Fixes database query semantics, various documentation
issues, and unused variables.

Change-Id: Ic2c2d4d3912a9cd6703f7690f9d08df8ea08cd5c
Follows-up: I3bf3366a5ff58942 (dfd481e113f2cf5aaa)

maintenance/benchmarks/benchmarkParse.php

index 79af911..cec2beb 100644 (file)
@@ -1,11 +1,40 @@
 <?php
+/**
+ * Benchmark script for parse operations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Tim Starling <tstarling@wikimedia.org>
+ * @ingroup Benchmark
+ */
 
 require __DIR__ . '/../Maintenance.php';
 
+/**
+ * Maintenance script to benchmark how long it takes to parse a given title at an optionally
+ * specified timestamp
+ *
+ * @since 1.23
+ */
 class BenchmarkParse extends Maintenance {
        /** @var string MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS) */
-       private $templateTimestamp;
+       private $templateTimestamp = null;
 
+       /** @var array Cache that maps a Title DB key to revision ID for the requested timestamp */
        private $idCache = array();
 
        function __construct() {
@@ -17,22 +46,23 @@ class BenchmarkParse extends Maintenance {
                        'Use the version of the page which was current at the given time',
                        false, true );
                $this->addOption( 'tpl-time',
-                       'Use templates which were current at the given time (except that moves and deletes are not handled properly)',
+                       'Use templates which were current at the given time (except that moves and ' .
+                               'deletes are not handled properly)',
                        false, true );
        }
 
        function execute() {
-               global $wgParser;
-
                if ( $this->hasOption( 'tpl-time' ) ) {
                        $this->templateTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'tpl-time' ) ) );
                        Hooks::register( 'BeforeParserFetchTemplateAndtitle', array( $this, 'onFetchTemplate' ) );
                }
+
                $title = Title::newFromText( $this->getArg() );
                if ( !$title ) {
                        $this->error( "Invalid title" );
                        exit( 1 );
                }
+
                if ( $this->hasOption( 'page-time' ) ) {
                        $pageTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'page-time' ) ) );
                        $id = $this->getRevIdForTime( $title, $pageTimestamp );
@@ -45,13 +75,16 @@ class BenchmarkParse extends Maintenance {
                } else {
                        $revision = Revision::newFromTitle( $title );
                }
+
                if ( !$revision ) {
                        $this->error( "Unable to load revision, incorrect title?" );
                        exit( 1 );
                }
+
                if ( !$this->hasOption( 'cold' ) ) {
                        $this->runParser( $revision );
                }
+
                $startUsage = getrusage();
                $startTime = microtime( true );
                $this->runParser( $revision );
@@ -59,49 +92,60 @@ class BenchmarkParse extends Maintenance {
                $endTime = microtime( true );
 
                printf( "CPU time = %.3f s, wall clock time = %.3f s\n",
+                       // CPU time
                        $endUsage['ru_utime.tv_sec'] + $endUsage['ru_utime.tv_usec'] * 1e-6
-                       - $startUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_usec'] * 1e-6,
+                               - $startUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_usec'] * 1e-6,
+                       // Wall clock time
                        $endTime - $startTime );
        }
 
        /**
+        * Fetch the ID of the revision of a Title that occurred
+        *
         * @param Title $title
         * @param string $timestamp
-        * @return bool|mixed
+        * @return bool|string Revision ID, or false if not found or error
         */
-       function getRevIdForTime( $title, $timestamp ) {
+       function getRevIdForTime( Title $title, $timestamp ) {
                $dbr = wfGetDB( DB_SLAVE );
+
                $id = $dbr->selectField(
                        array( 'revision', 'page' ),
                        'rev_id',
                        array(
                                'page_namespace' => $title->getNamespace(),
                                'page_title' => $title->getDBkey(),
-                               'rev_page=page_id',
                                'rev_timestamp <= ' . $dbr->addQuotes( $timestamp )
                        ),
                        __METHOD__,
-                       array( 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ) );
+                       array( 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ),
+                       array( 'revision' => array( 'INNER JOIN', 'rev_page=page_id' ) )
+               );
 
                return $id;
        }
 
        /**
+        * Parse the text from a given Revision
+        *
         * @param Revision $revision
         */
-       function runParser( $revision ) {
+       function runParser( Revision $revision ) {
                $content = $revision->getContent();
                $content->getParserOutput( $revision->getTitle(), $revision->getId() );
        }
 
        /**
+        * Hook into the parser's revision ID fetcher. Make sure that the parser only
+        * uses revisions around the specified timestamp.
+        *
         * @param Parser $parser
         * @param Title $title
-        * @param $skip
-        * @param $id
+        * @param bool &$skip
+        * @param string|bool &$id
         * @return bool
         */
-       function onFetchTemplate( $parser, $title, &$skip, &$id ) {
+       function onFetchTemplate( Parser $parser, Title $title, &$skip, &$id ) {
                $pdbk = $title->getPrefixedDBkey();
                if ( !isset( $this->idCache[$pdbk] ) ) {
                        $proposedId = $this->getRevIdForTime( $title, $this->templateTimestamp );