* @author Tim Starling
* @copyright © 2009, Tim Starling, Domas Mituzas
* @copyright © 2010, Max Sem
- * @copyright © 2011, Ashar Voultoiz
+ * @copyright © 2011, Antoine Musso
*/
class BacklinkCache {
* > 'batches' : array( $start, $end )
*
* @see BacklinkCache::partitionResult()
- * @todo Should be private
*
* Cleared with BacklinkCache::clear()
*/
- var $partitionCache = array();
+ protected $partitionCache = array();
/**
* Contains the whole links from a database result.
* This is raw data that will be partitioned in $partitionCache
*
- * @todo Should be private
- *
* Initialized with BacklinkCache::getLinks()
* Cleared with BacklinkCache::clear()
*/
- var $fullResultCache = array();
+ protected $fullResultCache = array();
/**
* Local copy of a database object.
* Accessor: BacklinkCache::getDB()
* Mutator : BacklinkCache::setDB()
* Cleared with BacklinkCache::clear()
- *
- * @todo Should be private
*/
- var $db;
+ protected $db;
/**
* Local copy of a Title object
- * @todo Should be private
*/
- var $title;
+ protected $title;
const CACHE_EXPIRY = 3600;
* Serialization handler, diasallows to serialize the database to prevent
* failures after this class is deserialized from cache with dead DB
* connection.
+ *
+ * @return array
*/
function __sleep() {
return array( 'partitionCache', 'fullResultCache', 'title' );
/**
* Clear locally stored data and database object.
*/
- function clear() {
+ public function clear() {
$this->partitionCache = array();
$this->fullResultCache = array();
unset( $this->db );
/**
* Set the Database object to use
+ *
+ * @param $db DatabaseBase
*/
public function setDB( $db ) {
$this->db = $db;
/**
* Get the slave connection to the database
* When non existing, will initialize the connection.
- * @return Database object
+ * @return DatabaseBase object
*/
protected function getDB() {
if ( !isset( $this->db ) ) {
* @param $table String
* @param $startId Integer or false
* @param $endId Integer or false
- * @return TitleArray
+ * @return TitleArrayFromResult
*/
public function getLinks( $table, $startId = false, $endId = false ) {
wfProfileIn( __METHOD__ );
return $ta;
}
- // FIXME : make this a function?
+ // @todo FIXME: Make this a function?
if ( !isset( $this->fullResultCache[$table] ) ) {
wfDebug( __METHOD__ . ": from DB\n" );
$res = $this->getDB()->select(
/**
* Get the field name prefix for a given table
* @param $table String
+ * @return null|string
*/
protected function getPrefix( $table ) {
static $prefixes = array(
if ( isset( $prefixes[$table] ) ) {
return $prefixes[$table];
} else {
- throw new MWException( "Invalid table \"$table\" in " . __CLASS__ );
+ $prefix = null;
+ wfRunHooks( 'BacklinkCacheGetPrefix', array( $table, &$prefix ) );
+ if( $prefix ) {
+ return $prefix;
+ } else {
+ throw new MWException( "Invalid table \"$table\" in " . __CLASS__ );
+ }
}
}
* Get the SQL condition array for selecting backlinks, with a join
* on the page table.
* @param $table String
+ * @return array|null
*/
protected function getConditions( $table ) {
$prefix = $this->getPrefix( $table );
- // FIXME imagelinks and categorylinks do not rely on getNamespace,
+ // @todo FIXME: imagelinks and categorylinks do not rely on getNamespace,
// they could be moved up for nicer case statements
switch ( $table ) {
case 'pagelinks':
case 'templatelinks':
+ $conds = array(
+ "{$prefix}_namespace" => $this->title->getNamespace(),
+ "{$prefix}_title" => $this->title->getDBkey(),
+ "page_id={$prefix}_from"
+ );
+ break;
case 'redirect':
$conds = array(
"{$prefix}_namespace" => $this->title->getNamespace(),
"{$prefix}_title" => $this->title->getDBkey(),
+ $this->getDb()->makeList( array(
+ "{$prefix}_interwiki = ''",
+ "{$prefix}_interwiki is null",
+ ), LIST_OR ),
"page_id={$prefix}_from"
);
break;
);
break;
default:
- throw new MWException( "Invalid table \"$table\" in " . __CLASS__ );
+ $conds = null;
+ wfRunHooks( 'BacklinkCacheGetConditions', array( $table, $this->title, &$conds ) );
+ if( !$conds )
+ throw new MWException( "Invalid table \"$table\" in " . __CLASS__ );
}
return $conds;
/**
* Partition the backlinks into batches.
- * Returns an array giving the start and end of each range. The firsti
+ * Returns an array giving the start and end of each range. The first
* batch has a start of false, and the last batch has an end of false.
*
* @param $table String: the links table name
*/
public function partition( $table, $batchSize ) {
- // 1) try this per process cache first
+ // 1) try partition cache ...
if ( isset( $this->partitionCache[$table][$batchSize] ) ) {
wfDebug( __METHOD__ . ": got from partition cache\n" );
$this->partitionCache[$table][$batchSize] = false;
$cacheEntry =& $this->partitionCache[$table][$batchSize];
-
- // 2) try full result cache
+ // 2) ... then try full result cache ...
if ( isset( $this->fullResultCache[$table] ) ) {
$cacheEntry = $this->partitionResult( $this->fullResultCache[$table], $batchSize );
return $cacheEntry['batches'];
}
-
// 3) ... fallback to memcached ...
global $wgMemc;
/**
* Partition a DB result with backlinks in it into batches
- * @param $res database result
+ * @param $res ResultWrapper database result
* @param $batchSize integer
* @return array @see
*/