var $mId, //!< Page ID of the article linked from
$mTitle, //!< Title object of the article linked from
$mLinks, //!< Map of title strings to IDs for the links in the document
- $mExistingLinks,
$mImages, //!< DB keys of the images used, in the array key only
- $mExistingImages,
$mTemplates, //!< Map of title strings to IDs for the template references, including broken ones
- $mExistingTemplates,
$mExternals, //!< URLs of external links, array key only
- $mExistingExternals,
$mCategories, //!< Map of category names to sort keys
- $mExistingCategories,
$mInterlangs, //!< Map of language codes to titles
- $mExistingInterlangs,
$mProperties, //!< Map of arbitrary name to value
- $mExistingProperties,
$mDb, //!< Database connection reference
$mOptions, //!< SELECT options to be used (array)
$mRecursive; //!< Whether to queue jobs for recursive updates
}
$this->mRecursive = $recursive;
+ $this->mTouchTmplLinks = false;
wfRunHooks( 'LinksUpdateConstructed', array( &$this ) );
}
/**
* Update link tables with outgoing links from an updated article
*/
- function doUpdate() {
- global $wgUseDumbLinkUpdate, $wgTrackLinkChanges;
+ public function doUpdate() {
+ global $wgUseDumbLinkUpdate;
wfRunHooks( 'LinksUpdate', array( &$this ) );
if ( $wgUseDumbLinkUpdate ) {
} else {
$this->doIncrementalUpdate();
}
- if ( $wgTrackLinkChanges )
- $this->makeRecentlinkchanges();
wfRunHooks( 'LinksUpdateComplete', array( &$this ) );
-
}
- function doIncrementalUpdate() {
+ protected function doIncrementalUpdate() {
wfProfileIn( __METHOD__ );
# Page links
* May be slower or faster depending on level of lock contention and write speed of DB
* Also useful where link table corruption needs to be repaired, e.g. in refreshLinks.php
*/
- function doDumbUpdate() {
+ protected function doDumbUpdate() {
wfProfileIn( __METHOD__ );
# Refresh category pages and image description pages
}
function queueRecursiveJobs() {
+ global $wgUpdateRowsPerJob;
wfProfileIn( __METHOD__ );
- $batchSize = 100;
- $dbr = wfGetDB( DB_SLAVE );
- $res = $dbr->select( array( 'templatelinks', 'page' ),
- array( 'page_namespace', 'page_title' ),
- array(
- 'page_id=tl_from',
- 'tl_namespace' => $this->mTitle->getNamespace(),
- 'tl_title' => $this->mTitle->getDBkey()
- ), __METHOD__
- );
-
- $done = false;
- while ( !$done ) {
- $jobs = array();
- for ( $i = 0; $i < $batchSize; $i++ ) {
- $row = $dbr->fetchObject( $res );
- if ( !$row ) {
- $done = true;
- break;
- }
- $title = Title::makeTitle( $row->page_namespace, $row->page_title );
- $jobs[] = new RefreshLinksJob( $title, '' );
- }
- Job::batchInsert( $jobs );
+ $cache = $this->mTitle->getBacklinkCache();
+ $batches = $cache->partition( 'templatelinks', $wgUpdateRowsPerJob );
+ if ( !$batches ) {
+ wfProfileOut( __METHOD__ );
+ return;
}
- $dbr->freeResult( $res );
+ $jobs = array();
+ foreach ( $batches as $batch ) {
+ list( $start, $end ) = $batch;
+ $params = array(
+ 'start' => $start,
+ 'end' => $end,
+ );
+ $jobs[] = new RefreshLinksJob2( $this->mTitle, $params );
+ }
+ Job::batchInsert( $jobs );
+
wfProfileOut( __METHOD__ );
}
}
function invalidateImageDescriptions( $images ) {
- $this->invalidatePages( NS_IMAGE, array_keys( $images ) );
+ $this->invalidatePages( NS_FILE, array_keys( $images ) );
}
function dumbTableUpdate( $table, $insertions, $fromField ) {
* @private
*/
function getCategoryInsertions( $existing = array() ) {
+ global $wgContLang;
$diffs = array_diff_assoc( $this->mCategories, $existing );
$arr = array();
foreach ( $diffs as $name => $sortkey ) {
+ $nt = Title::makeTitleSafe( NS_CATEGORY, $name );
+ $wgContLang->findVariantLink( $name, $nt, true );
$arr[] = array(
'cl_from' => $this->mId,
'cl_to' => $name,
* @private
*/
function getExistingLinks() {
- if ( is_array( $this->mExistingLinks ) )
- return $this->mExistingLinks;
-
$res = $this->mDb->select( 'pagelinks', array( 'pl_namespace', 'pl_title' ),
array( 'pl_from' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
$arr[$row->pl_namespace][$row->pl_title] = 1;
}
$this->mDb->freeResult( $res );
- return $this->mExistingLinks = $arr;
+ return $arr;
}
/**
* @private
*/
function getExistingTemplates() {
- if ( is_array( $this->mExistingTemplates ) )
- return $this->mExistingTemplates;
-
$res = $this->mDb->select( 'templatelinks', array( 'tl_namespace', 'tl_title' ),
array( 'tl_from' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
$arr[$row->tl_namespace][$row->tl_title] = 1;
}
$this->mDb->freeResult( $res );
- return $this->mExistingTemplates = $arr;
+ return $arr;
}
/**
* @private
*/
function getExistingImages() {
- if ( is_array( $this->mExistingImages ) )
- return $this->mExistingImages;
-
$res = $this->mDb->select( 'imagelinks', array( 'il_to' ),
array( 'il_from' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
$arr[$row->il_to] = 1;
}
$this->mDb->freeResult( $res );
- return $this->mExistingImages = $arr;
+ return $arr;
}
/**
* @private
*/
function getExistingExternals() {
- if ( is_array( $this->mExistingExternals ) )
- return $this->mExistingExternals;
-
$res = $this->mDb->select( 'externallinks', array( 'el_to' ),
array( 'el_from' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
$arr[$row->el_to] = 1;
}
$this->mDb->freeResult( $res );
- return $this->mExistingExternals = $arr;
+ return $arr;
}
/**
* @private
*/
function getExistingCategories() {
- if ( is_array( $this->mExistingCategories ) )
- return $this->mExistingCategories;
-
$res = $this->mDb->select( 'categorylinks', array( 'cl_to', 'cl_sortkey' ),
array( 'cl_from' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
$arr[$row->cl_to] = $row->cl_sortkey;
}
$this->mDb->freeResult( $res );
- return $this->mExistingCategories = $arr;
+ return $arr;
}
/**
* @private
*/
function getExistingInterlangs() {
- if ( is_array( $this->mExistingInterlangs ) )
- return $this->mExistingInterlangs;
-
$res = $this->mDb->select( 'langlinks', array( 'll_lang', 'll_title' ),
array( 'll_from' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
while ( $row = $this->mDb->fetchObject( $res ) ) {
$arr[$row->ll_lang] = $row->ll_title;
}
- return $this->mExistingInterlangs = $arr;
+ return $arr;
}
/**
* @private
*/
function getExistingProperties() {
- if ( is_array( $this->mExistingProperties ) )
- return $this->mExistingProperties;
-
$res = $this->mDb->select( 'page_props', array( 'pp_propname', 'pp_value' ),
array( 'pp_page' => $this->mId ), __METHOD__, $this->mOptions );
$arr = array();
$arr[$row->pp_propname] = $row->pp_value;
}
$this->mDb->freeResult( $res );
- return $this->mExistingProperties = $arr;
+ return $arr;
}
}
}
}
-
- // Recentlinkchanges constants
- const INSERTION = 1;
- const DELETION = 2;
- private static $rlcFields = array(
- 'rlc_type',
- 'rlc_timestamp',
- 'rlc_action',
- 'rlc_from',
- 'rlc_to_namespace',
- 'rlc_to_title',
- 'rlc_to_blob'
- );
- /*
- * Insert items to recentlinkchanges
- */
- function makeRecentlinkchanges() {
- $insert = array();
- $now = $this->mDb->timestamp();
-
- // Category changes
- $existing = array_keys( $this->getExistingCategories() );
- $current = array_keys( $this->mCategories );
- $this->simpleAddToLinkchanges( $insert, 'category', $now, $existing, $current, NS_CATEGORY );
-
- // External links
- $existing = array_keys( $this->getExistingExternals() );
- $current = array_keys( $this->mExternals );
- $insertions = array_diff( $current, $existing );
- foreach ( $insertions as $item )
- $insert[] = array(
- 'external', $now, self::INSERTION,
- $this->mId, null, null, $item );
- $deletions = array_diff( $existing, $current );
- foreach ( $deletions as $item )
- $insert[] = array(
- 'external', $now, self::DELETION,
- $this->mId, null, null, $item );
-
- // Image changes
- $existing = array_keys( $this->getExistingImages() );
- $current = array_keys( $this->mImages );
- $this->simpleAddToLinkchanges( $insert, 'image', $now, $existing, $current, NS_IMAGE );
-
- // Interlangs
- $existing = $this->getExistingInterlangs();
- $current = $this->mInterlangs;
- $this->assocAddToLinkchanges( $insert, 'interlang', $existing, $current );
-
- // Page links
- $existing = $this->getExistingLinks();
- $current = $this->mLinks;
- $this->addToLinkChangesByNamespace( $insert, 'page', $now, $existing, $current);
-
- // Properties
- $existing = $this->getExistingProperties();
- $current = $this->mProperties;
- $this->assocAddToLinkchanges( $insert, 'property', $existing, $current );
-
- // Templates
- $existing = $this->getExistingTemplates();
- $current = $this->mTemplates;
- $this->addToLinkChangesByNamespace( $insert, 'template', $now, $existing, $current);
-
- $this->mDb->insert( 'recentlinkchanges', $insert, __METHOD__ );
-
- }
-
- /*
- * Compute the difference for arrays of titles with namespace $ns and add
- * them to $insert.
- */
- private function simpleAddToLinkchanges( &$insert, $type, $now, $existing, $current, $ns ) {
-
- $insertions = array_diff( $current, $existing );
- foreach ( $insertions as $item )
- $insert[] = array_combine(self::$rlcFields, array(
- $type, $now, self::INSERTION,
- $this->mId, $ns, $item, null
- ) );
- $deletions = array_diff( $existing, $current );
- foreach ( $deletions as $item )
- $insert[] = array_combine(self::$rlcFields, array(
- $type, $now, self::DELETION,
- $this->mId, $ns, $item, null
- ) );
-
- }
-
- /*
- * Compute the difference for associative arrays and insert them to
- * $insert as title => blob.
- */
- function assocAddToLinkChanges( &$insert, $type, $now, $existing, $current ) {
- $insertions = array_diff_assoc( $current, $existing );
- foreach ( $insertions as $key => $value )
- $insert[] = array_combine(self::$rlcFields, array(
- $type, $now, self::INSERTION,
- $this->mId, null, $key, $value
- ) );
- $deletions = array_diff_assoc( $existing, $current );
- foreach ( $deletions as $key => $value )
- $insert[] = array_combine(self::$rlcFields, array(
- $type, $now, self::DELETION,
- $this->mId, null, $key, $value
- ) );
- }
-
- /*
- * Format arrays in the form $namespace => $titleArray for use in
- * simpleAddLinkLinkChanges
- */
- function addToLinkChangesByNamespace( &$insert, $type, $now, $existing, $current ) {
- $namespaces = array_merge( array_keys( $existing ), array_keys( $current ) );
- foreach ( $namespaces as $ns )
- $this->simpleAddToLinkchanges( $insert, $type, $now,
- isset( $existing[$ns] ) ? array_keys( $existing[$ns] ) : array(),
- isset( $current[$ns] ) ? array_keys( $current[$ns] ) : array(),
- $ns );
- }
}