You are here

function dmemcache_get_multi in Memcache API and Integration 7

Same name and namespace in other branches
  1. 6 dmemcache.inc \dmemcache_get_multi()

Retrieve multiple values from the cache.

Parameters

array $keys: The keys with which the items were stored.

string $bin: The bin in which the item was stored.

Return value

mixed An array keyed by $keys with the items requested or NULL values if the data was not present.

3 calls to dmemcache_get_multi()
MemCacheDrupal::getMultiple in ./memcache.inc
Implements DrupalCacheInterface::getMultiple().
MemCacheDrupal::wildcards in ./memcache.inc
Retrieves all matching wildcards for the given cache id.
_dmemcache_get_pieces in ./dmemcache.inc
Retrieve a value from the cache.

File

./dmemcache.inc, line 396
A memcache API for Drupal.

Code

function dmemcache_get_multi($keys, $bin = 'cache', $mc = NULL) {
  static $memcache_ascii_auth = NULL;
  $collect_stats = dmemcache_stats_init();
  $multi_stats = array();
  $full_keys = array();
  foreach ($keys as $key => $cid) {
    $full_key = dmemcache_key($cid, $bin);
    $full_keys[$cid] = $full_key;
    if ($collect_stats) {
      $multi_stats[$full_key] = FALSE;
    }
  }
  $results = array();
  if ($mc || ($mc = dmemcache_object($bin))) {
    if ($mc instanceof Memcached) {
      if (PHP_MAJOR_VERSION >= 7) {

        // See https://www.drupal.org/node/2728427
        $results = $mc
          ->getMulti($full_keys, Memcached::GET_PRESERVE_ORDER);
      }
      else {
        $cas_tokens = NULL;
        $results = $mc
          ->getMulti($full_keys, $cas_tokens, Memcached::GET_PRESERVE_ORDER);
      }

      // If $results is FALSE, convert it to an empty array.
      if (!$results) {
        $results = array();
      }
      if (!isset($memcache_ascii_auth)) {
        $memcache_ascii_auth = _dmemcache_use_ascii_auth();
      }

      // Find out which results have values and which have not.
      if ($memcache_ascii_auth && count(array_filter($results)) < count($full_keys)) {

        // Convert empty results to the full keys with value of NULL.
        if (empty($results)) {
          $results = array_fill_keys($full_keys, NULL);
        }
        $new_results = _dmemcache_get_multi_2nd_chance_ascii_auth($results, $mc);
        foreach ($new_results as $full_key => $value) {
          $results[$full_key] = $value;
        }
      }
    }
    elseif ($mc instanceof Memcache) {
      $track_errors = ini_set('track_errors', '1');
      $php_errormsg = '';
      $results = @$mc
        ->get($full_keys);
      if (!empty($php_errormsg)) {
        register_shutdown_function('watchdog', 'memcache', 'Exception caught in dmemcache_get_multi: !msg', array(
          '!msg' => $php_errormsg,
        ), WATCHDOG_WARNING);
        $php_errormsg = '';
      }
      ini_set('track_errors', $track_errors);

      // Order is not guaranteed, map responses to order of requests.
      if (is_array($results)) {
        $keys = array_fill_keys($full_keys, NULL);
        $results = array_merge($keys, $results);
      }
    }
  }

  // If $results is FALSE, convert it to an empty array.
  if (!$results) {
    $results = array();
    $keys = array_fill_keys($full_keys, NULL);
    $results = array_merge($keys, $results);
    _dmemcache_write_debug('getMulti', $bin, implode(',', $full_keys), FALSE);
  }
  if ($collect_stats) {
    foreach ($multi_stats as $key => $value) {
      $multi_stats[$key] = isset($results[$key]) ? TRUE : FALSE;
    }
  }

  // Convert the full keys back to the cid.
  $cid_results = array();
  $cid_lookup = array_flip($full_keys);
  foreach ($results as $key => $value) {

    // This is a multi-part value.
    if (is_object($value) && !empty($value->multi_part_data)) {
      $value = _dmemcache_get_pieces($value->data, $value->cid, $bin, $mc);
    }
    $cid_results[$cid_lookup[$key]] = $value;
    _dmemcache_write_debug('getMulti', $bin, $key, TRUE);
  }
  if ($collect_stats) {
    dmemcache_stats_write('getMulti', $bin, $multi_stats);
  }
  return $cid_results;
}