mediawiki-extensions-Echo/includes/Cache/LocalCache.php

101 lines
2 KiB
PHP
Raw Normal View History

<?php
namespace MediaWiki\Extension\Notifications\Cache;
use Iterator;
use MapCacheLRU;
/**
* Base Local cache object, which borrows the concept from Flow user listener
*/
abstract class LocalCache {
/**
* Max number of objects to hold in $targets. In theory, 1000
* is very hard to reach in a normal web request. We need to
* put cap, so it doesn't reach memory limit when running email
* digest against large amount of notifications
*/
private const TARGET_MAX_NUM = 1000;
/**
* Target object cache
* @var MapCacheLRU
*/
protected $targets;
/**
* Lookup ids that have not been resolved for a target
* @var bool[]
*/
private $lookups = [];
/**
* Resolve ids in lookups to targets
*
* @param int[] $lookups
* @return Iterator
*/
abstract protected function resolve( array $lookups );
/**
* Use a factory method, such as TitleLocalCache::create().
*
* @private
*/
public function __construct() {
$this->targets = new MapCacheLRU( self::TARGET_MAX_NUM );
}
/**
* Add a key to the lookup and the key is used to resolve cache target
*
* @param int $key
*/
public function add( $key ) {
if (
count( $this->lookups ) < self::TARGET_MAX_NUM
&& !$this->targets->get( (string)$key )
) {
$this->lookups[$key] = true;
}
}
/**
* Get the cache target based on the key
*
* @param int $key
* @return mixed|null
*/
public function get( $key ) {
$target = $this->targets->get( (string)$key );
if ( $target ) {
return $target;
}
if ( isset( $this->lookups[ $key ] ) ) {
// Resolve the lookup batch and store results in the cache
$targets = $this->resolve( array_keys( $this->lookups ) );
foreach ( $targets as $id => $val ) {
$this->targets->set( $id, $val );
}
$this->lookups = [];
$target = $this->targets->get( (string)$key );
if ( $target ) {
return $target;
}
}
return null;
}
/**
* Clear everything in local cache
*/
public function clearAll() {
$this->targets->clear();
$this->lookups = [];
}
}