You are here

protected function APDQCache::garbageCollection in Asynchronous Prefetch Database Query Cache 7

Generic garbage collection method.

Rather than respecting minimum cache lifetime at the bin-level, we respect it on an entry-by-entry basis.

Additionally, we've moved session cache handling to a separate method.

Overrides DrupalDatabaseCache::garbageCollection

3 calls to APDQCache::garbageCollection()
APDQCache::clear in ./apdqc.cache.inc
Implements DrupalCacheInterface::clear().
APDQCache::getMultiple in ./apdqc.cache.inc
Implements DrupalCacheInterface::getMultiple().
APDQCache::isEmpty in ./apdqc.cache.inc
Implements DrupalCacheInterface::isEmpty().

File

./apdqc.cache.inc, line 457
Extends Drupal's default database cache so async queries happen.

Class

APDQCache
A pretty darn quick cache implementation of Drupal's default cache backend.

Code

protected function garbageCollection() {
  $cache_lifetime = variable_get('cache_lifetime', 0);
  $gc_frequency = variable_get('cache_garbage_collection_frequency', CACHE_GARBAGE_COLLECTION_FREQUENCY);
  if (empty($gc_frequency)) {
    $cache_lifetime = variable_get('cache_lifetime', 0);

    // Clean-up the per-user cache expiration session data, so that the
    // session handler can properly clean-up the session data for anonymous
    // users.
    if (isset($_SESSION['cache_expiration'])) {
      $expire = REQUEST_TIME - $cache_lifetime;
      foreach ($_SESSION['cache_expiration'] as $bin => $timestamp) {
        if ($timestamp < $expire) {
          unset($_SESSION['cache_expiration'][$bin]);
        }
      }
      if (!$_SESSION['cache_expiration']) {
        unset($_SESSION['cache_expiration']);
      }
    }

    // Garbage collection of temporary items is only necessary when enforcing
    // a minimum cache lifetime.
    if (!$cache_lifetime) {
      return;
    }

    // When cache lifetime is in force, avoid running garbage collection too
    // often since this will remove temporary cache items indiscriminately.
    $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
    if ($cache_flush && $cache_flush + $cache_lifetime <= REQUEST_TIME) {

      // Reset the variable immediately to prevent a meltdown in heavy load
      // situations.
      variable_set('cache_flush_' . $this->bin, 0);

      // Time to flush old cache data
      // Build query.
      $query = Database::getConnection()
        ->prefixTables("DELETE FROM {" . db_escape_table($this->bin) . "} ");
      $query .= "WHERE (expire <> " . CACHE_PERMANENT . " AND expire <= " . $cache_flush . ")";

      // Run query.
      $result = apdqc_query(array(
        $this->bin,
      ), array(
        '*',
      ), $query, array(
        'async' => TRUE,
      ));
      if (is_string($result) && $result === 'NO DB') {

        // Use the DrupalDatabaseCache class.
        return parent::garbageCollection();
      }
    }
  }
  else {

    // Build query.
    $query = Database::getConnection()
      ->prefixTables("DELETE FROM {" . db_escape_table($this->bin) . "} ");
    if (!empty($cache_lifetime)) {

      // Clear expired items from the cache.
      $query .= "WHERE (expire > " . CACHE_PERMANENT . " AND expire < " . REQUEST_TIME . ")";

      // Clear CACHE_TEMPORARY items that are older than cache_lifetime.
      $query .= "OR (expire = " . CACHE_TEMPORARY . " AND created < " . apdqc_escape_string(REQUEST_TIME - $cache_lifetime) . ")";
    }
    else {

      // No minimum lifetime. Flush all expired and temporary cache entries.
      $query .= "WHERE (expire <> " . CACHE_PERMANENT . " AND expire < " . REQUEST_TIME . ")";
    }

    // Run query.
    $result = apdqc_query(array(
      $this->bin,
    ), array(
      '*',
    ), $query, array(
      'async' => TRUE,
    ));
    if (is_string($result) && $result === 'NO DB') {
      if (!empty($cache_lifetime)) {

        // Clear expired items from the cache.
        db_delete($this->bin)
          ->condition('expire', CACHE_PERMANENT, '>')
          ->condition('expire', REQUEST_TIME, '<')
          ->execute();

        // Clear CACHE_TEMPORARY items that are older than cache_lifetime.
        db_delete($this->bin)
          ->condition('expire', CACHE_TEMPORARY)
          ->condition('created', REQUEST_TIME - $cache_lifetime, '<')
          ->execute();
      }
      else {

        // No minimum lifetime. Flush all expired and temporary cache entries.
        db_delete($this->bin)
          ->condition('expire', CACHE_PERMANENT, '<>')
          ->condition('expire', REQUEST_TIME, '<')
          ->execute();
      }
    }
  }
}