r50436 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r50435‎ | r50436 | r50437 >
Date:14:08, 10 May 2009
Author:catrope
Status:deferred
Tags:
Comment:
Performance improvements:
* Fix orderings all over
* Precache page existence in DisambiguationsPage
* Grab target information from redirect table in ListRedirectsPage
* Skip unnecessary existence check in ShortpagesPage
* Mark lots of pages as potentially inexpensive
* Various fixes
Modified paths:
  • /branches/querypage-work/phase3/includes/Linker.php (modified) (history)
  • /branches/querypage-work/phase3/includes/QueryPage.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialBrokenRedirects.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialDeadendpages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialDisambiguations.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialDoubleRedirects.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialListredirects.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialLonelypages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialMostlinkedtemplates.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialShortpages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialUncategorizedimages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialUncategorizedpages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialUnusedcategories.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialUnusedimages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialUnusedtemplates.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialUnwatchedpages.php (modified) (history)
  • /branches/querypage-work/phase3/includes/specials/SpecialWithoutinterwiki.php (modified) (history)

Diff [purge]

Index: branches/querypage-work/phase3/includes/Linker.php
@@ -275,7 +275,7 @@
276276 }
277277
278278 # Note that redirects never count as stubs here.
279 - if ( $target->isRedirect() ) {
 279+ if ( !in_array( 'broken', $options ) && $target->isRedirect() ) {
280280 $classes[] = 'mw-redirect';
281281 } elseif( $target->isContentPage() ) {
282282 # Check for stub.
Index: branches/querypage-work/phase3/includes/specials/SpecialDisambiguations.php
@@ -21,63 +21,6 @@
2222 return wfMsgExt( 'disambiguations-text', array( 'parse' ) );
2323 }
2424
25 - function getSQL() {
26 - $dbr = wfGetDB( DB_SLAVE );
27 -
28 - $dMsgText = wfMsgForContent('disambiguationspage');
29 -
30 - $linkBatch = new LinkBatch;
31 -
32 - # If the text can be treated as a title, use it verbatim.
33 - # Otherwise, pull the titles from the links table
34 - $dp = Title::newFromText($dMsgText);
35 - if( $dp ) {
36 - if($dp->getNamespace() != NS_TEMPLATE) {
37 - # FIXME we assume the disambiguation message is a template but
38 - # the page can potentially be from another namespace :/
39 - wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n");
40 - }
41 - $linkBatch->addObj( $dp );
42 - } else {
43 - # Get all the templates linked from the Mediawiki:Disambiguationspage
44 - $disPageObj = Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage' );
45 - $res = $dbr->select(
46 - array('pagelinks', 'page'),
47 - 'pl_title',
48 - array('page_id = pl_from', 'pl_namespace' => NS_TEMPLATE,
49 - 'page_namespace' => $disPageObj->getNamespace(), 'page_title' => $disPageObj->getDBkey()),
50 - __METHOD__ );
51 -
52 - while ( $row = $dbr->fetchObject( $res ) ) {
53 - $linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title ));
54 - }
55 -
56 - $dbr->freeResult( $res );
57 - }
58 -
59 - $set = $linkBatch->constructSet( 'lb.tl', $dbr );
60 - if( $set === false ) {
61 - # We must always return a valid sql query, but this way DB will always quicly return an empty result
62 - $set = 'FALSE';
63 - wfDebug("Mediawiki:disambiguationspage message does not link to any templates!\n");
64 - }
65 -
66 - list( $page, $pagelinks, $templatelinks) = $dbr->tableNamesN( 'page', 'pagelinks', 'templatelinks' );
67 -
68 - $sql = "SELECT 'Disambiguations' AS \"type\", pb.page_namespace AS namespace,"
69 - ." pb.page_title AS title, la.pl_from AS value"
70 - ." FROM {$templatelinks} AS lb, {$page} AS pb, {$pagelinks} AS la, {$page} AS pa"
71 - ." WHERE $set" # disambiguation template(s)
72 - .' AND pa.page_id = la.pl_from'
73 - .' AND pa.page_namespace = ' . NS_MAIN # Limit to just articles in the main namespace
74 - .' AND pb.page_id = lb.tl_from'
75 - .' AND pb.page_namespace = la.pl_namespace'
76 - .' AND pb.page_title = la.pl_title'
77 - .' ORDER BY lb.tl_namespace, lb.tl_title';
78 -
79 - return $sql;
80 - }
81 -
8225 function getQueryInfo() {
8326 $dbr = wfGetDB( DB_SLAVE );
8427 $dMsgText = wfMsgForContent('disambiguationspage');
@@ -139,7 +82,23 @@
14083 function sortDescending() {
14184 return false;
14285 }
 86+
 87+ /**
 88+ * Fetch links and cache their existence
 89+ */
 90+ function preprocessResults( $db, $res ) {
 91+ $batch = new LinkBatch;
 92+ while ( $row = $db->fetchObject( $res ) )
 93+ $batch->add( $row->namespace, $row->title );
 94+ $batch->execute();
14395
 96+ // Back to start for display
 97+ if ( $db->numRows( $res ) > 0 )
 98+ // If there are no rows we get an error seeking.
 99+ $db->dataSeek( $res, 0 );
 100+ }
 101+
 102+
144103 function formatResult( $skin, $result ) {
145104 global $wgContLang;
146105 $title = Title::newFromID( $result->value );
Index: branches/querypage-work/phase3/includes/specials/SpecialBrokenRedirects.php
@@ -16,8 +16,10 @@
1717 return 'BrokenRedirects';
1818 }
1919
 20+ // inexpensive?
2021 function isExpensive() { return true; }
2122 function isSyndicated() { return false; }
 23+ function sortDescending() { return false; }
2224
2325 function getPageHeader() {
2426 return wfMsgExt( 'brokenredirectstext', array( 'parse' ) );
@@ -46,8 +48,7 @@
4749 }
4850
4951 function getOrderFields() {
50 - // FIXME: really?
51 - return array ();
 52+ return array ( 'rd_namespace', 'rd_title', 'rd_from' );
5253 }
5354
5455 function formatResult( $skin, $result ) {
Index: branches/querypage-work/phase3/includes/specials/SpecialUnwatchedpages.php
@@ -16,6 +16,7 @@
1717 class UnwatchedpagesPage extends QueryPage {
1818
1919 function getName() { return 'Unwatchedpages'; }
 20+ // inexpensive?
2021 function isExpensive() { return true; }
2122 function isSyndicated() { return false; }
2223
@@ -36,6 +37,9 @@
3738 }
3839
3940 function sortDescending() { return false; }
 41+
 42+ function getOrderFields() {
 43+ return array( 'page_namespace', 'page_title' );
4044
4145 function formatResult( $skin, $result ) {
4246 global $wgContLang;
Index: branches/querypage-work/phase3/includes/specials/SpecialLonelypages.php
@@ -22,6 +22,7 @@
2323 return false;
2424 }
2525
 26+ // inexpensive?
2627 function isExpensive() {
2728 return true;
2829 }
@@ -49,6 +50,15 @@
5051 'tl_title = page_title' ) ) )
5152 );
5253 }
 54+
 55+ function getOrderFields() {
 56+ // For some crazy reason ordering by a constant
 57+ // causes a filesort
 58+ if( count( MWNamespace::getContentNamespaces() ) > 1 )
 59+ return array( 'page_namespace', 'page_title' );
 60+ else
 61+ return array( 'page_title' );
 62+ }
