if($wgUseTeX) require_once( "Math.php" );
+define( 'RLH_FOR_UPDATE', 1 );
+
class OutputPage {
var $mHeaders, $mCookies, $mMetatags, $mKeywords;
var $mLinktags, $mPagetitle, $mBodytext, $mDebugtext;
var $mHTMLtitle, $mRobotpolicy, $mIsarticle, $mPrintable;
var $mSubtitle, $mRedirect;
var $mLastModified, $mCategoryLinks;
- var $mScripts;
+ var $mScripts, $mLinkColours;
var $mSuppressQuickbar;
var $mOnloadHandler;
$this->sendCacheControl();
# Perform link colouring
- $this->mBodytext = $this->parseLinkHolders();
+ $this->replaceLinkHolders();
# Disable temporary placeholders, so that the skin produces HTML
$sk->postParseLinkColour( false );
return $ret;
}
- # Parse <!--LINK--> link placeholders to avoid using linkcache
+ # Replace <!--LINK--> link placeholders with actual links, in the buffer
# Placeholders created in Skin::makeLinkObj()
- function parseLinkHolders()
+ # Returns an array of links found, indexed by PDBK:
+ # 0 - broken
+ # 1 - normal link
+ # 2 - stub
+ # $options is a bit field, RLH_FOR_UPDATE to select for update
+ function replaceLinkHolders( $options = 0 )
{
- global $wgUser;
+ global $wgUser, $wgLinkCache, $wgUseOldExistenceCheck;
- $fname = 'OutputPage::parseLinkHolders';
+ if ( $wgUseOldExistenceCheck ) {
+ return array();
+ }
+
+ $fname = 'OutputPage::replaceLinkHolders';
wfProfileIn( $fname );
+
+ $titles = array();
+ $pdbks = array();
+ $colours = array();
# Get placeholders from body
preg_match_all( "/<!--LINK (.*?) (.*?) (.*?) (.*?)-->/", $this->mBodytext, $tmpLinks );
asort( $namespaces );
# Generate query
+ $query = false;
foreach ( $namespaces as $key => $val ) {
- if ( !isset( $current ) ) {
- $current = $val;
- $query = "SELECT cur_namespace, cur_title";
- if ( $threshold > 0 ) {
- $query .= ", LENGTH(cur_text) AS cur_len, cur_is_redirect";
- }
- $query .= " FROM $cur WHERE (cur_namespace=$val AND cur_title IN(";
- } elseif ( $current != $val ) {
- $current = $val;
- $query .= ")) OR (cur_namespace=$val AND cur_title IN(";
+ # Make title object
+ $dbk = $dbkeys[$key];
+ $title = $titles[$key] = Title::makeTitle( $val, $dbk );
+ $pdbk = $pdbks[$key] = $title->getPrefixedDBkey();
+
+ # Check if it's in the link cache already
+ if ( $wgLinkCache->getGoodLinkID( $pdbk ) ) {
+ $colours[$pdbk] = 1;
+ } elseif ( $wgLinkCache->isBadLink( $pdbk ) ) {
+ $colours[$pdbk] = 0;
} else {
- $query .= ", ";
- }
+ # Not in the link cache, add it to the query
+ if ( !isset( $current ) ) {
+ $current = $val;
+ $query = "SELECT cur_id, cur_namespace, cur_title";
+ if ( $threshold > 0 ) {
+ $query .= ", LENGTH(cur_text) AS cur_len, cur_is_redirect";
+ }
+ $query .= " FROM $cur WHERE (cur_namespace=$val AND cur_title IN(";
+ } elseif ( $current != $val ) {
+ $current = $val;
+ $query .= ")) OR (cur_namespace=$val AND cur_title IN(";
+ } else {
+ $query .= ", ";
+ }
- $query .= $dbr->addQuotes( $dbkeys[$key] );
+ $query .= $dbr->addQuotes( $dbkeys[$key] );
+ }
}
-
- $query .= "))";
-
- $res = $dbr->query( $query, $fname );
+ if ( $query ) {
+ $query .= "))";
+ if ( $options & RLH_FOR_UPDATE ) {
+ $query .= " FOR UPDATE";
+ }
- # Fetch data and form into an associative array
- # non-existent = broken
- # 1 = known
- # 2 = stub
- $colours = array();
- while ( $s = $dbr->fetchObject($res) ) {
- $key = $s->cur_namespace . ' ' . $s->cur_title;
- if ( $threshold > 0 ) {
- $size = $s->cur_len;
- if ( $s->cur_is_redirect || $s->cur_namespace != 0 || $length < $threshold ) {
- $colours[$key] = 1;
+ $res = $dbr->query( $query, $fname );
+
+ # Fetch data and form into an associative array
+ # non-existent = broken
+ # 1 = known
+ # 2 = stub
+ while ( $s = $dbr->fetchObject($res) ) {
+ $title = Title::makeTitle( $s->cur_namespace, $s->cur_title );
+ $pdbk = $title->getPrefixedDBkey();
+ $wgLinkCache->addGoodLink( $s->cur_id, $pdbk );
+
+ if ( $threshold > 0 ) {
+ $size = $s->cur_len;
+ if ( $s->cur_is_redirect || $s->cur_namespace != 0 || $length < $threshold ) {
+ $colours[$pdbk] = 1;
+ } else {
+ $colours[$pdbk] = 2;
+ }
} else {
- $colours[$key] = 2;
+ $colours[$pdbk] = 1;
}
- $colours[$key] = array( $s->cur_len, $s->cur_is_redirect );
- } else {
- $colours[$key] = 1;
}
}
# Construct search and replace arrays
$search = $replace = array();
foreach ( $namespaces as $key => $ns ) {
- $cKey = $ns . ' ' . $dbkeys[$key];
+ $pdbk = $pdbks[$key];
$search[] = $tmpLinks[0][$key];
- $title = Title::makeTitle( $ns, $dbkeys[$key] );
- if ( empty( $colours[$cKey] ) ) {
+ $title = $titles[$key];
+ if ( empty( $colours[$pdbk] ) ) {
+ $wgLinkCache->addBadLink( $pdbk );
+ $colours[$pdbk] = 0;
$replace[] = $sk->makeBrokenLinkObj( $title, $texts[$key], $queries[$key] );
- } elseif ( $colours[$cKey] == 1 ) {
+ } elseif ( $colours[$pdbk] == 1 ) {
$replace[] = $sk->makeKnownLinkObj( $title, $texts[$key], $queries[$key] );
- } elseif ( $colours[$cKey] == 2 ) {
+ } elseif ( $colours[$pdbk] == 2 ) {
$replace[] = $sk->makeStubLinkObj( $title, $texts[$key], $queries[$key] );
}
}
-
# Do the thing
- $out = str_replace( $search, $replace, $this->mBodytext );
- } else {
- $out = $this->mBodytext;
+ $this->mBodytext = str_replace( $search, $replace, $this->mBodytext );
}
-
wfProfileOut( $fname );
- return ( $out );
+ return $colours;
}
}
wfProfileOut( $fname.'-includes' );
-wfProfileIn( $fname.'-memcached' );
+wfProfileIn( $fname.'-misc1' );
global $wgUser, $wgLang, $wgOut, $wgTitle;
global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
global $wgBlockCache, $wgParserCache, $wgParser, $wgDBConnections;
global $wgLoadBalancer, $wgDBservers, $wgDebugDumpSql;
global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype;
+global $wgUseOldExistenceCheck, $wgEnablePersistentLC;
+
global $wgFullyInitialised;
# Useful debug output
wfDebug( $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'] . "\n" );
}
+# Disable linkscc except if the old existence check method is enabled
+if (!$wgUseOldExistenceCheck) {
+ $wgEnablePersistentLC = false;
+}
+
+wfProfileOut( $fname.'-misc1' );
+wfProfileIn( $fname.'-memcached' );
+
# Set up Memcached
#
class MemCachedClientforWiki extends memcached {
}
wfProfileOut( $fname.'-User' );
-wfProfileIn( $fname.'-misc' );
+wfProfileIn( $fname.'-misc2' );
$wgDeferredUpdateList = array();
$wgLinkCache = new LinkCache();
$wgTitle = Title::newFromText( wfMsg( 'badtitle' ) );
$wgArticle = new Article($wgTitle);
-wfProfileOut( $fname.'-misc' );
+wfProfileOut( $fname.'-misc2' );
wfProfileIn( $fname.'-extensions' );
# Extension setup functions
# Don't generate TeX PNGs (lack of a sensible current directory causes errors anyway)
$wgUser->setOption("math", 3);
- # Turn on link cache in skin
- $sk =& $wgUser->getSkin();
- $sk->postParseLinkColour( false );
for ($id = $start; $id <= $end; $id++) {
if ( !($id % REPORTING_INTERVAL) ) {
if ( is_null( $wgTitle ) ) {
continue;
}
-
+ $dbw->query("BEGIN");
+
$wgArticle = new Article( $wgTitle );
$text = $wgArticle->getContent( true );
$wgLinkCache = new LinkCache;
$wgLinkCache->forUpdate( true );
+
+ # Parse the text and replace links with placeholders
$wgOut->addWikiText( $text );
+
+ # Look up the links in the DB and add them to the link cache
+ $wgOut->replaceLinkHolders( RLH_FOR_UPDATE );
if ( $wgEnablePersistentLC ) {
$wgLinkCache->saveToLinkscc( $id, $dbw->strencode( $wgTitle->getPrefixedDBkey() ) );
$linksUpdate = new LinksUpdate( $id, $wgTitle->getPrefixedDBkey() );
$linksUpdate->doDumbUpdate();
$linksUpdate->fixBrokenLinks();
+ $dbw->query("COMMIT");
}
}
?>