$mProperties, //!< Map of arbitrary name to value
$mDb, //!< Database connection reference
$mOptions, //!< SELECT options to be used (array)
- $mRecursive; //!< Whether to queue jobs for recursive updates
+ $mRecursive, //!< Whether to queue jobs for recursive updates
+ $mTouchTmplLinks; //!< Whether to queue HTMLCacheUpdate jobs IF recursive
/**@}}*/
/**
}
$this->mRecursive = $recursive;
+ $this->mTouchTmplLinks = false;
wfRunHooks( 'LinksUpdateConstructed', array( &$this ) );
}
+
+ /**
+ * Invalidate HTML cache of pages that include this page?
+ */
+ public function setRecursiveTouch( $val ) {
+ $this->mTouchTmplLinks = (bool)$val;
+ if( $val ) // Cannot invalidate without queueRecursiveJobs()
+ $this->mRecursive = true;
+ }
/**
* Update link tables with outgoing links from an updated article
*/
- function doUpdate() {
+ public function doUpdate() {
global $wgUseDumbLinkUpdate;
wfRunHooks( 'LinksUpdate', array( &$this ) );
}
- function doIncrementalUpdate() {
+ protected function doIncrementalUpdate() {
wfProfileIn( __METHOD__ );
# Page links
# Image links
$existing = $this->getExistingImages();
- $this->incrTableUpdate( 'imagelinks', 'il', $this->getImageDeletions( $existing ),
- $this->getImageInsertions( $existing ) );
+
+ $imageDeletes = $this->getImageDeletions( $existing );
+ $this->incrTableUpdate( 'imagelinks', 'il', $imageDeletes, $this->getImageInsertions( $existing ) );
# Invalidate all image description pages which had links added or removed
- $imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
+ $imageUpdates = $imageDeletes + array_diff_key( $this->mImages, $existing );
$this->invalidateImageDescriptions( $imageUpdates );
# External links
# Category links
$existing = $this->getExistingCategories();
- $this->incrTableUpdate( 'categorylinks', 'cl', $this->getCategoryDeletions( $existing ),
- $this->getCategoryInsertions( $existing ) );
+
+ $categoryDeletes = $this->getCategoryDeletions( $existing );
+
+ $this->incrTableUpdate( 'categorylinks', 'cl', $categoryDeletes, $this->getCategoryInsertions( $existing ) );
# Invalidate all categories which were added, deleted or changed (set symmetric difference)
$categoryInserts = array_diff_assoc( $this->mCategories, $existing );
- $categoryDeletes = array_diff_assoc( $existing, $this->mCategories );
$categoryUpdates = $categoryInserts + $categoryDeletes;
$this->invalidateCategories( $categoryUpdates );
$this->updateCategoryCounts( $categoryInserts, $categoryDeletes );
# Page properties
$existing = $this->getExistingProperties();
- $this->incrTableUpdate( 'page_props', 'pp', $this->getPropertyDeletions( $existing ),
- $this->getPropertyInsertions( $existing ) );
+
+ $propertiesDeletes = $this->getPropertyDeletions( $existing );
+
+ $this->incrTableUpdate( 'page_props', 'pp', $propertiesDeletes, $this->getPropertyInsertions( $existing ) );
# Invalidate the necessary pages
- $changed = array_diff_assoc( $existing, $this->mProperties ) + array_diff_assoc( $this->mProperties, $existing );
+ $changed = $propertiesDeletes + array_diff_assoc( $this->mProperties, $existing );
$this->invalidateProperties( $changed );
# Refresh links of all pages including this page
* 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
$existing = $this->getExistingCategories();
$categoryInserts = array_diff_assoc( $this->mCategories, $existing );
- $categoryDeletes = array_diff_assoc( $existing, $this->mCategoties );
+ $categoryDeletes = array_diff_assoc( $existing, $this->mCategories );
$categoryUpdates = $categoryInserts + $categoryDeletes;
$existing = $this->getExistingImages();
$imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
}
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',
+ $res = $dbr->select( 'templatelinks',
+ array( 'tl_from' ),
+ array(
'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;
+ $numRows = $res->numRows();
+ if( !$numRows ) {
+ wfProfileOut( __METHOD__ );
+ return; // nothing to do
+ }
+ $numBatches = ceil( $numRows / $wgUpdateRowsPerJob );
+ $realBatchSize = $numRows / $numBatches;
+ $start = false;
+ $jobs = array();
+ do {
+ for( $i = 0; $i <= $realBatchSize - 1; $i++ ) {
+ $row = $res->fetchRow();
+ if( $row ) {
+ $id = $row[0];
+ } else {
+ $id = false;
break;
}
- $title = Title::makeTitle( $row->page_namespace, $row->page_title );
- $jobs[] = new RefreshLinksJob( $title, '' );
}
- Job::batchInsert( $jobs );
- }
+ $params = array(
+ 'start' => $start,
+ 'end' => ( $id !== false ? $id - 1 : false ),
+ );
+ $jobs[] = new RefreshLinksJob2( $this->mTitle, $params );
+ # Hit page caches while we're at it if set to do so...
+ if( $this->mTouchTmplLinks ) {
+ $params['table'] = 'templatelinks';
+ $jobs[] = new HTMLCacheUpdateJob( $this->mTitle, $params );
+ }
+ $start = $id;
+ } while ( $start );
+
$dbr->freeResult( $res );
+
+ Job::batchInsert( $jobs );
+
wfProfileOut( __METHOD__ );
}