X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fcache%2FLinkCache.php;h=23cc26d5e23bb3cb6842ada788dfac3f2001e7d1;hb=d5a7166771613dfe4ed9fb75fa5efeced6134bd1;hp=6a602dfb2f5cacb12e15676170336bc0266f157c;hpb=7e350ba150404509d764c96a5ea4dbc9aa51d3ac;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/cache/LinkCache.php b/includes/cache/LinkCache.php index 6a602dfb2f..2d088952b6 100644 --- a/includes/cache/LinkCache.php +++ b/includes/cache/LinkCache.php @@ -20,6 +20,9 @@ * @file * @ingroup Cache */ + +use Wikimedia\Rdbms\Database; +use Wikimedia\Rdbms\IDatabase; use MediaWiki\Linker\LinkTarget; use MediaWiki\MediaWikiServices; @@ -29,19 +32,17 @@ use MediaWiki\MediaWikiServices; * @ingroup Cache */ class LinkCache { - /** - * @var HashBagOStuff - */ + /** @var HashBagOStuff */ private $mGoodLinks; - /** - * @var HashBagOStuff - */ + /** @var HashBagOStuff */ private $mBadLinks; + /** @var WANObjectCache */ + private $wanCache; + + /** @var bool */ private $mForUpdate = false; - /** - * @var TitleFormatter - */ + /** @var TitleFormatter */ private $titleFormatter; /** @@ -50,9 +51,10 @@ class LinkCache { */ const MAX_SIZE = 10000; - public function __construct( TitleFormatter $titleFormatter ) { + public function __construct( TitleFormatter $titleFormatter, WANObjectCache $cache ) { $this->mGoodLinks = new HashBagOStuff( [ 'maxKeys' => self::MAX_SIZE ] ); $this->mBadLinks = new HashBagOStuff( [ 'maxKeys' => self::MAX_SIZE ] ); + $this->wanCache = $cache; $this->titleFormatter = $titleFormatter; } @@ -244,15 +246,31 @@ class LinkCache { return 0; } - // Some fields heavily used for linking... - $db = $this->mForUpdate ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA ); + // Cache template/file pages as they are less often viewed but heavily used + if ( $this->mForUpdate ) { + $row = $this->fetchPageRow( wfGetDB( DB_MASTER ), $nt ); + } elseif ( $this->isCacheable( $nt ) ) { + // These pages are often transcluded heavily, so cache them + $cache = $this->wanCache; + $row = $cache->getWithSetCallback( + $cache->makeKey( 'page', $nt->getNamespace(), sha1( $nt->getDBkey() ) ), + $cache::TTL_DAY, + function ( $curValue, &$ttl, array &$setOpts ) use ( $cache, $nt ) { + $dbr = wfGetDB( DB_REPLICA ); + $setOpts += Database::getCacheSetOptions( $dbr ); - $row = $db->selectRow( 'page', self::getSelectFields(), - [ 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ], - __METHOD__ - ); + $row = $this->fetchPageRow( $dbr, $nt ); + $mtime = $row ? wfTimestamp( TS_UNIX, $row->page_touched ) : false; + $ttl = $cache->adaptiveTTL( $mtime, $ttl ); - if ( $row !== false ) { + return $row; + } + ); + } else { + $row = $this->fetchPageRow( wfGetDB( DB_REPLICA ), $nt ); + } + + if ( $row ) { $this->addGoodLinkObjFromRow( $nt, $row ); $id = intval( $row->page_id ); } else { @@ -263,6 +281,53 @@ class LinkCache { return $id; } + /** + * @param WANObjectCache $cache + * @param TitleValue $t + * @return string[] + * @since 1.28 + */ + public function getMutableCacheKeys( WANObjectCache $cache, TitleValue $t ) { + if ( $this->isCacheable( $t ) ) { + return [ $cache->makeKey( 'page', $t->getNamespace(), sha1( $t->getDBkey() ) ) ]; + } + + return []; + } + + private function isCacheable( LinkTarget $title ) { + return ( $title->inNamespace( NS_TEMPLATE ) || $title->inNamespace( NS_FILE ) ); + } + + private function fetchPageRow( IDatabase $db, LinkTarget $nt ) { + $fields = self::getSelectFields(); + if ( $this->isCacheable( $nt ) ) { + $fields[] = 'page_touched'; + } + + return $db->selectRow( + 'page', + $fields, + [ 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ], + __METHOD__ + ); + } + + /** + * Purge the link cache for a title + * + * @param LinkTarget $title + * @since 1.28 + */ + public function invalidateTitle( LinkTarget $title ) { + if ( $this->isCacheable( $title ) ) { + $cache = ObjectCache::getMainWANInstance(); + $cache->delete( + $cache->makeKey( 'page', $title->getNamespace(), sha1( $title->getDBkey() ) ) + ); + } + } + /** * Clears cache */