pageid parser function is expensive, make it so
authorBrad Jorsch <bjorsch@wikimedia.org>
Tue, 14 Jan 2014 20:36:48 +0000 (15:36 -0500)
committerBrad Jorsch <bjorsch@wikimedia.org>
Tue, 14 Jan 2014 20:44:08 +0000 (15:44 -0500)
The pageid parser function (not to be confused with the pageid magic
word) hits the database for every title passed, which meets the criteria
for being considered an expensive parser function.

To mitigate this new expensiveness, check for special namespaces,
interwiki titles, and titles in LinkCache before hitting the DB.

Also, record potentially-valid titles in pagelinks so that the page can
be properly purged if the target is created/deleted.

Change-Id: I4fbfc265543f0a64c14dc8a44e1c89cd928a1adb

includes/parser/CoreParserFunctions.php

index df0f118..13feb80 100644 (file)
@@ -986,10 +986,34 @@ class CoreParserFunctions {
                // Use title from parser to have correct pageid after edit
                if ( $t->equals( $parser->getTitle() ) ) {
                        $t = $parser->getTitle();
+                       return $t->getArticleID();
                }
-               // fetch pageid from cache/database and return the value
-               $pageid = $t->getArticleID();
-               return $pageid ? $pageid : '';
+
+               // These can't have ids
+               if ( !$t->canExist() || $t->isExternal() ) {
+                       return 0;
+               }
+
+               // Check the link cache, maybe something already looked it up.
+               $linkCache = LinkCache::singleton();
+               $pdbk = $t->getPrefixedDBkey();
+               $id = $linkCache->getGoodLinkID( $pdbk );
+               if ( $id != 0 ) {
+                       $parser->mOutput->addLink( $t, $id );
+                       return $id;
+               }
+               if ( $linkCache->isBadLink( $pdbk ) ) {
+                       $parser->mOutput->addLink( $t, 0 );
+                       return $id;
+               }
+
+               // We need to load it from the DB, so mark expensive
+               if ( $parser->incrementExpensiveFunctionCount() ) {
+                       $id = $t->getArticleID();
+                       $parser->mOutput->addLink( $t, $id );
+                       return $id;
+               }
+               return null;
        }
 
        /**