class LruMemoryCache

Defines a least recently used (LRU) static cache implementation.

Stores cache items in memory using a PHP array. The number of cache items is limited to a fixed number of slots. When the all slots are full, older items are purged based on least recent usage.

Hierarchy

Expanded class hierarchy of LruMemoryCache

Related topics

2 files declare their use of LruMemoryCache
LruCacheGenericTest.php in core/tests/Drupal/KernelTests/Core/Cache/LruCacheGenericTest.php
LruMemoryCacheTest.php in core/tests/Drupal/Tests/Core/Cache/LruMemoryCacheTest.php
1 string reference to 'LruMemoryCache'
core.services.yml in core/core.services.yml
core/core.services.yml
1 service uses LruMemoryCache
entity.memory_cache in core/core.services.yml
Drupal\Core\Cache\MemoryCache\LruMemoryCache

File

core/lib/Drupal/Core/Cache/MemoryCache/LruMemoryCache.php, line 17

Namespace

Drupal\Core\Cache\MemoryCache
View source
class LruMemoryCache extends MemoryCache {
  
  /**
   * Constructs an LruMemoryCache object.
   *
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param int $allowedSlots
   *   The number of slots to allocate for items in the cache.
   */
  public function __construct(TimeInterface $time, protected readonly int $allowedSlots) {
    parent::__construct($time);
  }
  
  /**
   * {@inheritdoc}
   */
  public function get($cid, $allow_invalid = FALSE) {
    if ($cached = parent::get($cid, $allow_invalid)) {
      $this->handleCacheHits([
        $cid => $cached,
      ]);
    }
    return $cached;
  }
  
  /**
   * {@inheritdoc}
   */
  public function getMultiple(&$cids, $allow_invalid = FALSE) {
    $ret = parent::getMultiple($cids, $allow_invalid);
    $this->handleCacheHits($ret);
    return $ret;
  }
  
  /**
   * Moves an array of cache items to the most recently used positions.
   *
   * @param array $items
   *   An array of cache items keyed by cid.
   */
  private function handleCacheHits(array $items) : void {
    $last_key = array_key_last($this->cache);
    foreach ($items as $cid => $cached) {
      if ($cached->valid && $cid !== $last_key) {
        // Move valid items to the end of the array, so they will be removed
        // last.
        unset($this->cache[$cid]);
        $this->cache[$cid] = $cached;
        $last_key = $cid;
      }
    }
  }
  
  /**
   * {@inheritdoc}
   */
  public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = []) : void {
    if (isset($this->cache[$cid])) {
      // If the item is already in the cache, move it to end of the array.
      unset($this->cache[$cid]);
    }
    elseif (count($this->cache) > $this->allowedSlots - 1) {
      // Remove one item from the cache to ensure we remain within the allowed
      // number of slots. Avoid using array_slice() because it makes a copy of
      // the array, and avoid using array_splice() or array_shift() because they
      // re-index numeric keys.
      unset($this->cache[array_key_first($this->cache)]);
    }
    parent::set($cid, $data, $expire, $tags);
  }
  
  /**
   * {@inheritdoc}
   */
  public function invalidate($cid) : void {
    $this->invalidateMultiple([
      $cid,
    ]);
  }
  
  /**
   * {@inheritdoc}
   */
  public function invalidateMultiple(array $cids) : void {
    $items = [];
    foreach ($cids as $cid) {
      if (isset($this->cache[$cid])) {
        $items[$cid] = $this->cache[$cid];
        parent::invalidate($cid);
      }
    }
    $this->moveItemsToLeastRecentlyUsed($items);
  }
  
  /**
   * {@inheritdoc}
   */
  public function invalidateTags(array $tags) : void {
    $items = [];
    foreach ($this->cache as $cid => $item) {
      if (array_intersect($tags, $item->tags)) {
        parent::invalidate($cid);
        $items[$cid] = $this->cache[$cid];
      }
    }
    $this->moveItemsToLeastRecentlyUsed($items);
  }
  
  /**
   * Moves items to the least recently used positions.
   *
   * @param array $items
   *   An array of items to move to the least recently used positions.
   */
  private function moveItemsToLeastRecentlyUsed(array $items) : void {
    // This cannot use array_unshift() because it would reindex an array with
    // numeric cache IDs.
    if (!empty($items)) {
      $this->cache = $items + $this->cache;
    }
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
CacheBackendInterface::CACHE_PERMANENT constant Indicates that the item should never be removed unless explicitly deleted.
LruMemoryCache::get public function Returns data from the persistent cache. Overrides MemoryBackend::get
LruMemoryCache::getMultiple public function Returns data from the persistent cache when given an array of cache IDs. Overrides MemoryBackend::getMultiple
LruMemoryCache::handleCacheHits private function Moves an array of cache items to the most recently used positions.
LruMemoryCache::invalidate public function Marks a cache item as invalid. Overrides MemoryBackend::invalidate
LruMemoryCache::invalidateMultiple public function Marks cache items as invalid. Overrides MemoryBackend::invalidateMultiple
LruMemoryCache::invalidateTags public function Marks cache items with any of the specified tags as invalid. Overrides MemoryBackend::invalidateTags
LruMemoryCache::moveItemsToLeastRecentlyUsed private function Moves items to the least recently used positions.
LruMemoryCache::set public function Stores data in the persistent cache. Overrides MemoryCache::set
LruMemoryCache::__construct public function Constructs an LruMemoryCache object. Overrides MemoryBackend::__construct
MemoryBackend::$cache protected property Array to store cache objects.
MemoryBackend::delete public function Deletes an item from the cache. Overrides CacheBackendInterface::delete 1
MemoryBackend::deleteAll public function Deletes all cache items in a bin. Overrides CacheBackendInterface::deleteAll
MemoryBackend::deleteMultiple public function Deletes multiple items from the cache. Overrides CacheBackendInterface::deleteMultiple
MemoryBackend::garbageCollection public function Performs garbage collection on a cache bin. Overrides CacheBackendInterface::garbageCollection
MemoryBackend::invalidateAll public function Marks all cache items as invalid. Overrides CacheBackendInterface::invalidateAll
MemoryBackend::removeBin public function Remove a cache bin. Overrides CacheBackendInterface::removeBin
MemoryBackend::reset public function Reset statically cached variables.
MemoryBackend::setMultiple public function Store multiple items in the persistent cache. Overrides CacheBackendInterface::setMultiple
MemoryBackend::__sleep public function Prevents data stored in memory backends from being serialized.
MemoryCache::prepareItem protected function Prepares a cached item. Overrides MemoryBackend::prepareItem

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.