5363 }
5464
5565 /**
Index: branches/querypage-work/phase3/includes/specials/SpecialUncategorizedpages.php
@@ -20,6 +20,7 @@
2121 return false;
2222 }
2323
 24+ // inexpensive?
2425 function isExpensive() {
2526 return true;
2627 }
@@ -40,6 +41,14 @@
4142 'LEFT JOIN', 'cl_from = page_id' ) )
4243 );
4344 }
 45+
 46+ function getOrderFields() {
 47+ // For some crazy reason ordering by a constant
 48+ // causes a filesort
 49+ if( $this->requestedNamespace === false && count( MWNamespace::getContentNamespaces() ) > 1 )
 50+ return array( 'page_namespace', 'page_title' );
 51+ return array( 'page_title' );
 52+ }
4453 }
4554
4655 /**
Index: branches/querypage-work/phase3/includes/specials/SpecialMostlinkedtemplates.php
@@ -84,7 +84,7 @@
8585 * @return string
8686 */
8787 public function formatResult( $skin, $result ) {
88 - $title = Title::makeTitleSafe( $result->namespace, $result->title );
 88+ $title = Title::makeTitle( $result->namespace, $result->title );
8989
9090 $skin->link( $title );
9191 return wfSpecialList(
Index: branches/querypage-work/phase3/includes/specials/SpecialUnusedcategories.php
@@ -9,6 +9,7 @@
1010 */
1111 class UnusedCategoriesPage extends QueryPage {
1212
 13+ // inexpensive?
1314 function isExpensive() { return true; }
1415
1516 function getName() {
@@ -35,7 +36,7 @@
3637
3738 function formatResult( $skin, $result ) {
3839 $title = Title::makeTitle( NS_CATEGORY, $result->title );
39 - return $skin->link( $title, $title->getText() );
 40+ return $skin->makeKnownLinkObj( $title, $title->getText() );
4041 }
4142 }
4243
Index: branches/querypage-work/phase3/includes/specials/SpecialShortpages.php
@@ -15,9 +15,9 @@
1616 return 'Shortpages';
1717 }
1818
 19+ // inexpensive?
1920 /**
2021 * This query is indexed as of 1.5
21 - * FIXME: Mark as inexpensive
2222 */
2323 function isExpensive() {
2424 return true;
@@ -60,7 +60,7 @@
6161 global $wgLang, $wgContLang;
6262 $dm = $wgContLang->getDirMark();
6363
64 - $title = Title::makeTitleSafe( $result->namespace, $result->title );
 64+ $title = Title::makeTitle( $result->namespace, $result->title );
6565 if ( !$title ) {
6666 return '<!-- Invalid title ' . htmlspecialchars( "{$result->namespace}:{$result->title}" ). '-->';
6767 }
@@ -70,9 +70,9 @@
7171 : $skin->makeKnownLinkObj( $title );
7272 $size = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), $wgLang->formatNum( htmlspecialchars( $result->value ) ) );
7373
74 - return $title->exists()
75 - ? "({$hlink}) {$dm}{$plink} {$dm}[{$size}]"
76 - : "<s>({$hlink}) {$dm}{$plink} {$dm}[{$size}]</s>";
 74+ return ($this->isCached() && !$title->exists())
 75+ ? "<s>({$hlink}) {$dm}{$plink} {$dm}[{$size}]</s>"
 76+ : "({$hlink}) {$dm}{$plink} {$dm}[{$size}]";
7777 }
7878 }
7979
Index: branches/querypage-work/phase3/includes/specials/SpecialUnusedtemplates.php
@@ -14,6 +14,7 @@
1515 class UnusedtemplatesPage extends QueryPage {
1616
1717 function getName() { return( 'Unusedtemplates' ); }
 18+ // inexpensive?
1819 function isExpensive() { return true; }
1920 function isSyndicated() { return false; }
2021 function sortDescending() { return false; }
@@ -23,7 +24,7 @@
2425 'tables' => array ( 'page', 'templatelinks' ),
2526 'fields' => array ( 'page_namespace AS namespace',
2627 'page_title AS title',
27 - '0 AS value' ),
 28+ 'page_title AS value' ),
