class Redis_Cache_Predis in Redis 7.2
Same name and namespace in other branches
- 7.3 lib/Redis/Cache/Predis.php \Redis_Cache_Predis
- 7 lib/Redis/Cache/Predis.php \Redis_Cache_Predis
Predis cache backend.
Hierarchy
- class \Redis_AbstractBackend
- class \Redis_Cache_Base implements DrupalCacheInterface
- class \Redis_Cache_Predis
- class \Redis_Cache_Base implements DrupalCacheInterface
Expanded class hierarchy of Redis_Cache_Predis
File
- lib/
Redis/ Cache/ Predis.php, line 6
View source
class Redis_Cache_Predis extends Redis_Cache_Base {
function get($cid) {
$client = Redis_Client::getClient();
$key = $this
->getKey($cid);
$cached = $client
->hgetall($key);
if (empty($cached)) {
return FALSE;
}
$cached = (object) $cached;
if ($cached->serialized) {
$cached->data = unserialize($cached->data);
}
return $cached;
}
function getMultiple(&$cids) {
$client = Redis_Client::getClient();
$ret = $keys = array();
$keys = array_map(array(
$this,
'getKey',
), $cids);
$replies = $client
->pipeline(function ($pipe) use ($keys) {
foreach ($keys as $key) {
$pipe
->hgetall($key);
}
});
foreach ($replies as $reply) {
if (!empty($reply)) {
// HGETALL signature seems to differ depending on Predis versions.
// This was found just after Predis update. Even though I'm not sure
// this comes from Predis or just because we're misusing it.
// FIXME: Needs some investigation.
if (!isset($reply['cid'])) {
$cache = new stdClass();
$size = count($reply);
for ($i = 0; $i < $size; ++$i) {
$cache->{$reply[$i]} = $reply[++$i];
}
}
else {
$cache = (object) $reply;
}
if ($cache->serialized) {
$cache->data = unserialize($cache->data);
}
$ret[$cache->cid] = $cache;
}
}
foreach ($cids as $index => $cid) {
if (isset($ret[$cid])) {
unset($cids[$index]);
}
}
return $ret;
}
function set($cid, $data, $expire = CACHE_PERMANENT) {
$client = Redis_Client::getClient();
$skey = $this
->getKey(Redis_Cache_Base::TEMP_SET);
$key = $this
->getKey($cid);
$self = $this;
$client
->pipeline(function ($pipe) use ($cid, $key, $skey, $data, $expire, $self) {
$hash = array(
'cid' => $cid,
'created' => time(),
'expire' => $expire,
'volatile' => (int) (CACHE_TEMPORARY === $expire),
);
if (!is_string($data)) {
$hash['data'] = serialize($data);
$hash['serialized'] = 1;
}
else {
$hash['data'] = $data;
$hash['serialized'] = 0;
}
$pipe
->hmset($key, $hash);
switch ($expire) {
case CACHE_TEMPORARY:
$lifetime = variable_get('cache_lifetime', Redis_Cache_Base::LIFETIME_DEFAULT);
if (0 < $lifetime) {
$pipe
->expire($key, $lifetime);
}
$pipe
->sadd($skey, $cid);
break;
case CACHE_PERMANENT:
if (0 !== ($ttl = $self
->getPermTtl())) {
$pipe
->expire($key, $ttl);
}
// We dont need the PERSIST command we want the cache item to
// never expire.
break;
default:
// If caller gives us an expiry timestamp in the past
// the key will expire now and will never be read.
$ttl = $expire - time();
$pipe
->expire($key, $ttl);
if (0 < $ttl) {
$pipe
->sadd($skey, $cid);
}
break;
}
});
}
protected function clearWithEval($cid = NULL, $wildcard = FALSE) {
$client = Redis_Client::getClient();
// @todo Should I restore the clear mode?
if (NULL === $cid && FALSE === $wildcard) {
// Flush volatile keys.
// Per Drupal core definition, do not expire volatile keys
// when a default cache lifetime is set.
if (Redis_Cache_Base::LIFETIME_INFINITE == variable_get('cache_lifetime', Redis_Cache_Base::LIFETIME_DEFAULT)) {
$ret = $client
->eval(self::EVAL_DELETE_VOLATILE, 0, $this
->getKey('*'));
if (1 != $ret) {
trigger_error(sprintf("EVAL failed: %s", $client
->getLastError()), E_USER_ERROR);
}
}
}
else {
if ('*' !== $cid && $wildcard) {
// Flush by prefix.
$ret = $client
->eval(self::EVAL_DELETE_PREFIX, 0, $this
->getKey($cid . '*'));
if (1 != $ret) {
trigger_error(sprintf("EVAL failed: %s", $client
->getLastError()), E_USER_ERROR);
}
}
else {
if ('*' === $cid) {
// Flush everything.
$ret = $client
->eval(self::EVAL_DELETE_PREFIX, 0, $this
->getKey('*'));
if (1 != $ret) {
trigger_error(sprintf("EVAL failed: %s", $client
->getLastError()), E_USER_ERROR);
}
}
else {
if (!$wildcard) {
$client
->del($this
->getKey($cid));
}
}
}
}
}
protected function clearWithoutEval($cid = NULL, $wildcard = FALSE) {
$keys = array();
$skey = $this
->getKey(Redis_Cache_Base::TEMP_SET);
$client = Redis_Client::getClient();
if (NULL === $cid) {
switch ($this
->getClearMode()) {
// One and only case of early return.
case Redis_Cache_Base::FLUSH_NOTHING:
return;
// Default behavior.
case Redis_Cache_Base::FLUSH_TEMPORARY:
if (Redis_Cache_Base::LIFETIME_INFINITE == variable_get('cache_lifetime', Redis_Cache_Base::LIFETIME_DEFAULT)) {
$keys[] = $skey;
foreach ($client
->smembers($skey) as $tcid) {
$keys[] = $this
->getKey($tcid);
}
}
break;
// Fallback on most secure mode: flush full bin.
default:
case Redis_Cache_Base::FLUSH_ALL:
$keys[] = $skey;
$cid = '*';
$wildcard = true;
break;
}
}
if ('*' !== $cid && $wildcard) {
// Prefix flush.
$keys = array_merge($keys, $client
->keys($this
->getKey($cid . '*')));
}
else {
if ('*' === $cid) {
// Full bin flush.
$keys = array_merge($keys, $client
->keys($this
->getKey('*')));
}
else {
if (empty($keys) && !empty($cid)) {
// Single key drop.
$keys[] = $key = $this
->getKey($cid);
$client
->srem($skey, $key);
}
}
}
if (!empty($keys)) {
if (count($keys) < Redis_Cache_Base::KEY_THRESHOLD) {
$client
->del($keys);
}
else {
$client
->pipeline(function ($pipe) use ($keys) {
do {
$buffer = array_splice($keys, 0, Redis_Cache_Base::KEY_THRESHOLD);
$pipe
->del($buffer);
} while (!empty($keys));
});
}
}
}
function clear($cid = NULL, $wildcard = FALSE) {
if ($this
->canUseEval()) {
$this
->clearWithEval($cid, $wildcard);
}
else {
$this
->clearWithoutEval($cid, $wildcard);
}
}
function isEmpty() {
// FIXME: Todo.
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Redis_AbstractBackend:: |
protected static | property | ||
Redis_AbstractBackend:: |
private | property | ||
Redis_AbstractBackend:: |
public | function | Get redis client | |
Redis_AbstractBackend:: |
public static | function | Get global default prefix | |
Redis_AbstractBackend:: |
public static | function | Get site default global prefix | |
Redis_AbstractBackend:: |
final public | function | Get prefix | |
Redis_AbstractBackend:: |
constant | Key components name separator | ||
Redis_AbstractBackend:: |
final public | function | Set prefix | |
Redis_Cache_Base:: |
protected | property | ||
Redis_Cache_Base:: |
protected | property | ||
Redis_Cache_Base:: |
protected | property | Default TTL for CACHE_PERMANENT items. | |
Redis_Cache_Base:: |
protected | property | Can this instance use EVAL. | |
Redis_Cache_Base:: |
public | function | Tell if the backend can use EVAL commands. | |
Redis_Cache_Base:: |
constant | Delete by prefix lua script | ||
Redis_Cache_Base:: |
constant | Delete volatile by prefix lua script | ||
Redis_Cache_Base:: |
constant | Flush all on generic clear(). | ||
Redis_Cache_Base:: |
constant | Flush nothing on generic clear(). | ||
Redis_Cache_Base:: |
constant | Flush only temporary on generic clear(). | ||
Redis_Cache_Base:: |
public | function | Get clear mode. | |
Redis_Cache_Base:: |
public | function |
Get full key name using the set prefix Overrides Redis_AbstractBackend:: |
|
Redis_Cache_Base:: |
public | function | Get TTL for CACHE_PERMANENT items. | |
Redis_Cache_Base:: |
constant | Computed keys are let's say arround 60 characters length due to key prefixing, which makes 1,000 keys DEL command to be something arround 50,000 bytes length: this is huge and may not pass into Redis, let's split this off. Some recommend to… | ||
Redis_Cache_Base:: |
constant | Default temporary cache items lifetime. | ||
Redis_Cache_Base:: |
constant | Temporary cache items lifetime is infinite. | ||
Redis_Cache_Base:: |
constant | Default lifetime for permanent items. Approximatively 1 year. | ||
Redis_Cache_Base:: |
constant | Temporary items SET name. | ||
Redis_Cache_Base:: |
public | function |
Default constructor Overrides Redis_AbstractBackend:: |
|
Redis_Cache_Predis:: |
function |
Expires data from the cache. Overrides DrupalCacheInterface:: |
||
Redis_Cache_Predis:: |
protected | function | ||
Redis_Cache_Predis:: |
protected | function | ||
Redis_Cache_Predis:: |
function |
Returns data from the persistent cache. Overrides DrupalCacheInterface:: |
||
Redis_Cache_Predis:: |
function |
Returns data from the persistent cache when given an array of cache IDs. Overrides DrupalCacheInterface:: |
||
Redis_Cache_Predis:: |
function |
Checks if a cache bin is empty. Overrides DrupalCacheInterface:: |
||
Redis_Cache_Predis:: |
function |
Stores data in the persistent cache. Overrides DrupalCacheInterface:: |