2829 'conds' => array ( 'page_namespace' => NS_TEMPLATE,
2930 'tl_from IS NULL',
3031 'page_is_redirect' => 0 ),
@@ -32,7 +33,7 @@
3334 'tl_namespace = page_namespace' ) ) )
3435 );
3536 }
36 -
 37+
3738 function formatResult( $skin, $result ) {
3839 $title = Title::makeTitle( NS_TEMPLATE, $result->title );
3940 $pageLink = $skin->makeKnownLinkObj( $title, '', 'redirect=no' );
Index: branches/querypage-work/phase3/includes/specials/SpecialWithoutinterwiki.php
@@ -41,7 +41,12 @@
4242 function sortDescending() {
4343 return false;
4444 }
 45+
 46+ function getOrderFields() {
 47+ return array( 'page_namespace', 'page_title' );
 48+ }
4549
 50+ // inexpensive?
4651 function isExpensive() {
4752 return true;
4853 }
Index: branches/querypage-work/phase3/includes/specials/SpecialUnusedimages.php
@@ -10,6 +10,7 @@
1111 */
1212 class UnusedimagesPage extends ImageQueryPage {
1313
 14+ // inexpensive?
1415 function isExpensive() { return true; }
1516
1617 function getName() {
Index: branches/querypage-work/phase3/includes/specials/SpecialUncategorizedimages.php
@@ -21,6 +21,7 @@
2222 return false;
2323 }
2424
 25+ // inexpensive?
2526 function isExpensive() {
2627 return true;
2728 }
@@ -28,17 +29,6 @@
2930 function isSyndicated() {
3031 return false;
3132 }
32 -
33 - function getSQL() {
34 - $dbr = wfGetDB( DB_SLAVE );
35 - list( $page, $categorylinks ) = $dbr->tableNamesN( 'page', 'categorylinks' );
36 - $ns = NS_FILE;
37 -
38 - return "SELECT 'Uncategorizedimages' AS type, page_namespace AS namespace,
39 - page_title AS title, page_title AS value
40 - FROM {$page} LEFT JOIN {$categorylinks} ON page_id = cl_from
41 - WHERE cl_from IS NULL AND page_namespace = {$ns} AND page_is_redirect = 0";
42 - }
4333
4434 function getQueryInfo() {
4535 return array (
Index: branches/querypage-work/phase3/includes/specials/SpecialDeadendpages.php
@@ -17,13 +17,14 @@
1818 return wfMsgExt( 'deadendpagestext', array( 'parse' ) );
1919 }
2020
 21+ // inexpensive?
2122 /**
2223 * LEFT JOIN is expensive
2324 *
2425 * @return true
2526 */
2627 function isExpensive() {
27 - return 1;
 28+ return true;
2829 }
2930
3031 function isSyndicated() { return false; }
@@ -51,6 +52,15 @@
5253 ) ) )
5354 );
5455 }
 56+
 57+ function getOrderFields() {
 58+ // For some crazy reason ordering by a constant
 59+ // causes a filesort
 60+ if( count( MWNamespace::getContentNamespaces() ) > 1 )
 61+ return array( 'page_namespace', 'page_title' );
 62+ else
 63+ return array( 'page_title' );
 64+ }
5565 }
5666
5767 /**
Index: branches/querypage-work/phase3/includes/specials/SpecialDoubleRedirects.php
@@ -15,14 +15,16 @@
1616 return 'DoubleRedirects';
1717 }
1818
19 - function isExpensive( ) { return true; }
 19+ // inexpensive?
 20+ function isExpensive() { return true; }
2021 function isSyndicated() { return false; }
 22+ function sortDescending() { return false; }
2123
22 - function getPageHeader( ) {
 24+ function getPageHeader() {
2325 return wfMsgExt( 'doubleredirectstext', array( 'parse' ) );
2426 }
2527
26 - function reallyGetQueryInfo($namespace = null, $title = null) {
 28+ function reallyGetQueryInfo( $namespace = null, $title = null ) {
2729 $limitToTitle = !( $namespace === null && $title === null );
2830 $retval = array (
2931 'tables' => array ( 'redirect AS ra', 'redirect AS rb',
@@ -36,7 +38,7 @@
3739 'pc.page_title AS tc' ),
3840 'conds' => array ( 'ra.rd_from = pa.page_id',
3941 'pb.page_namespace = ra.rd_namespace',
40 - 'pb.page_title = rb.rd_title',
 42+ 'pb.page_title = ra.rd_title',
4143 'rb.rd_from = pb.page_id',
4244 'pc.page_namespace = rb.rd_namespace',
4345 'pc.page_title = rb.rd_title' )
@@ -53,8 +55,7 @@
5456 }
5557
5658 function getOrderFields() {
57 - // FIXME: really?
58 - return array ();
 59+ return array ( 'ra.rd_namespace', 'ra.rd_title' );
5960 }
6061
6162 function formatResult( $skin, $result ) {
Index: branches/querypage-work/phase3/includes/specials/SpecialListredirects.php
@@ -15,22 +15,30 @@
1616 class ListredirectsPage extends QueryPage {
1717
1818 function getName() { return 'Listredirects'; }
 19+ // inexpensive?
1920 function isExpensive() { return true; }
2021 function isSyndicated() { return false; }
2122 function sortDescending() { return false; }
2223
2324 function getQueryInfo() {
24 - return array (
25 - 'tables' => array ( 'page' ),
26 - 'fields' => array ( 'page_namespace AS namespace',
27 - 'page_title AS title' ),
28 - 'conds' => array ( 'page_is_redirect' => 1 )
 25+ return array(
 26+ 'tables' => array( 'page AS p1', 'redirect', 'page AS p2' ),
 27+ 'fields' => array( 'p1.page_namespace AS namespace',
 28+ 'p1.page_title AS title',
 29+ 'rd_namespace',
 30+ 'rd_title',
 31+ 'p2.page_id AS redirid' ),
 32+ 'conds' => array( 'p1.page_is_redirect' => 1 ),
 33+ 'join_conds' => array( 'redirect' => array(
 34+ 'LEFT JOIN', 'rd_from=p1.page_id' ),
 35+ 'page AS p2' => array( 'LEFT JOIN', array(
 36+ 'p2.page_namespace=rd_namespace',
 37+ 'p2.page_title=rd_title' ) ) )
2938 );
3039 }
3140
3241 function getOrderFields() {
33 - // FIXME: really?
34 - return array ();
 42+ return array ( 'namespace', 'title' );
3543 }
3644
3745 function formatResult( $skin, $result ) {
@@ -38,25 +46,33 @@
3947
4048 # Make a link to the redirect itself
4149 $rd_title = Title::makeTitle( $result->namespace, $result->title );
42 - $rd_link = $skin->link(
 50+ $rd_link = $skin->makeKnownLinkObj(
4351 $rd_title,
4452 null,
45 - array(),
46 - array( 'redirect' => 'no' )
 53+ 'redirect=no'
4754 );
4855
4956 # Find out where the redirect leads
50 - $revision = Revision::newFromTitle( $rd_title );
51 - if( $revision ) {
52 - # Make a link to the destination page
53 - $target = Title::newFromRedirect( $revision->getText() );
54 - if( $target ) {
55 - $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
 57+ $target = null;
 58+ if( !is_null( $result->rd_namespace ) ) {
 59+ $target = Title::makeTitle( $result->rd_namespace, $result->rd_title );
 60+ } else {
 61+ $revision = Revision::newFromTitle( $rd_title );
 62+ if( $revision ) {
 63+ $target = Title::newFromRedirect( $revision->getText() );
 64+ }
 65+ }
 66+
 67+ # Make a link to the destination page
 68+ if( $target ) {
 69+ $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
 70+ if( !is_null ( $result->redirid ) )
 71+ $targetLink = $skin->makeKnownLinkObj( $target );
 72+ else if( !is_null( $result->rd_namespace ) )
 73+ $targetLink = $skin->makeBrokenLinkObj( $target );
 74+ else
5675 $targetLink = $skin->link( $target );
57 - return "$rd_link $arr $targetLink";
58 - } else {
59 - return "<s>$rd_link</s>";
60 - }
 76+ return "$rd_link $arr $targetLink";
6177 } else {
6278 return "<s>$rd_link</s>";
6379 }
Index: branches/querypage-work/phase3/includes/QueryPage.php
@@ -162,7 +162,7 @@
163163 * don't let it run in miser mode. $wgDisableQueryPages causes all query
164164 * pages to be declared expensive. Some query pages are always expensive.
165165 */
166 - function isExpensive( ) {
 166+ function isExpensive() {
167167 global $wgDisableQueryPages;
168168 return $wgDisableQueryPages;
169169 }

Follow-up revisions

RevisionCommit summaryAuthorDate
r65322querypage-work2: Merge r50436 r50437reedy14:24, 20 April 2010

Status & tagging log